mirror of
https://github.com/FEX-Emu/linux.git
synced 2024-12-20 16:30:53 +00:00
Merge branch 'master' of /home/trondmy/repositories/git/linux-2.6/
This commit is contained in:
commit
5cf4cf65a8
15
arch/avr32/boards/atstk1000/atstk1000.h
Normal file
15
arch/avr32/boards/atstk1000/atstk1000.h
Normal file
@ -0,0 +1,15 @@
|
||||
/*
|
||||
* ATSTK1000 setup code: Daughterboard interface
|
||||
*
|
||||
* Copyright (C) 2007 Atmel Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#ifndef __ARCH_AVR32_BOARDS_ATSTK1000_ATSTK1000_H
|
||||
#define __ARCH_AVR32_BOARDS_ATSTK1000_ATSTK1000_H
|
||||
|
||||
extern struct atmel_lcdfb_info atstk1000_lcdc_data;
|
||||
|
||||
#endif /* __ARCH_AVR32_BOARDS_ATSTK1000_ATSTK1000_H */
|
@ -16,6 +16,8 @@
|
||||
#include <linux/types.h>
|
||||
#include <linux/spi/spi.h>
|
||||
|
||||
#include <video/atmel_lcdc.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <asm/setup.h>
|
||||
#include <asm/arch/at32ap7000.h>
|
||||
@ -23,6 +25,7 @@
|
||||
#include <asm/arch/init.h>
|
||||
#include <asm/arch/portmux.h>
|
||||
|
||||
#include "atstk1000.h"
|
||||
|
||||
#define SW2_DEFAULT /* MMCI and UART_A available */
|
||||
|
||||
@ -31,9 +34,7 @@ struct eth_addr {
|
||||
};
|
||||
|
||||
static struct eth_addr __initdata hw_addr[2];
|
||||
|
||||
static struct eth_platform_data __initdata eth_data[2];
|
||||
static struct lcdc_platform_data atstk1000_fb0_data;
|
||||
|
||||
static struct spi_board_info spi0_board_info[] __initdata = {
|
||||
{
|
||||
@ -148,9 +149,8 @@ static int __init atstk1002_init(void)
|
||||
set_hw_addr(at32_add_device_eth(0, ð_data[0]));
|
||||
|
||||
at32_add_device_spi(0, spi0_board_info, ARRAY_SIZE(spi0_board_info));
|
||||
atstk1000_fb0_data.fbmem_start = fbmem_start;
|
||||
atstk1000_fb0_data.fbmem_size = fbmem_size;
|
||||
at32_add_device_lcdc(0, &atstk1000_fb0_data);
|
||||
at32_add_device_lcdc(0, &atstk1000_lcdc_data,
|
||||
fbmem_start, fbmem_size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -8,13 +8,56 @@
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#include <linux/bootmem.h>
|
||||
#include <linux/fb.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/linkage.h>
|
||||
|
||||
#include <asm/setup.h>
|
||||
#include <video/atmel_lcdc.h>
|
||||
|
||||
#include <asm/setup.h>
|
||||
#include <asm/arch/board.h>
|
||||
|
||||
#include "atstk1000.h"
|
||||
|
||||
/* Initialized by bootloader-specific startup code. */
|
||||
struct tag *bootloader_tags __initdata;
|
||||
|
||||
static struct fb_videomode __initdata ltv350qv_modes[] = {
|
||||
{
|
||||
.name = "320x240 @ 75",
|
||||
.refresh = 75,
|
||||
.xres = 320, .yres = 240,
|
||||
.pixclock = KHZ2PICOS(6891),
|
||||
|
||||
.left_margin = 17, .right_margin = 33,
|
||||
.upper_margin = 10, .lower_margin = 10,
|
||||
.hsync_len = 16, .vsync_len = 1,
|
||||
|
||||
.sync = 0,
|
||||
.vmode = FB_VMODE_NONINTERLACED,
|
||||
},
|
||||
};
|
||||
|
||||
static struct fb_monspecs __initdata atstk1000_default_monspecs = {
|
||||
.manufacturer = "SNG",
|
||||
.monitor = "LTV350QV",
|
||||
.modedb = ltv350qv_modes,
|
||||
.modedb_len = ARRAY_SIZE(ltv350qv_modes),
|
||||
.hfmin = 14820,
|
||||
.hfmax = 22230,
|
||||
.vfmin = 60,
|
||||
.vfmax = 90,
|
||||
.dclkmax = 30000000,
|
||||
};
|
||||
|
||||
struct atmel_lcdfb_info __initdata atstk1000_lcdc_data = {
|
||||
.default_bpp = 24,
|
||||
.default_dmacon = ATMEL_LCDC_DMAEN | ATMEL_LCDC_DMA2DEN,
|
||||
.default_lcdcon2 = (ATMEL_LCDC_DISTYPE_TFT
|
||||
| ATMEL_LCDC_INVCLK
|
||||
| ATMEL_LCDC_CLKMOD_ALWAYSACTIVE
|
||||
| ATMEL_LCDC_MEMOR_BIG),
|
||||
.default_monspecs = &atstk1000_default_monspecs,
|
||||
.guard_time = 2,
|
||||
};
|
||||
|
@ -7,15 +7,6 @@
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This file contains the code used by various IRQ handling routines:
|
||||
* asking for different IRQ's should be done through these routines
|
||||
* instead of just grabbing them. Thus setups with different IRQ numbers
|
||||
* shouldn't result in any weird surprises, and installing new handlers
|
||||
* should be easier.
|
||||
*
|
||||
* IRQ's are in fact implemented a bit like signal handlers for the kernel.
|
||||
* Naturally it's not a 1:1 relation, but there are similarities.
|
||||
*/
|
||||
|
||||
#include <linux/interrupt.h>
|
||||
|
@ -179,7 +179,7 @@ static int __kprobes post_kprobe_handler(struct pt_regs *regs)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
|
||||
int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
|
||||
{
|
||||
struct kprobe *cur = kprobe_running();
|
||||
|
||||
@ -216,11 +216,6 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
|
||||
if (post_kprobe_handler(args->regs))
|
||||
ret = NOTIFY_STOP;
|
||||
break;
|
||||
case DIE_FAULT:
|
||||
if (kprobe_running()
|
||||
&& kprobe_fault_handler(args->regs, args->trapnr))
|
||||
ret = NOTIFY_STOP;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -292,4 +292,7 @@ sys_call_table:
|
||||
.long sys_shmdt
|
||||
.long sys_shmctl
|
||||
.long sys_utimensat
|
||||
.long sys_signalfd
|
||||
.long sys_timerfd /* 280 */
|
||||
.long sys_eventfd
|
||||
.long sys_ni_syscall /* r8 is saturated at nr_syscalls */
|
||||
|
@ -6,6 +6,7 @@
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#include <linux/clk.h>
|
||||
#include <linux/fb.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/spi/spi.h>
|
||||
@ -17,6 +18,8 @@
|
||||
#include <asm/arch/portmux.h>
|
||||
#include <asm/arch/sm.h>
|
||||
|
||||
#include <video/atmel_lcdc.h>
|
||||
|
||||
#include "clock.h"
|
||||
#include "hmatrix.h"
|
||||
#include "pio.h"
|
||||
@ -881,20 +884,26 @@ at32_add_device_spi(unsigned int id, struct spi_board_info *b, unsigned int n)
|
||||
/* --------------------------------------------------------------------
|
||||
* LCDC
|
||||
* -------------------------------------------------------------------- */
|
||||
static struct lcdc_platform_data lcdc0_data;
|
||||
static struct resource lcdc0_resource[] = {
|
||||
static struct atmel_lcdfb_info atmel_lcdfb0_data;
|
||||
static struct resource atmel_lcdfb0_resource[] = {
|
||||
{
|
||||
.start = 0xff000000,
|
||||
.end = 0xff000fff,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
IRQ(1),
|
||||
{
|
||||
/* Placeholder for pre-allocated fb memory */
|
||||
.start = 0x00000000,
|
||||
.end = 0x00000000,
|
||||
.flags = 0,
|
||||
},
|
||||
};
|
||||
DEFINE_DEV_DATA(lcdc, 0);
|
||||
DEV_CLK(hclk, lcdc0, hsb, 7);
|
||||
static struct clk lcdc0_pixclk = {
|
||||
.name = "pixclk",
|
||||
.dev = &lcdc0_device.dev,
|
||||
DEFINE_DEV_DATA(atmel_lcdfb, 0);
|
||||
DEV_CLK(hck1, atmel_lcdfb0, hsb, 7);
|
||||
static struct clk atmel_lcdfb0_pixclk = {
|
||||
.name = "lcdc_clk",
|
||||
.dev = &atmel_lcdfb0_device.dev,
|
||||
.mode = genclk_mode,
|
||||
.get_rate = genclk_get_rate,
|
||||
.set_rate = genclk_set_rate,
|
||||
@ -903,13 +912,34 @@ static struct clk lcdc0_pixclk = {
|
||||
};
|
||||
|
||||
struct platform_device *__init
|
||||
at32_add_device_lcdc(unsigned int id, struct lcdc_platform_data *data)
|
||||
at32_add_device_lcdc(unsigned int id, struct atmel_lcdfb_info *data,
|
||||
unsigned long fbmem_start, unsigned long fbmem_len)
|
||||
{
|
||||
struct platform_device *pdev;
|
||||
struct atmel_lcdfb_info *info;
|
||||
struct fb_monspecs *monspecs;
|
||||
struct fb_videomode *modedb;
|
||||
unsigned int modedb_size;
|
||||
|
||||
/*
|
||||
* Do a deep copy of the fb data, monspecs and modedb. Make
|
||||
* sure all allocations are done before setting up the
|
||||
* portmux.
|
||||
*/
|
||||
monspecs = kmemdup(data->default_monspecs,
|
||||
sizeof(struct fb_monspecs), GFP_KERNEL);
|
||||
if (!monspecs)
|
||||
return NULL;
|
||||
|
||||
modedb_size = sizeof(struct fb_videomode) * monspecs->modedb_len;
|
||||
modedb = kmemdup(monspecs->modedb, modedb_size, GFP_KERNEL);
|
||||
if (!modedb)
|
||||
goto err_dup_modedb;
|
||||
monspecs->modedb = modedb;
|
||||
|
||||
switch (id) {
|
||||
case 0:
|
||||
pdev = &lcdc0_device;
|
||||
pdev = &atmel_lcdfb0_device;
|
||||
select_peripheral(PC(19), PERIPH_A, 0); /* CC */
|
||||
select_peripheral(PC(20), PERIPH_A, 0); /* HSYNC */
|
||||
select_peripheral(PC(21), PERIPH_A, 0); /* PCLK */
|
||||
@ -942,19 +972,32 @@ at32_add_device_lcdc(unsigned int id, struct lcdc_platform_data *data)
|
||||
select_peripheral(PD(16), PERIPH_A, 0); /* DATA22 */
|
||||
select_peripheral(PD(17), PERIPH_A, 0); /* DATA23 */
|
||||
|
||||
clk_set_parent(&lcdc0_pixclk, &pll0);
|
||||
clk_set_rate(&lcdc0_pixclk, clk_get_rate(&pll0));
|
||||
clk_set_parent(&atmel_lcdfb0_pixclk, &pll0);
|
||||
clk_set_rate(&atmel_lcdfb0_pixclk, clk_get_rate(&pll0));
|
||||
break;
|
||||
|
||||
default:
|
||||
return NULL;
|
||||
goto err_invalid_id;
|
||||
}
|
||||
|
||||
memcpy(pdev->dev.platform_data, data,
|
||||
sizeof(struct lcdc_platform_data));
|
||||
if (fbmem_len) {
|
||||
pdev->resource[2].start = fbmem_start;
|
||||
pdev->resource[2].end = fbmem_start + fbmem_len - 1;
|
||||
pdev->resource[2].flags = IORESOURCE_MEM;
|
||||
}
|
||||
|
||||
info = pdev->dev.platform_data;
|
||||
memcpy(info, data, sizeof(struct atmel_lcdfb_info));
|
||||
info->default_monspecs = monspecs;
|
||||
|
||||
platform_device_register(pdev);
|
||||
return pdev;
|
||||
|
||||
err_invalid_id:
|
||||
kfree(modedb);
|
||||
err_dup_modedb:
|
||||
kfree(monspecs);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
@ -1037,8 +1080,8 @@ struct clk *at32_clock_list[] = {
|
||||
&macb1_pclk,
|
||||
&atmel_spi0_spi_clk,
|
||||
&atmel_spi1_spi_clk,
|
||||
&lcdc0_hclk,
|
||||
&lcdc0_pixclk,
|
||||
&atmel_lcdfb0_hck1,
|
||||
&atmel_lcdfb0_pixclk,
|
||||
&gclk0,
|
||||
&gclk1,
|
||||
&gclk2,
|
||||
@ -1077,7 +1120,7 @@ void __init at32_clock_init(void)
|
||||
genclk_init_parent(&gclk2);
|
||||
genclk_init_parent(&gclk3);
|
||||
genclk_init_parent(&gclk4);
|
||||
genclk_init_parent(&lcdc0_pixclk);
|
||||
genclk_init_parent(&atmel_lcdfb0_pixclk);
|
||||
|
||||
/*
|
||||
* Turn on all clocks that have at least one user already, and
|
||||
|
@ -12,41 +12,30 @@
|
||||
#include <linux/mm.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/pagemap.h>
|
||||
|
||||
#include <linux/kdebug.h>
|
||||
#include <linux/kprobes.h>
|
||||
|
||||
#include <asm/mmu_context.h>
|
||||
#include <asm/sysreg.h>
|
||||
#include <asm/tlb.h>
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
#ifdef CONFIG_KPROBES
|
||||
ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain);
|
||||
|
||||
/* Hook to register for page fault notifications */
|
||||
int register_page_fault_notifier(struct notifier_block *nb)
|
||||
static inline int notify_page_fault(struct pt_regs *regs, int trap)
|
||||
{
|
||||
return atomic_notifier_chain_register(¬ify_page_fault_chain, nb);
|
||||
int ret = 0;
|
||||
|
||||
if (!user_mode(regs)) {
|
||||
if (kprobe_running() && kprobe_fault_handler(regs, trap))
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
int unregister_page_fault_notifier(struct notifier_block *nb)
|
||||
{
|
||||
return atomic_notifier_chain_unregister(¬ify_page_fault_chain, nb);
|
||||
}
|
||||
|
||||
static inline int notify_page_fault(enum die_val val, struct pt_regs *regs,
|
||||
int trap, int sig)
|
||||
{
|
||||
struct die_args args = {
|
||||
.regs = regs,
|
||||
.trapnr = trap,
|
||||
};
|
||||
return atomic_notifier_call_chain(¬ify_page_fault_chain, val, &args);
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
static inline int notify_page_fault(enum die_val val, struct pt_regs *regs,
|
||||
int trap, int sig)
|
||||
static inline int notify_page_fault(struct pt_regs *regs, int trap)
|
||||
{
|
||||
return NOTIFY_DONE;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -76,8 +65,7 @@ asmlinkage void do_page_fault(unsigned long ecr, struct pt_regs *regs)
|
||||
long signr;
|
||||
int code;
|
||||
|
||||
if (notify_page_fault(DIE_PAGE_FAULT, regs,
|
||||
ecr, SIGSEGV) == NOTIFY_STOP)
|
||||
if (notify_page_fault(regs, ecr))
|
||||
return;
|
||||
|
||||
address = sysreg_read(TLBEAR);
|
||||
|
@ -791,7 +791,7 @@ static __init int setup_additional_cpus(char *s)
|
||||
early_param("additional_cpus", setup_additional_cpus);
|
||||
|
||||
/*
|
||||
* cpu_possible_map should be static, it cannot change as cpu's
|
||||
* cpu_possible_map should be static, it cannot change as CPUs
|
||||
* are onlined, or offlined. The reason is per-cpu data-structures
|
||||
* are allocated by some modules at init time, and dont expect to
|
||||
* do this dynamically on cpu arrival/departure.
|
||||
|
@ -156,23 +156,29 @@ kdump_init_notifier(struct notifier_block *self, unsigned long val, void *data)
|
||||
if (!kdump_on_init)
|
||||
return NOTIFY_DONE;
|
||||
|
||||
if (val != DIE_INIT_MONARCH_ENTER &&
|
||||
val != DIE_INIT_SLAVE_ENTER &&
|
||||
if (val != DIE_INIT_MONARCH_LEAVE &&
|
||||
val != DIE_INIT_SLAVE_LEAVE &&
|
||||
val != DIE_INIT_MONARCH_PROCESS &&
|
||||
val != DIE_MCA_RENDZVOUS_LEAVE &&
|
||||
val != DIE_MCA_MONARCH_LEAVE)
|
||||
return NOTIFY_DONE;
|
||||
|
||||
nd = (struct ia64_mca_notify_die *)args->err;
|
||||
/* Reason code 1 means machine check rendezous*/
|
||||
if ((val == DIE_INIT_MONARCH_ENTER || val == DIE_INIT_SLAVE_ENTER) &&
|
||||
nd->sos->rv_rc == 1)
|
||||
/* Reason code 1 means machine check rendezvous*/
|
||||
if ((val == DIE_INIT_MONARCH_LEAVE || val == DIE_INIT_SLAVE_LEAVE
|
||||
|| val == DIE_INIT_MONARCH_PROCESS) && nd->sos->rv_rc == 1)
|
||||
return NOTIFY_DONE;
|
||||
|
||||
switch (val) {
|
||||
case DIE_INIT_MONARCH_ENTER:
|
||||
case DIE_INIT_MONARCH_PROCESS:
|
||||
atomic_set(&kdump_in_progress, 1);
|
||||
*(nd->monarch_cpu) = -1;
|
||||
break;
|
||||
case DIE_INIT_MONARCH_LEAVE:
|
||||
machine_kdump_on_init();
|
||||
break;
|
||||
case DIE_INIT_SLAVE_ENTER:
|
||||
case DIE_INIT_SLAVE_LEAVE:
|
||||
if (atomic_read(&kdump_in_progress))
|
||||
unw_init_running(kdump_cpu_freeze, NULL);
|
||||
break;
|
||||
case DIE_MCA_RENDZVOUS_LEAVE:
|
||||
@ -215,8 +221,10 @@ static ctl_table sys_table[] = {
|
||||
static int
|
||||
machine_crash_setup(void)
|
||||
{
|
||||
/* be notified before default_monarch_init_process */
|
||||
static struct notifier_block kdump_init_notifier_nb = {
|
||||
.notifier_call = kdump_init_notifier,
|
||||
.priority = 1,
|
||||
};
|
||||
int ret;
|
||||
if((ret = register_die_notifier(&kdump_init_notifier_nb)) != 0)
|
||||
|
@ -1585,5 +1585,8 @@ sys_call_table:
|
||||
data8 sys_getcpu
|
||||
data8 sys_epoll_pwait // 1305
|
||||
data8 sys_utimensat
|
||||
data8 sys_signalfd
|
||||
data8 sys_timerfd
|
||||
data8 sys_eventfd
|
||||
|
||||
.org sys_call_table + 8*NR_syscalls // guard against failures to increase NR_syscalls
|
||||
|
@ -4,7 +4,7 @@
|
||||
* Copyright (C) 1992, 1998 Linus Torvalds, Ingo Molnar
|
||||
*
|
||||
* This file contains the code used by various IRQ handling routines:
|
||||
* asking for different IRQ's should be done through these routines
|
||||
* asking for different IRQs should be done through these routines
|
||||
* instead of just grabbing them. Thus setups with different IRQ numbers
|
||||
* shouldn't result in any weird surprises, and installing new handlers
|
||||
* should be easier.
|
||||
@ -12,7 +12,7 @@
|
||||
* Copyright (C) Ashok Raj<ashok.raj@intel.com>, Intel Corporation 2004
|
||||
*
|
||||
* 4/14/2004: Added code to handle cpu migration and do safe irq
|
||||
* migration without lossing interrupts for iosapic
|
||||
* migration without losing interrupts for iosapic
|
||||
* architecture.
|
||||
*/
|
||||
|
||||
@ -190,7 +190,7 @@ void fixup_irqs(void)
|
||||
}
|
||||
|
||||
/*
|
||||
* Phase 1: Locate irq's bound to this cpu and
|
||||
* Phase 1: Locate IRQs bound to this cpu and
|
||||
* relocate them for cpu removal.
|
||||
*/
|
||||
migrate_irqs();
|
||||
|
@ -23,7 +23,7 @@ lsapic_noop_startup (unsigned int irq)
|
||||
static void
|
||||
lsapic_noop (unsigned int irq)
|
||||
{
|
||||
/* nuthing to do... */
|
||||
/* nothing to do... */
|
||||
}
|
||||
|
||||
static int lsapic_retrigger(unsigned int irq)
|
||||
|
@ -151,12 +151,12 @@ static uint __kprobes is_cmp_ctype_unc_inst(uint template, uint slot,
|
||||
|
||||
cmp_inst.l = kprobe_inst;
|
||||
if ((cmp_inst.f.x2 == 0) || (cmp_inst.f.x2 == 1)) {
|
||||
/* Integere compare - Register Register (A6 type)*/
|
||||
/* Integer compare - Register Register (A6 type)*/
|
||||
if ((cmp_inst.f.tb == 0) && (cmp_inst.f.ta == 0)
|
||||
&&(cmp_inst.f.c == 1))
|
||||
ctype_unc = 1;
|
||||
} else if ((cmp_inst.f.x2 == 2)||(cmp_inst.f.x2 == 3)) {
|
||||
/* Integere compare - Immediate Register (A8 type)*/
|
||||
/* Integer compare - Immediate Register (A8 type)*/
|
||||
if ((cmp_inst.f.ta == 0) &&(cmp_inst.f.c == 1))
|
||||
ctype_unc = 1;
|
||||
}
|
||||
@ -820,7 +820,7 @@ out:
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int __kprobes kprobes_fault_handler(struct pt_regs *regs, int trapnr)
|
||||
int __kprobes kprobes_fault_handler(struct pt_regs *regs, int trapnr)
|
||||
{
|
||||
struct kprobe *cur = kprobe_running();
|
||||
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
|
||||
@ -904,13 +904,6 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
|
||||
if (post_kprobes_handler(args->regs))
|
||||
ret = NOTIFY_STOP;
|
||||
break;
|
||||
case DIE_PAGE_FAULT:
|
||||
/* kprobe_running() needs smp_processor_id() */
|
||||
preempt_disable();
|
||||
if (kprobe_running() &&
|
||||
kprobes_fault_handler(args->regs, args->trapnr))
|
||||
ret = NOTIFY_STOP;
|
||||
preempt_enable();
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -954,7 +947,7 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
|
||||
/*
|
||||
* Callee owns the argument space and could overwrite it, eg
|
||||
* tail call optimization. So to be absolutely safe
|
||||
* we save the argument space before transfering the control
|
||||
* we save the argument space before transferring the control
|
||||
* to instrumented jprobe function which runs in
|
||||
* the process context
|
||||
*/
|
||||
|
@ -273,7 +273,6 @@ static void ia64_mlogbuf_finish(int wait)
|
||||
|
||||
mlogbuf_finished = 1;
|
||||
}
|
||||
EXPORT_SYMBOL(ia64_mlogbuf_finish);
|
||||
|
||||
/*
|
||||
* Print buffered messages from INIT context.
|
||||
@ -1477,6 +1476,10 @@ default_monarch_init_process(struct notifier_block *self, unsigned long val, voi
|
||||
struct task_struct *g, *t;
|
||||
if (val != DIE_INIT_MONARCH_PROCESS)
|
||||
return NOTIFY_DONE;
|
||||
#ifdef CONFIG_KEXEC
|
||||
if (atomic_read(&kdump_in_progress))
|
||||
return NOTIFY_DONE;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* FIXME: mlogbuf will brim over with INIT stack dumps.
|
||||
|
@ -438,7 +438,7 @@ is_mca_global(peidx_table_t *peidx, pal_bus_check_info_t *pbci,
|
||||
* @peidx: pointer of index of processor error section
|
||||
*
|
||||
* Return value:
|
||||
* target address on Success / 0 on Failue
|
||||
* target address on Success / 0 on Failure
|
||||
*/
|
||||
static u64
|
||||
get_target_identifier(peidx_table_t *peidx)
|
||||
@ -701,7 +701,7 @@ recover_from_processor_error(int platform, slidx_table_t *slidx,
|
||||
return fatal_mca("External bus check fatal status");
|
||||
|
||||
/*
|
||||
* This is a local MCA and estimated as a recoverble error.
|
||||
* This is a local MCA and estimated as a recoverable error.
|
||||
*/
|
||||
if (platform)
|
||||
return recover_from_platform_error(slidx, peidx, pbci, sos);
|
||||
|
@ -861,7 +861,7 @@ apply_relocate (Elf64_Shdr *sechdrs, const char *strtab, unsigned int symindex,
|
||||
/*
|
||||
* Modules contain a single unwind table which covers both the core and the init text
|
||||
* sections but since the two are not contiguous, we need to split this table up such that
|
||||
* we can register (and unregister) each "segment" seperately. Fortunately, this sounds
|
||||
* we can register (and unregister) each "segment" separately. Fortunately, this sounds
|
||||
* more complicated than it really is.
|
||||
*/
|
||||
static void
|
||||
|
@ -1318,7 +1318,7 @@ pfm_reserve_session(struct task_struct *task, int is_syswide, unsigned int cpu)
|
||||
{
|
||||
unsigned long flags;
|
||||
/*
|
||||
* validy checks on cpu_mask have been done upstream
|
||||
* validity checks on cpu_mask have been done upstream
|
||||
*/
|
||||
LOCK_PFS(flags);
|
||||
|
||||
@ -1384,7 +1384,7 @@ pfm_unreserve_session(pfm_context_t *ctx, int is_syswide, unsigned int cpu)
|
||||
{
|
||||
unsigned long flags;
|
||||
/*
|
||||
* validy checks on cpu_mask have been done upstream
|
||||
* validity checks on cpu_mask have been done upstream
|
||||
*/
|
||||
LOCK_PFS(flags);
|
||||
|
||||
@ -1835,7 +1835,7 @@ pfm_flush(struct file *filp, fl_owner_t id)
|
||||
/*
|
||||
* remove our file from the async queue, if we use this mode.
|
||||
* This can be done without the context being protected. We come
|
||||
* here when the context has become unreacheable by other tasks.
|
||||
* here when the context has become unreachable by other tasks.
|
||||
*
|
||||
* We may still have active monitoring at this point and we may
|
||||
* end up in pfm_overflow_handler(). However, fasync_helper()
|
||||
@ -2132,7 +2132,7 @@ doit:
|
||||
filp->private_data = NULL;
|
||||
|
||||
/*
|
||||
* if we free on the spot, the context is now completely unreacheable
|
||||
* if we free on the spot, the context is now completely unreachable
|
||||
* from the callers side. The monitored task side is also cut, so we
|
||||
* can freely cut.
|
||||
*
|
||||
@ -2562,7 +2562,7 @@ pfm_reset_pmu_state(pfm_context_t *ctx)
|
||||
ctx->ctx_all_pmcs[0] = pmu_conf->impl_pmcs[0] & ~0x1;
|
||||
|
||||
/*
|
||||
* bitmask of all PMDs that are accesible to this context
|
||||
* bitmask of all PMDs that are accessible to this context
|
||||
*/
|
||||
ctx->ctx_all_pmds[0] = pmu_conf->impl_pmds[0];
|
||||
|
||||
@ -3395,7 +3395,7 @@ pfm_read_pmds(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
|
||||
if (unlikely(!PMD_IS_IMPL(cnum))) goto error;
|
||||
/*
|
||||
* we can only read the register that we use. That includes
|
||||
* the one we explicitely initialize AND the one we want included
|
||||
* the one we explicitly initialize AND the one we want included
|
||||
* in the sampling buffer (smpl_regs).
|
||||
*
|
||||
* Having this restriction allows optimization in the ctxsw routine
|
||||
@ -3715,7 +3715,7 @@ pfm_restart(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
|
||||
* if non-blocking, then we ensure that the task will go into
|
||||
* pfm_handle_work() before returning to user mode.
|
||||
*
|
||||
* We cannot explicitely reset another task, it MUST always
|
||||
* We cannot explicitly reset another task, it MUST always
|
||||
* be done by the task itself. This works for system wide because
|
||||
* the tool that is controlling the session is logically doing
|
||||
* "self-monitoring".
|
||||
@ -4644,7 +4644,7 @@ pfm_exit_thread(struct task_struct *task)
|
||||
switch(state) {
|
||||
case PFM_CTX_UNLOADED:
|
||||
/*
|
||||
* only comes to thios function if pfm_context is not NULL, i.e., cannot
|
||||
* only comes to this function if pfm_context is not NULL, i.e., cannot
|
||||
* be in unloaded state
|
||||
*/
|
||||
printk(KERN_ERR "perfmon: pfm_exit_thread [%d] ctx unloaded\n", task->pid);
|
||||
@ -5247,7 +5247,7 @@ pfm_end_notify_user(pfm_context_t *ctx)
|
||||
|
||||
/*
|
||||
* main overflow processing routine.
|
||||
* it can be called from the interrupt path or explicitely during the context switch code
|
||||
* it can be called from the interrupt path or explicitly during the context switch code
|
||||
*/
|
||||
static void
|
||||
pfm_overflow_handler(struct task_struct *task, pfm_context_t *ctx, u64 pmc0, struct pt_regs *regs)
|
||||
|
@ -181,7 +181,7 @@ static pmu_config_t pmu_conf_mck={
|
||||
.pmc_desc = pfm_mck_pmc_desc,
|
||||
.num_ibrs = 8,
|
||||
.num_dbrs = 8,
|
||||
.use_rr_dbregs = 1 /* debug register are use for range retrictions */
|
||||
.use_rr_dbregs = 1 /* debug register are use for range restrictions */
|
||||
};
|
||||
|
||||
|
||||
|
@ -134,7 +134,7 @@ set_smp_redirect (int flag)
|
||||
* interrupt redirection. The reason is this would require that
|
||||
* All interrupts be stopped and hard bind the irq to a cpu.
|
||||
* Later when the interrupt is fired we need to set the redir hint
|
||||
* on again in the vector. This is combersome for something that the
|
||||
* on again in the vector. This is cumbersome for something that the
|
||||
* user mode irq balancer will solve anyways.
|
||||
*/
|
||||
no_int_routing=1;
|
||||
|
@ -162,7 +162,7 @@ static DEFINE_SPINLOCK(data_saved_lock);
|
||||
/** salinfo_platform_oemdata - optional callback to decode oemdata from an error
|
||||
* record.
|
||||
* @sect_header: pointer to the start of the section to decode.
|
||||
* @oemdata: returns vmalloc area containing the decded output.
|
||||
* @oemdata: returns vmalloc area containing the decoded output.
|
||||
* @oemdata_size: returns length of decoded output (strlen).
|
||||
*
|
||||
* Description: If user space asks for oem data to be decoded by the kernel
|
||||
|
@ -576,7 +576,7 @@ setup_arch (char **cmdline_p)
|
||||
}
|
||||
|
||||
/*
|
||||
* Display cpu info for all cpu's.
|
||||
* Display cpu info for all CPUs.
|
||||
*/
|
||||
static int
|
||||
show_cpuinfo (struct seq_file *m, void *v)
|
||||
@ -761,7 +761,7 @@ identify_cpu (struct cpuinfo_ia64 *c)
|
||||
c->cpu = smp_processor_id();
|
||||
|
||||
/* below default values will be overwritten by identify_siblings()
|
||||
* for Multi-Threading/Multi-Core capable cpu's
|
||||
* for Multi-Threading/Multi-Core capable CPUs
|
||||
*/
|
||||
c->threads_per_core = c->cores_per_socket = c->num_log = 1;
|
||||
c->socket_id = -1;
|
||||
@ -947,7 +947,7 @@ cpu_init (void)
|
||||
ia32_cpu_init();
|
||||
#endif
|
||||
|
||||
/* Clear ITC to eliminiate sched_clock() overflows in human time. */
|
||||
/* Clear ITC to eliminate sched_clock() overflows in human time. */
|
||||
ia64_set_itc(0);
|
||||
|
||||
/* disable all local interrupt sources: */
|
||||
|
@ -186,7 +186,7 @@ handle_IPI (int irq, void *dev_id)
|
||||
}
|
||||
|
||||
/*
|
||||
* Called with preeemption disabled.
|
||||
* Called with preemption disabled.
|
||||
*/
|
||||
static inline void
|
||||
send_IPI_single (int dest_cpu, int op)
|
||||
@ -196,7 +196,7 @@ send_IPI_single (int dest_cpu, int op)
|
||||
}
|
||||
|
||||
/*
|
||||
* Called with preeemption disabled.
|
||||
* Called with preemption disabled.
|
||||
*/
|
||||
static inline void
|
||||
send_IPI_allbutself (int op)
|
||||
@ -210,7 +210,7 @@ send_IPI_allbutself (int op)
|
||||
}
|
||||
|
||||
/*
|
||||
* Called with preeemption disabled.
|
||||
* Called with preemption disabled.
|
||||
*/
|
||||
static inline void
|
||||
send_IPI_all (int op)
|
||||
@ -223,7 +223,7 @@ send_IPI_all (int op)
|
||||
}
|
||||
|
||||
/*
|
||||
* Called with preeemption disabled.
|
||||
* Called with preemption disabled.
|
||||
*/
|
||||
static inline void
|
||||
send_IPI_self (int op)
|
||||
@ -252,7 +252,7 @@ kdump_smp_send_init(void)
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* Called with preeemption disabled.
|
||||
* Called with preemption disabled.
|
||||
*/
|
||||
void
|
||||
smp_send_reschedule (int cpu)
|
||||
@ -261,7 +261,7 @@ smp_send_reschedule (int cpu)
|
||||
}
|
||||
|
||||
/*
|
||||
* Called with preeemption disabled.
|
||||
* Called with preemption disabled.
|
||||
*/
|
||||
static void
|
||||
smp_send_local_flush_tlb (int cpu)
|
||||
|
@ -694,7 +694,7 @@ int migrate_platform_irqs(unsigned int cpu)
|
||||
set_cpei_target_cpu(new_cpei_cpu);
|
||||
desc = irq_desc + ia64_cpe_irq;
|
||||
/*
|
||||
* Switch for now, immediatly, we need to do fake intr
|
||||
* Switch for now, immediately, we need to do fake intr
|
||||
* as other interrupts, but need to study CPEI behaviour with
|
||||
* polling before making changes.
|
||||
*/
|
||||
@ -840,7 +840,7 @@ __cpu_up (unsigned int cpu)
|
||||
}
|
||||
|
||||
/*
|
||||
* Assume that CPU's have been discovered by some platform-dependent interface. For
|
||||
* Assume that CPUs have been discovered by some platform-dependent interface. For
|
||||
* SoftSDV/Lion, that would be ACPI.
|
||||
*
|
||||
* Setup of the IPI irq handler is done in irq.c:init_IRQ_SMP().
|
||||
@ -854,7 +854,7 @@ init_smp_config(void)
|
||||
} *ap_startup;
|
||||
long sal_ret;
|
||||
|
||||
/* Tell SAL where to drop the AP's. */
|
||||
/* Tell SAL where to drop the APs. */
|
||||
ap_startup = (struct fptr *) start_ap;
|
||||
sal_ret = ia64_sal_set_vectors(SAL_VECTOR_OS_BOOT_RENDEZ,
|
||||
ia64_tpa(ap_startup->fp), ia64_tpa(ap_startup->gp), 0, 0, 0, 0);
|
||||
|
@ -304,7 +304,7 @@ handle_fpu_swa (int fp_fault, struct pt_regs *regs, unsigned long isr)
|
||||
* Lower 4 bits are used as a count. Upper bits are a sequence
|
||||
* number that is updated when count is reset. The cmpxchg will
|
||||
* fail is seqno has changed. This minimizes mutiple cpus
|
||||
* reseting the count.
|
||||
* resetting the count.
|
||||
*/
|
||||
if (current_jiffies > last.time)
|
||||
(void) cmpxchg_acq(&last.count, count, 16 + (count & ~15));
|
||||
|
@ -2,7 +2,7 @@
|
||||
* Copyright (C) 1999-2004 Hewlett-Packard Co
|
||||
* David Mosberger-Tang <davidm@hpl.hp.com>
|
||||
* Copyright (C) 2003 Fenghua Yu <fenghua.yu@intel.com>
|
||||
* - Change pt_regs_off() to make it less dependant on pt_regs structure.
|
||||
* - Change pt_regs_off() to make it less dependent on pt_regs structure.
|
||||
*/
|
||||
/*
|
||||
* This file implements call frame unwind support for the Linux
|
||||
|
@ -317,7 +317,7 @@ static void __meminit scatter_node_data(void)
|
||||
* node_online_map is not set for hot-added nodes at this time,
|
||||
* because we are halfway through initialization of the new node's
|
||||
* structures. If for_each_online_node() is used, a new node's
|
||||
* pg_data_ptrs will be not initialized. Insted of using it,
|
||||
* pg_data_ptrs will be not initialized. Instead of using it,
|
||||
* pgdat_list[] is checked.
|
||||
*/
|
||||
for_each_node(node) {
|
||||
|
@ -19,36 +19,24 @@
|
||||
extern void die (char *, struct pt_regs *, long);
|
||||
|
||||
#ifdef CONFIG_KPROBES
|
||||
ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain);
|
||||
|
||||
/* Hook to register for page fault notifications */
|
||||
int register_page_fault_notifier(struct notifier_block *nb)
|
||||
static inline int notify_page_fault(struct pt_regs *regs, int trap)
|
||||
{
|
||||
return atomic_notifier_chain_register(¬ify_page_fault_chain, nb);
|
||||
int ret = 0;
|
||||
|
||||
if (!user_mode(regs)) {
|
||||
/* kprobe_running() needs smp_processor_id() */
|
||||
preempt_disable();
|
||||
if (kprobe_running() && kprobes_fault_handler(regs, trap))
|
||||
ret = 1;
|
||||
preempt_enable();
|
||||
}
|
||||
|
||||
int unregister_page_fault_notifier(struct notifier_block *nb)
|
||||
{
|
||||
return atomic_notifier_chain_unregister(¬ify_page_fault_chain, nb);
|
||||
}
|
||||
|
||||
static inline int notify_page_fault(enum die_val val, const char *str,
|
||||
struct pt_regs *regs, long err, int trap, int sig)
|
||||
{
|
||||
struct die_args args = {
|
||||
.regs = regs,
|
||||
.str = str,
|
||||
.err = err,
|
||||
.trapnr = trap,
|
||||
.signr = sig
|
||||
};
|
||||
return atomic_notifier_call_chain(¬ify_page_fault_chain, val, &args);
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
static inline int notify_page_fault(enum die_val val, const char *str,
|
||||
struct pt_regs *regs, long err, int trap, int sig)
|
||||
static inline int notify_page_fault(struct pt_regs *regs, int trap)
|
||||
{
|
||||
return NOTIFY_DONE;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -117,8 +105,7 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re
|
||||
/*
|
||||
* This is to handle the kprobes on user space access instructions
|
||||
*/
|
||||
if (notify_page_fault(DIE_PAGE_FAULT, "page fault", regs, code, TRAP_BRKPT,
|
||||
SIGSEGV) == NOTIFY_STOP)
|
||||
if (notify_page_fault(regs, TRAP_BRKPT))
|
||||
return;
|
||||
|
||||
down_read(&mm->mmap_sem);
|
||||
|
@ -63,7 +63,7 @@ static inline void bte_start_transfer(struct bteinfo_s *bte, u64 len, u64 mode)
|
||||
* Use the block transfer engine to move kernel memory from src to dest
|
||||
* using the assigned mode.
|
||||
*
|
||||
* Paramaters:
|
||||
* Parameters:
|
||||
* src - physical address of the transfer source.
|
||||
* dest - physical address of the transfer destination.
|
||||
* len - number of bytes to transfer from source to dest.
|
||||
@ -247,7 +247,7 @@ EXPORT_SYMBOL(bte_copy);
|
||||
* use the block transfer engine to move kernel
|
||||
* memory from src to dest using the assigned mode.
|
||||
*
|
||||
* Paramaters:
|
||||
* Parameters:
|
||||
* src - physical address of the transfer source.
|
||||
* dest - physical address of the transfer destination.
|
||||
* len - number of bytes to transfer from source to dest.
|
||||
@ -255,7 +255,7 @@ EXPORT_SYMBOL(bte_copy);
|
||||
* for IBCT0/1 in the SGI documentation.
|
||||
*
|
||||
* NOTE: If the source, dest, and len are all cache line aligned,
|
||||
* then it would be _FAR_ preferrable to use bte_copy instead.
|
||||
* then it would be _FAR_ preferable to use bte_copy instead.
|
||||
*/
|
||||
bte_result_t bte_unaligned_copy(u64 src, u64 dest, u64 len, u64 mode)
|
||||
{
|
||||
@ -300,7 +300,7 @@ bte_result_t bte_unaligned_copy(u64 src, u64 dest, u64 len, u64 mode)
|
||||
* a standard bte copy.
|
||||
*
|
||||
* One nasty exception to the above rule is when the
|
||||
* source and destination are not symetrically
|
||||
* source and destination are not symmetrically
|
||||
* mis-aligned. If the source offset from the first
|
||||
* cache line is different from the destination offset,
|
||||
* we make the first section be the entire transfer
|
||||
@ -337,7 +337,7 @@ bte_result_t bte_unaligned_copy(u64 src, u64 dest, u64 len, u64 mode)
|
||||
|
||||
if (footBcopyDest == (headBcopyDest + headBcopyLen)) {
|
||||
/*
|
||||
* We have two contigous bcopy
|
||||
* We have two contiguous bcopy
|
||||
* blocks. Merge them.
|
||||
*/
|
||||
headBcopyLen += footBcopyLen;
|
||||
@ -375,7 +375,7 @@ bte_result_t bte_unaligned_copy(u64 src, u64 dest, u64 len, u64 mode)
|
||||
} else {
|
||||
|
||||
/*
|
||||
* The transfer is not symetric, we will
|
||||
* The transfer is not symmetric, we will
|
||||
* allocate a buffer large enough for all the
|
||||
* data, bte_copy into that buffer and then
|
||||
* bcopy to the destination.
|
||||
|
@ -105,7 +105,7 @@ int shub1_bte_error_handler(unsigned long _nodepda)
|
||||
}
|
||||
|
||||
BTE_PRINTK(("eh:%p:%d Cleaning up\n", err_nodepda, smp_processor_id()));
|
||||
/* Reenable both bte interfaces */
|
||||
/* Re-enable both bte interfaces */
|
||||
imem.ii_imem_regval = REMOTE_HUB_L(nasid, IIO_IMEM);
|
||||
imem.ii_imem_fld_s.i_b0_esd = imem.ii_imem_fld_s.i_b1_esd = 1;
|
||||
REMOTE_HUB_S(nasid, IIO_IMEM, imem.ii_imem_regval);
|
||||
@ -243,7 +243,7 @@ bte_crb_error_handler(cnodeid_t cnode, int btenum,
|
||||
|
||||
/*
|
||||
* The caller has already figured out the error type, we save that
|
||||
* in the bte handle structure for the thread excercising the
|
||||
* in the bte handle structure for the thread exercising the
|
||||
* interface to consume.
|
||||
*/
|
||||
bte->bh_error = ioe->ie_errortype + BTEFAIL_OFFSET;
|
||||
|
@ -479,7 +479,7 @@ sn_io_early_init(void)
|
||||
}
|
||||
|
||||
/*
|
||||
* prime sn_pci_provider[]. Individial provider init routines will
|
||||
* prime sn_pci_provider[]. Individual provider init routines will
|
||||
* override their respective default entries.
|
||||
*/
|
||||
|
||||
|
@ -104,7 +104,7 @@ static inline unsigned long wait_piowc(void)
|
||||
*
|
||||
* SN2 PIO writes from separate CPUs are not guaranteed to arrive in order.
|
||||
* Context switching user threads which have memory-mapped MMIO may cause
|
||||
* PIOs to issue from seperate CPUs, thus the PIO writes must be drained
|
||||
* PIOs to issue from separate CPUs, thus the PIO writes must be drained
|
||||
* from the previous CPU's Shub before execution resumes on the new CPU.
|
||||
*/
|
||||
void sn_migrate(struct task_struct *task)
|
||||
|
@ -293,7 +293,7 @@ xpc_pull_remote_cachelines(struct xpc_partition *part, void *dst,
|
||||
|
||||
|
||||
/*
|
||||
* Pull the remote per partititon specific variables from the specified
|
||||
* Pull the remote per partition specific variables from the specified
|
||||
* partition.
|
||||
*/
|
||||
enum xpc_retval
|
||||
@ -461,7 +461,7 @@ xpc_allocate_local_msgqueue(struct xpc_channel *ch)
|
||||
// >>> may want to check for ch->flags & XPC_C_DISCONNECTING between
|
||||
// >>> iterations of the for-loop, bail if set?
|
||||
|
||||
// >>> should we impose a minumum #of entries? like 4 or 8?
|
||||
// >>> should we impose a minimum #of entries? like 4 or 8?
|
||||
for (nentries = ch->local_nentries; nentries > 0; nentries--) {
|
||||
|
||||
nbytes = nentries * ch->msg_size;
|
||||
@ -514,7 +514,7 @@ xpc_allocate_remote_msgqueue(struct xpc_channel *ch)
|
||||
// >>> may want to check for ch->flags & XPC_C_DISCONNECTING between
|
||||
// >>> iterations of the for-loop, bail if set?
|
||||
|
||||
// >>> should we impose a minumum #of entries? like 4 or 8?
|
||||
// >>> should we impose a minimum #of entries? like 4 or 8?
|
||||
for (nentries = ch->remote_nentries; nentries > 0; nentries--) {
|
||||
|
||||
nbytes = nentries * ch->msg_size;
|
||||
@ -1478,7 +1478,7 @@ xpc_teardown_infrastructure(struct xpc_partition *part)
|
||||
|
||||
|
||||
/*
|
||||
* Before proceding with the teardown we have to wait until all
|
||||
* Before proceeding with the teardown we have to wait until all
|
||||
* existing references cease.
|
||||
*/
|
||||
wait_event(part->teardown_wq, (atomic_read(&part->references) == 0));
|
||||
|
@ -531,7 +531,7 @@ xpnet_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
dev_dbg(xpnet, "destination Partitions mask (dp) = 0x%lx\n", dp);
|
||||
|
||||
/*
|
||||
* If we wanted to allow promiscous mode to work like an
|
||||
* If we wanted to allow promiscuous mode to work like an
|
||||
* unswitched network, this would be a good point to OR in a
|
||||
* mask of partitions which should be receiving all packets.
|
||||
*/
|
||||
|
@ -333,7 +333,7 @@ int sn_pci_legacy_read(struct pci_bus *bus, u16 port, u32 *val, u8 size)
|
||||
/*
|
||||
* First, try the SN_SAL_IOIF_PCI_SAFE SAL call which can work
|
||||
* around hw issues at the pci bus level. SGI proms older than
|
||||
* 4.10 don't implment this.
|
||||
* 4.10 don't implement this.
|
||||
*/
|
||||
|
||||
SAL_CALL(isrv, SN_SAL_IOIF_PCI_SAFE,
|
||||
@ -348,7 +348,7 @@ int sn_pci_legacy_read(struct pci_bus *bus, u16 port, u32 *val, u8 size)
|
||||
/*
|
||||
* If the above failed, retry using the SAL_PROBE call which should
|
||||
* be present in all proms (but which cannot work round PCI chipset
|
||||
* bugs). This code is retained for compatability with old
|
||||
* bugs). This code is retained for compatibility with old
|
||||
* pre-4.10 proms, and should be removed at some point in the future.
|
||||
*/
|
||||
|
||||
@ -379,7 +379,7 @@ int sn_pci_legacy_write(struct pci_bus *bus, u16 port, u32 val, u8 size)
|
||||
/*
|
||||
* First, try the SN_SAL_IOIF_PCI_SAFE SAL call which can work
|
||||
* around hw issues at the pci bus level. SGI proms older than
|
||||
* 4.10 don't implment this.
|
||||
* 4.10 don't implement this.
|
||||
*/
|
||||
|
||||
SAL_CALL(isrv, SN_SAL_IOIF_PCI_SAFE,
|
||||
@ -394,7 +394,7 @@ int sn_pci_legacy_write(struct pci_bus *bus, u16 port, u32 val, u8 size)
|
||||
/*
|
||||
* If the above failed, retry using the SAL_PROBE call which should
|
||||
* be present in all proms (but which cannot work round PCI chipset
|
||||
* bugs). This code is retained for compatability with old
|
||||
* bugs). This code is retained for compatibility with old
|
||||
* pre-4.10 proms, and should be removed at some point in the future.
|
||||
*/
|
||||
|
||||
|
@ -30,7 +30,7 @@ static void mark_ate(struct ate_resource *ate_resource, int start, int number,
|
||||
|
||||
/*
|
||||
* find_free_ate: Find the first free ate index starting from the given
|
||||
* index for the desired consequtive count.
|
||||
* index for the desired consecutive count.
|
||||
*/
|
||||
static int find_free_ate(struct ate_resource *ate_resource, int start,
|
||||
int count)
|
||||
@ -88,7 +88,7 @@ static inline int alloc_ate_resource(struct ate_resource *ate_resource,
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* Find the required number of free consequtive ates.
|
||||
* Find the required number of free consecutive ates.
|
||||
*/
|
||||
start_index =
|
||||
find_free_ate(ate_resource, ate_resource->lowest_free_index,
|
||||
@ -105,7 +105,7 @@ static inline int alloc_ate_resource(struct ate_resource *ate_resource,
|
||||
/*
|
||||
* Allocate "count" contiguous Bridge Address Translation Entries
|
||||
* on the specified bridge to be used for PCI to XTALK mappings.
|
||||
* Indices in rm map range from 1..num_entries. Indicies returned
|
||||
* Indices in rm map range from 1..num_entries. Indices returned
|
||||
* to caller range from 0..num_entries-1.
|
||||
*
|
||||
* Return the start index on success, -1 on failure.
|
||||
|
@ -201,7 +201,7 @@ pcibr_dmatrans_direct32(struct pcidev_info * info,
|
||||
}
|
||||
|
||||
/*
|
||||
* Wrapper routine for free'ing DMA maps
|
||||
* Wrapper routine for freeing DMA maps
|
||||
* DMA mappings for Direct 64 and 32 do not have any DMA maps.
|
||||
*/
|
||||
void
|
||||
|
@ -223,7 +223,7 @@ tioca_fastwrite_enable(struct tioca_kernel *tioca_kern)
|
||||
|
||||
/*
|
||||
* Scan all vga controllers on this bus making sure they all
|
||||
* suport FW. If not, return.
|
||||
* support FW. If not, return.
|
||||
*/
|
||||
|
||||
list_for_each_entry(pdev, tioca_kern->ca_devices, bus_list) {
|
||||
@ -364,7 +364,7 @@ tioca_dma_d48(struct pci_dev *pdev, u64 paddr)
|
||||
* @req_size: len (bytes) to map
|
||||
*
|
||||
* Map @paddr into CA address space using the GART mechanism. The mapped
|
||||
* dma_addr_t is guarenteed to be contiguous in CA bus space.
|
||||
* dma_addr_t is guaranteed to be contiguous in CA bus space.
|
||||
*/
|
||||
static dma_addr_t
|
||||
tioca_dma_mapped(struct pci_dev *pdev, u64 paddr, size_t req_size)
|
||||
@ -526,7 +526,7 @@ tioca_dma_map(struct pci_dev *pdev, u64 paddr, size_t byte_count, int dma_flags)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* If card is 64 or 48 bit addresable, use a direct mapping. 32
|
||||
* If card is 64 or 48 bit addressable, use a direct mapping. 32
|
||||
* bit direct is so restrictive w.r.t. where the memory resides that
|
||||
* we don't use it even though CA has some support.
|
||||
*/
|
||||
|
@ -256,9 +256,9 @@ pcidev_to_tioce(struct pci_dev *pdev, struct tioce __iomem **base,
|
||||
* @ct_addr: the coretalk address to map
|
||||
* @len: number of bytes to map
|
||||
*
|
||||
* Given the addressing type, set up various paramaters that define the
|
||||
* Given the addressing type, set up various parameters that define the
|
||||
* ATE pool to use. Search for a contiguous block of entries to cover the
|
||||
* length, and if enough resources exist, fill in the ATE's and construct a
|
||||
* length, and if enough resources exist, fill in the ATEs and construct a
|
||||
* tioce_dmamap struct to track the mapping.
|
||||
*/
|
||||
static u64
|
||||
@ -581,8 +581,8 @@ tioce_do_dma_map(struct pci_dev *pdev, u64 paddr, size_t byte_count,
|
||||
*/
|
||||
if (!mapaddr && !barrier && dma_mask >= 0xffffffffffUL) {
|
||||
/*
|
||||
* We have two options for 40-bit mappings: 16GB "super" ATE's
|
||||
* and 64MB "regular" ATE's. We'll try both if needed for a
|
||||
* We have two options for 40-bit mappings: 16GB "super" ATEs
|
||||
* and 64MB "regular" ATEs. We'll try both if needed for a
|
||||
* given mapping but which one we try first depends on the
|
||||
* size. For requests >64MB, prefer to use a super page with
|
||||
* regular as the fallback. Otherwise, try in the reverse order.
|
||||
@ -687,8 +687,8 @@ tioce_error_intr_handler(int irq, void *arg)
|
||||
}
|
||||
|
||||
/**
|
||||
* tioce_reserve_m32 - reserve M32 ate's for the indicated address range
|
||||
* @tioce_kernel: TIOCE context to reserve ate's for
|
||||
* tioce_reserve_m32 - reserve M32 ATEs for the indicated address range
|
||||
* @tioce_kernel: TIOCE context to reserve ATEs for
|
||||
* @base: starting bus address to reserve
|
||||
* @limit: last bus address to reserve
|
||||
*
|
||||
@ -763,7 +763,7 @@ tioce_kern_init(struct tioce_common *tioce_common)
|
||||
|
||||
/*
|
||||
* Set PMU pagesize to the largest size available, and zero out
|
||||
* the ate's.
|
||||
* the ATEs.
|
||||
*/
|
||||
|
||||
tioce_mmr = (struct tioce __iomem *)tioce_common->ce_pcibus.bs_base;
|
||||
@ -784,7 +784,7 @@ tioce_kern_init(struct tioce_common *tioce_common)
|
||||
}
|
||||
|
||||
/*
|
||||
* Reserve ATE's corresponding to reserved address ranges. These
|
||||
* Reserve ATEs corresponding to reserved address ranges. These
|
||||
* include:
|
||||
*
|
||||
* Memory space covered by each PPB mem base/limit register
|
||||
|
@ -12,7 +12,7 @@ obj-y := process.o setup.o cpu.o idprom.o \
|
||||
irq.o ptrace.o time.o sys_sparc.o signal.o \
|
||||
unaligned.o central.o pci.o starfire.o semaphore.o \
|
||||
power.o sbus.o iommu_common.o sparc64_ksyms.o chmc.o \
|
||||
visemul.o prom.o of_device.o
|
||||
visemul.o prom.o of_device.o hvapi.o
|
||||
|
||||
obj-$(CONFIG_STACKTRACE) += stacktrace.o
|
||||
obj-$(CONFIG_PCI) += ebus.o isa.o pci_common.o pci_iommu.o \
|
||||
|
@ -1843,3 +1843,97 @@ sun4v_cpu_state:
|
||||
mov %o1, %o0
|
||||
1: retl
|
||||
nop
|
||||
|
||||
/* %o0: API group number
|
||||
* %o1: pointer to unsigned long major number storage
|
||||
* %o2: pointer to unsigned long minor number storage
|
||||
*
|
||||
* returns %o0: status
|
||||
*/
|
||||
.globl sun4v_get_version
|
||||
sun4v_get_version:
|
||||
mov HV_CORE_GET_VER, %o5
|
||||
mov %o1, %o3
|
||||
mov %o2, %o4
|
||||
ta HV_CORE_TRAP
|
||||
stx %o1, [%o3]
|
||||
retl
|
||||
stx %o2, [%o4]
|
||||
|
||||
/* %o0: API group number
|
||||
* %o1: desired major number
|
||||
* %o2: desired minor number
|
||||
* %o3: pointer to unsigned long actual minor number storage
|
||||
*
|
||||
* returns %o0: status
|
||||
*/
|
||||
.globl sun4v_set_version
|
||||
sun4v_set_version:
|
||||
mov HV_CORE_SET_VER, %o5
|
||||
mov %o3, %o4
|
||||
ta HV_CORE_TRAP
|
||||
retl
|
||||
stx %o1, [%o4]
|
||||
|
||||
/* %o0: pointer to unsigned long status
|
||||
*
|
||||
* returns %o0: signed character
|
||||
*/
|
||||
.globl sun4v_con_getchar
|
||||
sun4v_con_getchar:
|
||||
mov %o0, %o4
|
||||
mov HV_FAST_CONS_GETCHAR, %o5
|
||||
clr %o0
|
||||
clr %o1
|
||||
ta HV_FAST_TRAP
|
||||
stx %o0, [%o4]
|
||||
retl
|
||||
sra %o1, 0, %o0
|
||||
|
||||
/* %o0: signed long character
|
||||
*
|
||||
* returns %o0: status
|
||||
*/
|
||||
.globl sun4v_con_putchar
|
||||
sun4v_con_putchar:
|
||||
mov HV_FAST_CONS_PUTCHAR, %o5
|
||||
ta HV_FAST_TRAP
|
||||
retl
|
||||
sra %o0, 0, %o0
|
||||
|
||||
/* %o0: buffer real address
|
||||
* %o1: buffer size
|
||||
* %o2: pointer to unsigned long bytes_read
|
||||
*
|
||||
* returns %o0: status
|
||||
*/
|
||||
.globl sun4v_con_read
|
||||
sun4v_con_read:
|
||||
mov %o2, %o4
|
||||
mov HV_FAST_CONS_READ, %o5
|
||||
ta HV_FAST_TRAP
|
||||
brnz %o0, 1f
|
||||
cmp %o1, -1 /* break */
|
||||
be,a,pn %icc, 1f
|
||||
mov %o1, %o0
|
||||
cmp %o1, -2 /* hup */
|
||||
be,a,pn %icc, 1f
|
||||
mov %o1, %o0
|
||||
stx %o1, [%o4]
|
||||
1: retl
|
||||
nop
|
||||
|
||||
/* %o0: buffer real address
|
||||
* %o1: buffer size
|
||||
* %o2: pointer to unsigned long bytes_written
|
||||
*
|
||||
* returns %o0: status
|
||||
*/
|
||||
.globl sun4v_con_write
|
||||
sun4v_con_write:
|
||||
mov %o2, %o4
|
||||
mov HV_FAST_CONS_WRITE, %o5
|
||||
ta HV_FAST_TRAP
|
||||
stx %o1, [%o4]
|
||||
retl
|
||||
nop
|
||||
|
189
arch/sparc64/kernel/hvapi.c
Normal file
189
arch/sparc64/kernel/hvapi.c
Normal file
@ -0,0 +1,189 @@
|
||||
/* hvapi.c: Hypervisor API management.
|
||||
*
|
||||
* Copyright (C) 2007 David S. Miller <davem@davemloft.net>
|
||||
*/
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <asm/hypervisor.h>
|
||||
#include <asm/oplib.h>
|
||||
|
||||
/* If the hypervisor indicates that the API setting
|
||||
* calls are unsupported, by returning HV_EBADTRAP or
|
||||
* HV_ENOTSUPPORTED, we assume that API groups with the
|
||||
* PRE_API flag set are major 1 minor 0.
|
||||
*/
|
||||
struct api_info {
|
||||
unsigned long group;
|
||||
unsigned long major;
|
||||
unsigned long minor;
|
||||
unsigned int refcnt;
|
||||
unsigned int flags;
|
||||
#define FLAG_PRE_API 0x00000001
|
||||
};
|
||||
|
||||
static struct api_info api_table[] = {
|
||||
{ .group = HV_GRP_SUN4V, .flags = FLAG_PRE_API },
|
||||
{ .group = HV_GRP_CORE, .flags = FLAG_PRE_API },
|
||||
{ .group = HV_GRP_INTR, },
|
||||
{ .group = HV_GRP_SOFT_STATE, },
|
||||
{ .group = HV_GRP_PCI, .flags = FLAG_PRE_API },
|
||||
{ .group = HV_GRP_LDOM, },
|
||||
{ .group = HV_GRP_SVC_CHAN, .flags = FLAG_PRE_API },
|
||||
{ .group = HV_GRP_NCS, .flags = FLAG_PRE_API },
|
||||
{ .group = HV_GRP_NIAG_PERF, .flags = FLAG_PRE_API },
|
||||
{ .group = HV_GRP_FIRE_PERF, },
|
||||
{ .group = HV_GRP_DIAG, .flags = FLAG_PRE_API },
|
||||
};
|
||||
|
||||
static DEFINE_SPINLOCK(hvapi_lock);
|
||||
|
||||
static struct api_info *__get_info(unsigned long group)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(api_table); i++) {
|
||||
if (api_table[i].group == group)
|
||||
return &api_table[i];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void __get_ref(struct api_info *p)
|
||||
{
|
||||
p->refcnt++;
|
||||
}
|
||||
|
||||
static void __put_ref(struct api_info *p)
|
||||
{
|
||||
if (--p->refcnt == 0) {
|
||||
unsigned long ignore;
|
||||
|
||||
sun4v_set_version(p->group, 0, 0, &ignore);
|
||||
p->major = p->minor = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Register a hypervisor API specification. It indicates the
|
||||
* API group and desired major+minor.
|
||||
*
|
||||
* If an existing API registration exists '0' (success) will
|
||||
* be returned if it is compatible with the one being registered.
|
||||
* Otherwise a negative error code will be returned.
|
||||
*
|
||||
* Otherwise an attempt will be made to negotiate the requested
|
||||
* API group/major/minor with the hypervisor, and errors returned
|
||||
* if that does not succeed.
|
||||
*/
|
||||
int sun4v_hvapi_register(unsigned long group, unsigned long major,
|
||||
unsigned long *minor)
|
||||
{
|
||||
struct api_info *p;
|
||||
unsigned long flags;
|
||||
int ret;
|
||||
|
||||
spin_lock_irqsave(&hvapi_lock, flags);
|
||||
p = __get_info(group);
|
||||
ret = -EINVAL;
|
||||
if (p) {
|
||||
if (p->refcnt) {
|
||||
ret = -EINVAL;
|
||||
if (p->major == major) {
|
||||
*minor = p->minor;
|
||||
ret = 0;
|
||||
}
|
||||
} else {
|
||||
unsigned long actual_minor;
|
||||
unsigned long hv_ret;
|
||||
|
||||
hv_ret = sun4v_set_version(group, major, *minor,
|
||||
&actual_minor);
|
||||
ret = -EINVAL;
|
||||
if (hv_ret == HV_EOK) {
|
||||
*minor = actual_minor;
|
||||
p->major = major;
|
||||
p->minor = actual_minor;
|
||||
ret = 0;
|
||||
} else if (hv_ret == HV_EBADTRAP ||
|
||||
HV_ENOTSUPPORTED) {
|
||||
if (p->flags & FLAG_PRE_API) {
|
||||
if (major == 1) {
|
||||
p->major = 1;
|
||||
p->minor = 0;
|
||||
*minor = 0;
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0)
|
||||
__get_ref(p);
|
||||
}
|
||||
spin_unlock_irqrestore(&hvapi_lock, flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(sun4v_hvapi_register);
|
||||
|
||||
void sun4v_hvapi_unregister(unsigned long group)
|
||||
{
|
||||
struct api_info *p;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&hvapi_lock, flags);
|
||||
p = __get_info(group);
|
||||
if (p)
|
||||
__put_ref(p);
|
||||
spin_unlock_irqrestore(&hvapi_lock, flags);
|
||||
}
|
||||
EXPORT_SYMBOL(sun4v_hvapi_unregister);
|
||||
|
||||
int sun4v_hvapi_get(unsigned long group,
|
||||
unsigned long *major,
|
||||
unsigned long *minor)
|
||||
{
|
||||
struct api_info *p;
|
||||
unsigned long flags;
|
||||
int ret;
|
||||
|
||||
spin_lock_irqsave(&hvapi_lock, flags);
|
||||
ret = -EINVAL;
|
||||
p = __get_info(group);
|
||||
if (p && p->refcnt) {
|
||||
*major = p->major;
|
||||
*minor = p->minor;
|
||||
ret = 0;
|
||||
}
|
||||
spin_unlock_irqrestore(&hvapi_lock, flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(sun4v_hvapi_get);
|
||||
|
||||
void __init sun4v_hvapi_init(void)
|
||||
{
|
||||
unsigned long group, major, minor;
|
||||
|
||||
group = HV_GRP_SUN4V;
|
||||
major = 1;
|
||||
minor = 0;
|
||||
if (sun4v_hvapi_register(group, major, &minor))
|
||||
goto bad;
|
||||
|
||||
group = HV_GRP_CORE;
|
||||
major = 1;
|
||||
minor = 1;
|
||||
if (sun4v_hvapi_register(group, major, &minor))
|
||||
goto bad;
|
||||
|
||||
return;
|
||||
|
||||
bad:
|
||||
prom_printf("HVAPI: Cannot register API group "
|
||||
"%lx with major(%u) minor(%u)\n",
|
||||
group, major, minor);
|
||||
prom_halt();
|
||||
}
|
@ -269,6 +269,7 @@ void __init per_cpu_patch(void)
|
||||
|
||||
void __init sun4v_patch(void)
|
||||
{
|
||||
extern void sun4v_hvapi_init(void);
|
||||
struct sun4v_1insn_patch_entry *p1;
|
||||
struct sun4v_2insn_patch_entry *p2;
|
||||
|
||||
@ -300,6 +301,8 @@ void __init sun4v_patch(void)
|
||||
|
||||
p2++;
|
||||
}
|
||||
|
||||
sun4v_hvapi_init();
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
|
@ -173,7 +173,8 @@ enum {
|
||||
|
||||
AHCI_FLAG_COMMON = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
|
||||
ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
|
||||
ATA_FLAG_SKIP_D2H_BSY,
|
||||
ATA_FLAG_SKIP_D2H_BSY |
|
||||
ATA_FLAG_ACPI_SATA,
|
||||
};
|
||||
|
||||
struct ahci_cmd_hdr {
|
||||
|
@ -321,7 +321,7 @@ static int do_drive_get_GTF(struct ata_device *dev, unsigned int *gtf_length,
|
||||
|
||||
/* Don't continue if device has no _ADR method.
|
||||
* _GTF is intended for known motherboard devices. */
|
||||
if (!(ap->cbl == ATA_CBL_SATA)) {
|
||||
if (!(ap->flags & ATA_FLAG_ACPI_SATA)) {
|
||||
err = pata_get_dev_handle(gdev, &dev_handle, &pcidevfn);
|
||||
if (err < 0) {
|
||||
if (ata_msg_probe(ap))
|
||||
@ -343,7 +343,7 @@ static int do_drive_get_GTF(struct ata_device *dev, unsigned int *gtf_length,
|
||||
|
||||
/* Get this drive's _ADR info. if not already known. */
|
||||
if (!dev->obj_handle) {
|
||||
if (!(ap->cbl == ATA_CBL_SATA)) {
|
||||
if (!(ap->flags & ATA_FLAG_ACPI_SATA)) {
|
||||
/* get child objects of dev_handle == channel objects,
|
||||
* + _their_ children == drive objects */
|
||||
/* channel is ap->port_no */
|
||||
@ -528,7 +528,7 @@ static int do_drive_set_taskfiles(struct ata_device *dev,
|
||||
ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER: port#: %d\n",
|
||||
__FUNCTION__, ap->port_no);
|
||||
|
||||
if (libata_noacpi || !(ap->cbl == ATA_CBL_SATA))
|
||||
if (libata_noacpi || !(ap->flags & ATA_FLAG_ACPI_SATA))
|
||||
return 0;
|
||||
|
||||
if (!ata_dev_enabled(dev) || (ap->flags & ATA_FLAG_DISABLED))
|
||||
@ -578,7 +578,7 @@ int ata_acpi_exec_tfs(struct ata_port *ap)
|
||||
* we should not run GTF on PATA devices since some
|
||||
* PATA require execution of GTM/STM before GTF.
|
||||
*/
|
||||
if (!(ap->cbl == ATA_CBL_SATA))
|
||||
if (!(ap->flags & ATA_FLAG_ACPI_SATA))
|
||||
return 0;
|
||||
|
||||
for (ix = 0; ix < ATA_MAX_DEVICES; ix++) {
|
||||
@ -641,7 +641,7 @@ int ata_acpi_push_id(struct ata_device *dev)
|
||||
__FUNCTION__, dev->devno, ap->port_no);
|
||||
|
||||
/* Don't continue if not a SATA device. */
|
||||
if (!(ap->cbl == ATA_CBL_SATA)) {
|
||||
if (!(ap->flags & ATA_FLAG_ACPI_SATA)) {
|
||||
if (ata_msg_probe(ap))
|
||||
ata_dev_printk(dev, KERN_DEBUG,
|
||||
"%s: Not a SATA device\n", __FUNCTION__);
|
||||
|
@ -1919,7 +1919,6 @@ int ata_dev_configure(struct ata_device *dev)
|
||||
snprintf(revbuf, 7, "ATA-%d", ata_id_major_version(id));
|
||||
|
||||
dev->n_sectors = ata_id_n_sectors(id);
|
||||
dev->n_sectors_boot = dev->n_sectors;
|
||||
|
||||
/* SCSI only uses 4-char revisions, dump full 8 chars from ATA */
|
||||
ata_id_c_string(dev->id, fwrevbuf, ATA_ID_FW_REV,
|
||||
@ -3632,7 +3631,6 @@ static int ata_dev_same_device(struct ata_device *dev, unsigned int new_class,
|
||||
const u16 *old_id = dev->id;
|
||||
unsigned char model[2][ATA_ID_PROD_LEN + 1];
|
||||
unsigned char serial[2][ATA_ID_SERNO_LEN + 1];
|
||||
u64 new_n_sectors;
|
||||
|
||||
if (dev->class != new_class) {
|
||||
ata_dev_printk(dev, KERN_INFO, "class mismatch %d != %d\n",
|
||||
@ -3644,7 +3642,6 @@ static int ata_dev_same_device(struct ata_device *dev, unsigned int new_class,
|
||||
ata_id_c_string(new_id, model[1], ATA_ID_PROD, sizeof(model[1]));
|
||||
ata_id_c_string(old_id, serial[0], ATA_ID_SERNO, sizeof(serial[0]));
|
||||
ata_id_c_string(new_id, serial[1], ATA_ID_SERNO, sizeof(serial[1]));
|
||||
new_n_sectors = ata_id_n_sectors(new_id);
|
||||
|
||||
if (strcmp(model[0], model[1])) {
|
||||
ata_dev_printk(dev, KERN_INFO, "model number mismatch "
|
||||
@ -3658,25 +3655,12 @@ static int ata_dev_same_device(struct ata_device *dev, unsigned int new_class,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (dev->class == ATA_DEV_ATA && dev->n_sectors != new_n_sectors) {
|
||||
ata_dev_printk(dev, KERN_INFO, "n_sectors mismatch "
|
||||
"%llu != %llu\n",
|
||||
(unsigned long long)dev->n_sectors,
|
||||
(unsigned long long)new_n_sectors);
|
||||
/* Are we the boot time size - if so we appear to be the
|
||||
same disk at this point and our HPA got reapplied */
|
||||
if (ata_ignore_hpa && dev->n_sectors_boot == new_n_sectors
|
||||
&& ata_id_hpa_enabled(new_id))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_dev_revalidate - Revalidate ATA device
|
||||
* @dev: device to revalidate
|
||||
* ata_dev_reread_id - Re-read IDENTIFY data
|
||||
* @adev: target ATA device
|
||||
* @readid_flags: read ID flags
|
||||
*
|
||||
* Re-read IDENTIFY page and make sure @dev is still attached to
|
||||
@ -3688,33 +3672,67 @@ static int ata_dev_same_device(struct ata_device *dev, unsigned int new_class,
|
||||
* RETURNS:
|
||||
* 0 on success, negative errno otherwise
|
||||
*/
|
||||
int ata_dev_revalidate(struct ata_device *dev, unsigned int readid_flags)
|
||||
int ata_dev_reread_id(struct ata_device *dev, unsigned int readid_flags)
|
||||
{
|
||||
unsigned int class = dev->class;
|
||||
u16 *id = (void *)dev->ap->sector_buf;
|
||||
int rc;
|
||||
|
||||
if (!ata_dev_enabled(dev)) {
|
||||
rc = -ENODEV;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* read ID data */
|
||||
rc = ata_dev_read_id(dev, &class, readid_flags, id);
|
||||
if (rc)
|
||||
goto fail;
|
||||
return rc;
|
||||
|
||||
/* is the device still there? */
|
||||
if (!ata_dev_same_device(dev, class, id)) {
|
||||
if (!ata_dev_same_device(dev, class, id))
|
||||
return -ENODEV;
|
||||
|
||||
memcpy(dev->id, id, sizeof(id[0]) * ATA_ID_WORDS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_dev_revalidate - Revalidate ATA device
|
||||
* @dev: device to revalidate
|
||||
* @readid_flags: read ID flags
|
||||
*
|
||||
* Re-read IDENTIFY page, make sure @dev is still attached to the
|
||||
* port and reconfigure it according to the new IDENTIFY page.
|
||||
*
|
||||
* LOCKING:
|
||||
* Kernel thread context (may sleep)
|
||||
*
|
||||
* RETURNS:
|
||||
* 0 on success, negative errno otherwise
|
||||
*/
|
||||
int ata_dev_revalidate(struct ata_device *dev, unsigned int readid_flags)
|
||||
{
|
||||
u64 n_sectors = dev->n_sectors;
|
||||
int rc;
|
||||
|
||||
if (!ata_dev_enabled(dev))
|
||||
return -ENODEV;
|
||||
|
||||
/* re-read ID */
|
||||
rc = ata_dev_reread_id(dev, readid_flags);
|
||||
if (rc)
|
||||
goto fail;
|
||||
|
||||
/* configure device according to the new ID */
|
||||
rc = ata_dev_configure(dev);
|
||||
if (rc)
|
||||
goto fail;
|
||||
|
||||
/* verify n_sectors hasn't changed */
|
||||
if (dev->class == ATA_DEV_ATA && dev->n_sectors != n_sectors) {
|
||||
ata_dev_printk(dev, KERN_INFO, "n_sectors mismatch "
|
||||
"%llu != %llu\n",
|
||||
(unsigned long long)n_sectors,
|
||||
(unsigned long long)dev->n_sectors);
|
||||
rc = -ENODEV;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
memcpy(dev->id, id, sizeof(id[0]) * ATA_ID_WORDS);
|
||||
|
||||
/* configure device according to the new ID */
|
||||
rc = ata_dev_configure(dev);
|
||||
if (rc == 0)
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
|
@ -893,6 +893,23 @@ int ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth)
|
||||
return queue_depth;
|
||||
}
|
||||
|
||||
/* XXX: for ata_spindown_compat */
|
||||
static void ata_delayed_done_timerfn(unsigned long arg)
|
||||
{
|
||||
struct scsi_cmnd *scmd = (void *)arg;
|
||||
|
||||
scmd->scsi_done(scmd);
|
||||
}
|
||||
|
||||
/* XXX: for ata_spindown_compat */
|
||||
static void ata_delayed_done(struct scsi_cmnd *scmd)
|
||||
{
|
||||
static struct timer_list timer;
|
||||
|
||||
setup_timer(&timer, ata_delayed_done_timerfn, (unsigned long)scmd);
|
||||
mod_timer(&timer, jiffies + 5 * HZ);
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_scsi_start_stop_xlat - Translate SCSI START STOP UNIT command
|
||||
* @qc: Storage for translated ATA taskfile
|
||||
@ -950,21 +967,24 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc)
|
||||
* for more info.
|
||||
*/
|
||||
if (ata_spindown_compat &&
|
||||
(qc->dev->flags & ATA_DFLAG_SPUNDOWN) &&
|
||||
(system_state == SYSTEM_HALT ||
|
||||
system_state == SYSTEM_POWER_OFF)) {
|
||||
static int warned = 0;
|
||||
static unsigned long warned = 0;
|
||||
|
||||
if (!warned) {
|
||||
spin_unlock_irq(qc->ap->lock);
|
||||
if (!test_and_set_bit(0, &warned)) {
|
||||
ata_dev_printk(qc->dev, KERN_WARNING,
|
||||
"DISK MIGHT NOT BE SPUN DOWN PROPERLY. "
|
||||
"UPDATE SHUTDOWN UTILITY\n");
|
||||
ata_dev_printk(qc->dev, KERN_WARNING,
|
||||
"For more info, visit "
|
||||
"http://linux-ata.org/shutdown.html\n");
|
||||
warned = 1;
|
||||
ssleep(5);
|
||||
spin_lock_irq(qc->ap->lock);
|
||||
|
||||
/* ->scsi_done is not used, use it for
|
||||
* delayed completion.
|
||||
*/
|
||||
scmd->scsi_done = qc->scsidone;
|
||||
qc->scsidone = ata_delayed_done;
|
||||
}
|
||||
scmd->result = SAM_STAT_GOOD;
|
||||
return 1;
|
||||
@ -1375,6 +1395,14 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc)
|
||||
}
|
||||
}
|
||||
|
||||
/* XXX: track spindown state for spindown_compat */
|
||||
if (unlikely(qc->tf.command == ATA_CMD_STANDBY ||
|
||||
qc->tf.command == ATA_CMD_STANDBYNOW1))
|
||||
qc->dev->flags |= ATA_DFLAG_SPUNDOWN;
|
||||
else if (likely(system_state != SYSTEM_HALT &&
|
||||
system_state != SYSTEM_POWER_OFF))
|
||||
qc->dev->flags &= ~ATA_DFLAG_SPUNDOWN;
|
||||
|
||||
if (need_sense && !ap->ops->error_handler)
|
||||
ata_dump_status(ap->print_id, &qc->result_tf);
|
||||
|
||||
@ -1488,14 +1516,14 @@ static int ata_scsi_translate(struct ata_device *dev, struct scsi_cmnd *cmd,
|
||||
|
||||
early_finish:
|
||||
ata_qc_free(qc);
|
||||
done(cmd);
|
||||
qc->scsidone(cmd);
|
||||
DPRINTK("EXIT - early finish (good or error)\n");
|
||||
return 0;
|
||||
|
||||
err_did:
|
||||
ata_qc_free(qc);
|
||||
cmd->result = (DID_ERROR << 16);
|
||||
done(cmd);
|
||||
qc->scsidone(cmd);
|
||||
err_mem:
|
||||
DPRINTK("EXIT - internal\n");
|
||||
return 0;
|
||||
|
@ -76,7 +76,8 @@ extern unsigned ata_exec_internal_sg(struct ata_device *dev,
|
||||
extern unsigned int ata_do_simple_cmd(struct ata_device *dev, u8 cmd);
|
||||
extern int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
|
||||
unsigned int flags, u16 *id);
|
||||
extern int ata_dev_revalidate(struct ata_device *dev, unsigned int flags);
|
||||
extern int ata_dev_reread_id(struct ata_device *dev, unsigned int readid_flags);
|
||||
extern int ata_dev_revalidate(struct ata_device *dev, unsigned int readid_flags);
|
||||
extern int ata_dev_configure(struct ata_device *dev);
|
||||
extern int sata_down_spd_limit(struct ata_port *ap);
|
||||
extern int sata_set_spd_needed(struct ata_port *ap);
|
||||
|
@ -864,10 +864,10 @@ static void scc_bmdma_freeze (struct ata_port *ap)
|
||||
* @ap: ATA port to be reset
|
||||
*/
|
||||
|
||||
static int scc_pata_prereset (struct ata_port *ap)
|
||||
static int scc_pata_prereset (struct ata_port *ap, unsigned long deadline)
|
||||
{
|
||||
ap->cbl = ATA_CBL_PATA80;
|
||||
return ata_std_prereset(ap);
|
||||
return ata_std_prereset(ap, deadline);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -237,7 +237,8 @@ enum {
|
||||
/* host flags */
|
||||
SIL24_COMMON_FLAGS = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
|
||||
ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
|
||||
ATA_FLAG_NCQ | ATA_FLAG_SKIP_D2H_BSY,
|
||||
ATA_FLAG_NCQ | ATA_FLAG_SKIP_D2H_BSY |
|
||||
ATA_FLAG_ACPI_SATA,
|
||||
SIL24_FLAG_PCIX_IRQ_WOC = (1 << 24), /* IRQ loss errata on PCI-X */
|
||||
|
||||
IRQ_STAT_4PORTS = 0xf,
|
||||
|
@ -51,6 +51,7 @@
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/pnp.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* sunhv.c: Serial driver for SUN4V hypervisor console.
|
||||
*
|
||||
* Copyright (C) 2006 David S. Miller (davem@davemloft.net)
|
||||
* Copyright (C) 2006, 2007 David S. Miller (davem@davemloft.net)
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
@ -35,57 +35,51 @@
|
||||
#define CON_BREAK ((long)-1)
|
||||
#define CON_HUP ((long)-2)
|
||||
|
||||
static inline long hypervisor_con_getchar(long *status)
|
||||
{
|
||||
register unsigned long func asm("%o5");
|
||||
register unsigned long arg0 asm("%o0");
|
||||
register unsigned long arg1 asm("%o1");
|
||||
|
||||
func = HV_FAST_CONS_GETCHAR;
|
||||
arg0 = 0;
|
||||
arg1 = 0;
|
||||
__asm__ __volatile__("ta %6"
|
||||
: "=&r" (func), "=&r" (arg0), "=&r" (arg1)
|
||||
: "0" (func), "1" (arg0), "2" (arg1),
|
||||
"i" (HV_FAST_TRAP));
|
||||
|
||||
*status = arg0;
|
||||
|
||||
return (long) arg1;
|
||||
}
|
||||
|
||||
static inline long hypervisor_con_putchar(long ch)
|
||||
{
|
||||
register unsigned long func asm("%o5");
|
||||
register unsigned long arg0 asm("%o0");
|
||||
|
||||
func = HV_FAST_CONS_PUTCHAR;
|
||||
arg0 = ch;
|
||||
__asm__ __volatile__("ta %4"
|
||||
: "=&r" (func), "=&r" (arg0)
|
||||
: "0" (func), "1" (arg0), "i" (HV_FAST_TRAP));
|
||||
|
||||
return (long) arg0;
|
||||
}
|
||||
|
||||
#define IGNORE_BREAK 0x1
|
||||
#define IGNORE_ALL 0x2
|
||||
|
||||
static char *con_write_page;
|
||||
static char *con_read_page;
|
||||
|
||||
static int hung_up = 0;
|
||||
|
||||
static struct tty_struct *receive_chars(struct uart_port *port)
|
||||
static void transmit_chars_putchar(struct uart_port *port, struct circ_buf *xmit)
|
||||
{
|
||||
while (!uart_circ_empty(xmit)) {
|
||||
long status = sun4v_con_putchar(xmit->buf[xmit->tail]);
|
||||
|
||||
if (status != HV_EOK)
|
||||
break;
|
||||
|
||||
xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
|
||||
port->icount.tx++;
|
||||
}
|
||||
}
|
||||
|
||||
static void transmit_chars_write(struct uart_port *port, struct circ_buf *xmit)
|
||||
{
|
||||
while (!uart_circ_empty(xmit)) {
|
||||
unsigned long ra = __pa(xmit->buf + xmit->tail);
|
||||
unsigned long len, status, sent;
|
||||
|
||||
len = CIRC_CNT_TO_END(xmit->head, xmit->tail,
|
||||
UART_XMIT_SIZE);
|
||||
status = sun4v_con_write(ra, len, &sent);
|
||||
if (status != HV_EOK)
|
||||
break;
|
||||
xmit->tail = (xmit->tail + sent) & (UART_XMIT_SIZE - 1);
|
||||
port->icount.tx += sent;
|
||||
}
|
||||
}
|
||||
|
||||
static int receive_chars_getchar(struct uart_port *port, struct tty_struct *tty)
|
||||
{
|
||||
struct tty_struct *tty = NULL;
|
||||
int saw_console_brk = 0;
|
||||
int limit = 10000;
|
||||
|
||||
if (port->info != NULL) /* Unopened serial console */
|
||||
tty = port->info->tty;
|
||||
|
||||
while (limit-- > 0) {
|
||||
long status;
|
||||
long c = hypervisor_con_getchar(&status);
|
||||
unsigned char flag;
|
||||
long c = sun4v_con_getchar(&status);
|
||||
|
||||
if (status == HV_EWOULDBLOCK)
|
||||
break;
|
||||
@ -110,27 +104,90 @@ static struct tty_struct *receive_chars(struct uart_port *port)
|
||||
continue;
|
||||
}
|
||||
|
||||
flag = TTY_NORMAL;
|
||||
port->icount.rx++;
|
||||
if (c == CON_BREAK) {
|
||||
port->icount.brk++;
|
||||
if (uart_handle_break(port))
|
||||
continue;
|
||||
flag = TTY_BREAK;
|
||||
}
|
||||
|
||||
if (uart_handle_sysrq_char(port, c))
|
||||
continue;
|
||||
|
||||
if ((port->ignore_status_mask & IGNORE_ALL) ||
|
||||
((port->ignore_status_mask & IGNORE_BREAK) &&
|
||||
(c == CON_BREAK)))
|
||||
continue;
|
||||
|
||||
tty_insert_flip_char(tty, c, flag);
|
||||
tty_insert_flip_char(tty, c, TTY_NORMAL);
|
||||
}
|
||||
|
||||
if (saw_console_brk)
|
||||
return saw_console_brk;
|
||||
}
|
||||
|
||||
static int receive_chars_read(struct uart_port *port, struct tty_struct *tty)
|
||||
{
|
||||
int saw_console_brk = 0;
|
||||
int limit = 10000;
|
||||
|
||||
while (limit-- > 0) {
|
||||
unsigned long ra = __pa(con_read_page);
|
||||
unsigned long bytes_read, i;
|
||||
long stat = sun4v_con_read(ra, PAGE_SIZE, &bytes_read);
|
||||
|
||||
if (stat != HV_EOK) {
|
||||
bytes_read = 0;
|
||||
|
||||
if (stat == CON_BREAK) {
|
||||
if (uart_handle_break(port))
|
||||
continue;
|
||||
saw_console_brk = 1;
|
||||
*con_read_page = 0;
|
||||
bytes_read = 1;
|
||||
} else if (stat == CON_HUP) {
|
||||
hung_up = 1;
|
||||
uart_handle_dcd_change(port, 0);
|
||||
continue;
|
||||
} else {
|
||||
/* HV_EWOULDBLOCK, etc. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (hung_up) {
|
||||
hung_up = 0;
|
||||
uart_handle_dcd_change(port, 1);
|
||||
}
|
||||
|
||||
for (i = 0; i < bytes_read; i++)
|
||||
uart_handle_sysrq_char(port, con_read_page[i]);
|
||||
|
||||
if (tty == NULL)
|
||||
continue;
|
||||
|
||||
port->icount.rx += bytes_read;
|
||||
|
||||
tty_insert_flip_string(tty, con_read_page, bytes_read);
|
||||
}
|
||||
|
||||
return saw_console_brk;
|
||||
}
|
||||
|
||||
struct sunhv_ops {
|
||||
void (*transmit_chars)(struct uart_port *port, struct circ_buf *xmit);
|
||||
int (*receive_chars)(struct uart_port *port, struct tty_struct *tty);
|
||||
};
|
||||
|
||||
static struct sunhv_ops bychar_ops = {
|
||||
.transmit_chars = transmit_chars_putchar,
|
||||
.receive_chars = receive_chars_getchar,
|
||||
};
|
||||
|
||||
static struct sunhv_ops bywrite_ops = {
|
||||
.transmit_chars = transmit_chars_write,
|
||||
.receive_chars = receive_chars_read,
|
||||
};
|
||||
|
||||
static struct sunhv_ops *sunhv_ops = &bychar_ops;
|
||||
|
||||
static struct tty_struct *receive_chars(struct uart_port *port)
|
||||
{
|
||||
struct tty_struct *tty = NULL;
|
||||
|
||||
if (port->info != NULL) /* Unopened serial console */
|
||||
tty = port->info->tty;
|
||||
|
||||
if (sunhv_ops->receive_chars(port, tty))
|
||||
sun_do_break();
|
||||
|
||||
return tty;
|
||||
@ -147,15 +204,7 @@ static void transmit_chars(struct uart_port *port)
|
||||
if (uart_circ_empty(xmit) || uart_tx_stopped(port))
|
||||
return;
|
||||
|
||||
while (!uart_circ_empty(xmit)) {
|
||||
long status = hypervisor_con_putchar(xmit->buf[xmit->tail]);
|
||||
|
||||
if (status != HV_EOK)
|
||||
break;
|
||||
|
||||
xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
|
||||
port->icount.tx++;
|
||||
}
|
||||
sunhv_ops->transmit_chars(port, xmit);
|
||||
|
||||
if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
|
||||
uart_write_wakeup(port);
|
||||
@ -212,7 +261,7 @@ static void sunhv_start_tx(struct uart_port *port)
|
||||
struct circ_buf *xmit = &port->info->xmit;
|
||||
|
||||
while (!uart_circ_empty(xmit)) {
|
||||
long status = hypervisor_con_putchar(xmit->buf[xmit->tail]);
|
||||
long status = sun4v_con_putchar(xmit->buf[xmit->tail]);
|
||||
|
||||
if (status != HV_EOK)
|
||||
break;
|
||||
@ -231,9 +280,10 @@ static void sunhv_send_xchar(struct uart_port *port, char ch)
|
||||
spin_lock_irqsave(&port->lock, flags);
|
||||
|
||||
while (limit-- > 0) {
|
||||
long status = hypervisor_con_putchar(ch);
|
||||
long status = sun4v_con_putchar(ch);
|
||||
if (status == HV_EOK)
|
||||
break;
|
||||
udelay(1);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&port->lock, flags);
|
||||
@ -254,15 +304,15 @@ static void sunhv_break_ctl(struct uart_port *port, int break_state)
|
||||
{
|
||||
if (break_state) {
|
||||
unsigned long flags;
|
||||
int limit = 1000000;
|
||||
int limit = 10000;
|
||||
|
||||
spin_lock_irqsave(&port->lock, flags);
|
||||
|
||||
while (limit-- > 0) {
|
||||
long status = hypervisor_con_putchar(CON_BREAK);
|
||||
long status = sun4v_con_putchar(CON_BREAK);
|
||||
if (status == HV_EOK)
|
||||
break;
|
||||
udelay(2);
|
||||
udelay(1);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&port->lock, flags);
|
||||
@ -359,38 +409,99 @@ static struct uart_driver sunhv_reg = {
|
||||
|
||||
static struct uart_port *sunhv_port;
|
||||
|
||||
static inline void sunhv_console_putchar(struct uart_port *port, char c)
|
||||
/* Copy 's' into the con_write_page, decoding "\n" into
|
||||
* "\r\n" along the way. We have to return two lengths
|
||||
* because the caller needs to know how much to advance
|
||||
* 's' and also how many bytes to output via con_write_page.
|
||||
*/
|
||||
static int fill_con_write_page(const char *s, unsigned int n,
|
||||
unsigned long *page_bytes)
|
||||
{
|
||||
unsigned long flags;
|
||||
int limit = 1000000;
|
||||
const char *orig_s = s;
|
||||
char *p = con_write_page;
|
||||
int left = PAGE_SIZE;
|
||||
|
||||
spin_lock_irqsave(&port->lock, flags);
|
||||
|
||||
while (limit-- > 0) {
|
||||
long status = hypervisor_con_putchar(c);
|
||||
if (status == HV_EOK)
|
||||
while (n--) {
|
||||
if (*s == '\n') {
|
||||
if (left < 2)
|
||||
break;
|
||||
udelay(2);
|
||||
*p++ = '\r';
|
||||
left--;
|
||||
} else if (left < 1)
|
||||
break;
|
||||
*p++ = *s++;
|
||||
left--;
|
||||
}
|
||||
*page_bytes = p - con_write_page;
|
||||
return s - orig_s;
|
||||
}
|
||||
|
||||
static void sunhv_console_write_paged(struct console *con, const char *s, unsigned n)
|
||||
{
|
||||
struct uart_port *port = sunhv_port;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&port->lock, flags);
|
||||
while (n > 0) {
|
||||
unsigned long ra = __pa(con_write_page);
|
||||
unsigned long page_bytes;
|
||||
unsigned int cpy = fill_con_write_page(s, n,
|
||||
&page_bytes);
|
||||
|
||||
n -= cpy;
|
||||
s += cpy;
|
||||
while (page_bytes > 0) {
|
||||
unsigned long written;
|
||||
int limit = 1000000;
|
||||
|
||||
while (limit--) {
|
||||
unsigned long stat;
|
||||
|
||||
stat = sun4v_con_write(ra, page_bytes,
|
||||
&written);
|
||||
if (stat == HV_EOK)
|
||||
break;
|
||||
udelay(1);
|
||||
}
|
||||
if (limit <= 0)
|
||||
break;
|
||||
page_bytes -= written;
|
||||
ra += written;
|
||||
}
|
||||
}
|
||||
spin_unlock_irqrestore(&port->lock, flags);
|
||||
}
|
||||
|
||||
static void sunhv_console_write(struct console *con, const char *s, unsigned n)
|
||||
static inline void sunhv_console_putchar(struct uart_port *port, char c)
|
||||
{
|
||||
int limit = 1000000;
|
||||
|
||||
while (limit-- > 0) {
|
||||
long status = sun4v_con_putchar(c);
|
||||
if (status == HV_EOK)
|
||||
break;
|
||||
udelay(1);
|
||||
}
|
||||
}
|
||||
|
||||
static void sunhv_console_write_bychar(struct console *con, const char *s, unsigned n)
|
||||
{
|
||||
struct uart_port *port = sunhv_port;
|
||||
unsigned long flags;
|
||||
int i;
|
||||
|
||||
spin_lock_irqsave(&port->lock, flags);
|
||||
for (i = 0; i < n; i++) {
|
||||
if (*s == '\n')
|
||||
sunhv_console_putchar(port, '\r');
|
||||
sunhv_console_putchar(port, *s++);
|
||||
}
|
||||
spin_unlock_irqrestore(&port->lock, flags);
|
||||
}
|
||||
|
||||
static struct console sunhv_console = {
|
||||
.name = "ttyHV",
|
||||
.write = sunhv_console_write,
|
||||
.write = sunhv_console_write_bychar,
|
||||
.device = uart_console_device,
|
||||
.flags = CON_PRINTBUFFER,
|
||||
.index = -1,
|
||||
@ -410,6 +521,7 @@ static inline struct console *SUNHV_CONSOLE(void)
|
||||
static int __devinit hv_probe(struct of_device *op, const struct of_device_id *match)
|
||||
{
|
||||
struct uart_port *port;
|
||||
unsigned long minor;
|
||||
int err;
|
||||
|
||||
if (op->irqs[0] == 0xffffffff)
|
||||
@ -419,6 +531,22 @@ static int __devinit hv_probe(struct of_device *op, const struct of_device_id *m
|
||||
if (unlikely(!port))
|
||||
return -ENOMEM;
|
||||
|
||||
minor = 1;
|
||||
if (sun4v_hvapi_register(HV_GRP_CORE, 1, &minor) == 0 &&
|
||||
minor >= 1) {
|
||||
err = -ENOMEM;
|
||||
con_write_page = kzalloc(PAGE_SIZE, GFP_KERNEL);
|
||||
if (!con_write_page)
|
||||
goto out_free_port;
|
||||
|
||||
con_read_page = kzalloc(PAGE_SIZE, GFP_KERNEL);
|
||||
if (!con_read_page)
|
||||
goto out_free_con_write_page;
|
||||
|
||||
sunhv_console.write = sunhv_console_write_paged;
|
||||
sunhv_ops = &bywrite_ops;
|
||||
}
|
||||
|
||||
sunhv_port = port;
|
||||
|
||||
port->line = 0;
|
||||
@ -437,7 +565,7 @@ static int __devinit hv_probe(struct of_device *op, const struct of_device_id *m
|
||||
|
||||
err = uart_register_driver(&sunhv_reg);
|
||||
if (err)
|
||||
goto out_free_port;
|
||||
goto out_free_con_read_page;
|
||||
|
||||
sunhv_reg.tty_driver->name_base = sunhv_reg.minor - 64;
|
||||
sunserial_current_minor += 1;
|
||||
@ -463,6 +591,12 @@ out_unregister_driver:
|
||||
sunserial_current_minor -= 1;
|
||||
uart_unregister_driver(&sunhv_reg);
|
||||
|
||||
out_free_con_read_page:
|
||||
kfree(con_read_page);
|
||||
|
||||
out_free_con_write_page:
|
||||
kfree(con_write_page);
|
||||
|
||||
out_free_port:
|
||||
kfree(port);
|
||||
sunhv_port = NULL;
|
||||
|
@ -484,7 +484,7 @@ static int spidev_probe(struct spi_device *spi)
|
||||
* Reusing minors is fine so long as udev or mdev is working.
|
||||
*/
|
||||
mutex_lock(&device_list_lock);
|
||||
minor = find_first_zero_bit(minors, ARRAY_SIZE(minors));
|
||||
minor = find_first_zero_bit(minors, N_SPI_MINORS);
|
||||
if (minor < N_SPI_MINORS) {
|
||||
spidev->dev.parent = &spi->dev;
|
||||
spidev->dev.class = &spidev_class;
|
||||
|
@ -47,7 +47,6 @@ struct file_system_type afs_fs_type = {
|
||||
static const struct super_operations afs_super_ops = {
|
||||
.statfs = afs_statfs,
|
||||
.alloc_inode = afs_alloc_inode,
|
||||
.drop_inode = generic_delete_inode,
|
||||
.write_inode = afs_write_inode,
|
||||
.destroy_inode = afs_destroy_inode,
|
||||
.clear_inode = afs_clear_inode,
|
||||
|
@ -206,7 +206,6 @@ int afs_prepare_write(struct file *file, struct page *page,
|
||||
_leave(" = %d [prep]", ret);
|
||||
return ret;
|
||||
}
|
||||
SetPageUptodate(page);
|
||||
}
|
||||
|
||||
try_again:
|
||||
@ -311,8 +310,8 @@ int afs_commit_write(struct file *file, struct page *page,
|
||||
spin_unlock(&vnode->writeback_lock);
|
||||
}
|
||||
|
||||
SetPageUptodate(page);
|
||||
set_page_dirty(page);
|
||||
|
||||
if (PageDirty(page))
|
||||
_debug("dirtied");
|
||||
|
||||
|
@ -30,11 +30,9 @@ struct spi_board_info;
|
||||
struct platform_device *
|
||||
at32_add_device_spi(unsigned int id, struct spi_board_info *b, unsigned int n);
|
||||
|
||||
struct lcdc_platform_data {
|
||||
unsigned long fbmem_start;
|
||||
unsigned long fbmem_size;
|
||||
};
|
||||
struct atmel_lcdfb_info;
|
||||
struct platform_device *
|
||||
at32_add_device_lcdc(unsigned int id, struct lcdc_platform_data *data);
|
||||
at32_add_device_lcdc(unsigned int id, struct atmel_lcdfb_info *data,
|
||||
unsigned long fbmem_start, unsigned long fbmem_len);
|
||||
|
||||
#endif /* __ASM_ARCH_BOARD_H */
|
||||
|
@ -5,13 +5,22 @@
|
||||
|
||||
/* Grossly misnamed. */
|
||||
enum die_val {
|
||||
DIE_FAULT,
|
||||
DIE_BREAKPOINT,
|
||||
DIE_SSTEP,
|
||||
DIE_PAGE_FAULT,
|
||||
};
|
||||
|
||||
int register_page_fault_notifier(struct notifier_block *nb);
|
||||
int unregister_page_fault_notifier(struct notifier_block *nb);
|
||||
/*
|
||||
* These are only here because kprobes.c wants them to implement a
|
||||
* blatant layering violation. Will hopefully go away soon once all
|
||||
* architectures are updated.
|
||||
*/
|
||||
static inline int register_page_fault_notifier(struct notifier_block *nb)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline int unregister_page_fault_notifier(struct notifier_block *nb)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* __ASM_AVR32_KDEBUG_H */
|
||||
|
@ -26,6 +26,7 @@ struct arch_specific_insn {
|
||||
kprobe_opcode_t insn[MAX_INSN_SIZE];
|
||||
};
|
||||
|
||||
extern int kprobe_fault_handler(struct pt_regs *regs, int trapnr);
|
||||
extern int kprobe_exceptions_notify(struct notifier_block *self,
|
||||
unsigned long val, void *data);
|
||||
|
||||
|
@ -296,9 +296,12 @@
|
||||
#define __NR_shmctl 277
|
||||
|
||||
#define __NR_utimensat 278
|
||||
#define __NR_signalfd 279
|
||||
#define __NR_timerfd 280
|
||||
#define __NR_eventfd 281
|
||||
|
||||
#ifdef __KERNEL__
|
||||
#define NR_syscalls 279
|
||||
#define NR_syscalls 282
|
||||
|
||||
|
||||
#define __ARCH_WANT_IPC_PARSE_VERSION
|
||||
|
@ -28,14 +28,24 @@
|
||||
*/
|
||||
#include <linux/notifier.h>
|
||||
|
||||
extern int register_page_fault_notifier(struct notifier_block *);
|
||||
extern int unregister_page_fault_notifier(struct notifier_block *);
|
||||
/*
|
||||
* These are only here because kprobes.c wants them to implement a
|
||||
* blatant layering violation. Will hopefully go away soon once all
|
||||
* architectures are updated.
|
||||
*/
|
||||
static inline int register_page_fault_notifier(struct notifier_block *nb)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline int unregister_page_fault_notifier(struct notifier_block *nb)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
enum die_val {
|
||||
DIE_BREAK = 1,
|
||||
DIE_FAULT,
|
||||
DIE_OOPS,
|
||||
DIE_PAGE_FAULT,
|
||||
DIE_MACHINE_HALT,
|
||||
DIE_MACHINE_RESTART,
|
||||
DIE_MCA_MONARCH_ENTER,
|
||||
|
@ -120,6 +120,7 @@ struct arch_specific_insn {
|
||||
unsigned short slot;
|
||||
};
|
||||
|
||||
extern int kprobes_fault_handler(struct pt_regs *regs, int trapnr);
|
||||
extern int kprobe_exceptions_notify(struct notifier_block *self,
|
||||
unsigned long val, void *data);
|
||||
|
||||
|
@ -296,11 +296,14 @@
|
||||
#define __NR_getcpu 1304
|
||||
#define __NR_epoll_pwait 1305
|
||||
#define __NR_utimensat 1306
|
||||
#define __NR_signalfd 1307
|
||||
#define __NR_timerfd 1308
|
||||
#define __NR_eventfd 1309
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
|
||||
#define NR_syscalls 283 /* length of syscall table */
|
||||
#define NR_syscalls 286 /* length of syscall table */
|
||||
|
||||
#define __ARCH_WANT_SYS_RT_SIGACTION
|
||||
#define __ARCH_WANT_SYS_RT_SIGSUSPEND
|
||||
|
@ -940,6 +940,54 @@ struct hv_fault_status {
|
||||
*/
|
||||
#define HV_FAST_CONS_PUTCHAR 0x61
|
||||
|
||||
/* con_read()
|
||||
* TRAP: HV_FAST_TRAP
|
||||
* FUNCTION: HV_FAST_CONS_READ
|
||||
* ARG0: buffer real address
|
||||
* ARG1: buffer size in bytes
|
||||
* RET0: status
|
||||
* RET1: bytes read or BREAK or HUP
|
||||
* ERRORS: EWOULDBLOCK No character available.
|
||||
*
|
||||
* Reads characters into a buffer from the console device. If no
|
||||
* character is available then an EWOULDBLOCK error is returned.
|
||||
* If a character is available, then the returned status is EOK
|
||||
* and the number of bytes read into the given buffer is provided
|
||||
* in RET1.
|
||||
*
|
||||
* A virtual BREAK is represented by the 64-bit RET1 value -1.
|
||||
*
|
||||
* A virtual HUP signal is represented by the 64-bit RET1 value -2.
|
||||
*
|
||||
* If BREAK or HUP are indicated, no bytes were read into buffer.
|
||||
*/
|
||||
#define HV_FAST_CONS_READ 0x62
|
||||
|
||||
/* con_write()
|
||||
* TRAP: HV_FAST_TRAP
|
||||
* FUNCTION: HV_FAST_CONS_WRITE
|
||||
* ARG0: buffer real address
|
||||
* ARG1: buffer size in bytes
|
||||
* RET0: status
|
||||
* RET1: bytes written
|
||||
* ERRORS: EWOULDBLOCK Output buffer currently full, would block
|
||||
*
|
||||
* Send a characters in buffer to the console device. Breaks must be
|
||||
* sent using con_putchar().
|
||||
*/
|
||||
#define HV_FAST_CONS_WRITE 0x63
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
extern long sun4v_con_getchar(long *status);
|
||||
extern long sun4v_con_putchar(long c);
|
||||
extern long sun4v_con_read(unsigned long buffer,
|
||||
unsigned long size,
|
||||
unsigned long *bytes_read);
|
||||
extern unsigned long sun4v_con_write(unsigned long buffer,
|
||||
unsigned long size,
|
||||
unsigned long *bytes_written);
|
||||
#endif
|
||||
|
||||
/* Trap trace services.
|
||||
*
|
||||
* The hypervisor provides a trap tracing capability for privileged
|
||||
@ -2121,8 +2169,41 @@ struct hv_mmu_statistics {
|
||||
#define HV_FAST_MMUSTAT_INFO 0x103
|
||||
|
||||
/* Function numbers for HV_CORE_TRAP. */
|
||||
#define HV_CORE_VER 0x00
|
||||
#define HV_CORE_SET_VER 0x00
|
||||
#define HV_CORE_PUTCHAR 0x01
|
||||
#define HV_CORE_EXIT 0x02
|
||||
#define HV_CORE_GET_VER 0x03
|
||||
|
||||
/* Hypervisor API groups for use with HV_CORE_SET_VER and
|
||||
* HV_CORE_GET_VER.
|
||||
*/
|
||||
#define HV_GRP_SUN4V 0x0000
|
||||
#define HV_GRP_CORE 0x0001
|
||||
#define HV_GRP_INTR 0x0002
|
||||
#define HV_GRP_SOFT_STATE 0x0003
|
||||
#define HV_GRP_PCI 0x0100
|
||||
#define HV_GRP_LDOM 0x0101
|
||||
#define HV_GRP_SVC_CHAN 0x0102
|
||||
#define HV_GRP_NCS 0x0103
|
||||
#define HV_GRP_NIAG_PERF 0x0200
|
||||
#define HV_GRP_FIRE_PERF 0x0201
|
||||
#define HV_GRP_DIAG 0x0300
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
extern unsigned long sun4v_get_version(unsigned long group,
|
||||
unsigned long *major,
|
||||
unsigned long *minor);
|
||||
extern unsigned long sun4v_set_version(unsigned long group,
|
||||
unsigned long major,
|
||||
unsigned long minor,
|
||||
unsigned long *actual_minor);
|
||||
|
||||
extern int sun4v_hvapi_register(unsigned long group, unsigned long major,
|
||||
unsigned long *minor);
|
||||
extern void sun4v_hvapi_unregister(unsigned long group);
|
||||
extern int sun4v_hvapi_get(unsigned long group,
|
||||
unsigned long *major,
|
||||
unsigned long *minor);
|
||||
#endif
|
||||
|
||||
#endif /* !(_SPARC64_HYPERVISOR_H) */
|
||||
|
@ -140,6 +140,7 @@ enum {
|
||||
|
||||
ATA_DFLAG_PIO = (1 << 8), /* device limited to PIO mode */
|
||||
ATA_DFLAG_NCQ_OFF = (1 << 9), /* device limited to non-NCQ mode */
|
||||
ATA_DFLAG_SPUNDOWN = (1 << 10), /* XXX: for spindown_compat */
|
||||
ATA_DFLAG_INIT_MASK = (1 << 16) - 1,
|
||||
|
||||
ATA_DFLAG_DETACH = (1 << 16),
|
||||
@ -173,6 +174,7 @@ enum {
|
||||
ATA_FLAG_SETXFER_POLLING= (1 << 14), /* use polling for SETXFER */
|
||||
ATA_FLAG_IGN_SIMPLEX = (1 << 15), /* ignore SIMPLEX */
|
||||
ATA_FLAG_NO_IORDY = (1 << 16), /* controller lacks iordy */
|
||||
ATA_FLAG_ACPI_SATA = (1 << 17), /* need native SATA ACPI layout */
|
||||
|
||||
/* The following flag belongs to ap->pflags but is kept in
|
||||
* ap->flags because it's referenced in many LLDs and will be
|
||||
@ -431,7 +433,6 @@ struct ata_device {
|
||||
struct scsi_device *sdev; /* attached SCSI device */
|
||||
/* n_sector is used as CLEAR_OFFSET, read comment above CLEAR_OFFSET */
|
||||
u64 n_sectors; /* size of device, if ATA */
|
||||
u64 n_sectors_boot; /* size of ATA device at startup */
|
||||
unsigned int class; /* ATA_DEV_xxx */
|
||||
u16 id[ATA_ID_WORDS]; /* IDENTIFY xxx DEVICE data */
|
||||
u8 pio_mode;
|
||||
|
@ -88,7 +88,7 @@ static inline int kmalloc_index(int size)
|
||||
*/
|
||||
WARN_ON_ONCE(size == 0);
|
||||
|
||||
if (size >= (1 << KMALLOC_SHIFT_HIGH))
|
||||
if (size > (1 << KMALLOC_SHIFT_HIGH))
|
||||
return -1;
|
||||
|
||||
if (size > 64 && size <= 96)
|
||||
|
@ -22,7 +22,7 @@
|
||||
#include <sound/control.h>
|
||||
#include <sound/ac97_codec.h>
|
||||
|
||||
#define SND_SOC_VERSION "0.13.0"
|
||||
#define SND_SOC_VERSION "0.13.1"
|
||||
|
||||
/*
|
||||
* Convenience kcontrol builders
|
||||
@ -83,6 +83,7 @@
|
||||
#define SND_SOC_DAI_AC97 0x1
|
||||
#define SND_SOC_DAI_I2S 0x2
|
||||
#define SND_SOC_DAI_PCM 0x4
|
||||
#define SND_SOC_DAI_AC97_BUS 0x8 /* for custom i.e. non ac97_codec.c */
|
||||
|
||||
/*
|
||||
* DAI hardware audio formats
|
||||
@ -278,6 +279,7 @@ struct snd_soc_cpu_ops {
|
||||
struct snd_soc_codec_dai {
|
||||
char *name;
|
||||
int id;
|
||||
unsigned char type;
|
||||
|
||||
/* DAI capabilities */
|
||||
struct snd_soc_pcm_stream playback;
|
||||
|
@ -1,3 +1,3 @@
|
||||
/* include/version.h. Generated by alsa/ksync script. */
|
||||
#define CONFIG_SND_VERSION "1.0.14rc4"
|
||||
#define CONFIG_SND_DATE " (Wed May 09 09:51:39 2007 UTC)"
|
||||
#define CONFIG_SND_DATE " (Wed May 16 09:45:46 2007 UTC)"
|
||||
|
@ -97,25 +97,26 @@ static int suspend_prepare(suspend_state_t state)
|
||||
}
|
||||
}
|
||||
|
||||
if (pm_ops->prepare) {
|
||||
if ((error = pm_ops->prepare(state)))
|
||||
goto Thaw;
|
||||
}
|
||||
|
||||
suspend_console();
|
||||
error = device_suspend(PMSG_SUSPEND);
|
||||
if (error) {
|
||||
printk(KERN_ERR "Some devices failed to suspend\n");
|
||||
goto Resume_console;
|
||||
}
|
||||
if (pm_ops->prepare) {
|
||||
if ((error = pm_ops->prepare(state)))
|
||||
goto Resume_devices;
|
||||
}
|
||||
|
||||
error = disable_nonboot_cpus();
|
||||
if (!error)
|
||||
return 0;
|
||||
|
||||
enable_nonboot_cpus();
|
||||
Resume_devices:
|
||||
pm_finish(state);
|
||||
Resume_devices:
|
||||
device_resume();
|
||||
Resume_console:
|
||||
resume_console();
|
||||
Thaw:
|
||||
thaw_processes();
|
||||
|
@ -670,7 +670,8 @@ repeat:
|
||||
page = find_lock_page(mapping, index);
|
||||
if (!page) {
|
||||
if (!cached_page) {
|
||||
cached_page = alloc_page(gfp_mask);
|
||||
cached_page =
|
||||
__page_cache_alloc(gfp_mask);
|
||||
if (!cached_page)
|
||||
return NULL;
|
||||
}
|
||||
|
@ -2522,7 +2522,7 @@ struct kmem_cache *kmem_cache_create(const char *name, size_t size,
|
||||
struct kmem_cache *s;
|
||||
|
||||
down_write(&slub_lock);
|
||||
s = find_mergeable(size, align, flags, dtor, ctor);
|
||||
s = find_mergeable(size, align, flags, ctor, dtor);
|
||||
if (s) {
|
||||
s->refcount++;
|
||||
/*
|
||||
|
@ -109,6 +109,7 @@ module_param_array(wssdma, int, NULL, 0444);
|
||||
MODULE_PARM_DESC(wssdma, "DMA for CMI8330 WSS driver.");
|
||||
|
||||
#ifdef CONFIG_PNP
|
||||
static int isa_registered;
|
||||
static int pnp_registered;
|
||||
#endif
|
||||
|
||||
@ -686,14 +687,18 @@ static int __init alsa_card_cmi8330_init(void)
|
||||
int err;
|
||||
|
||||
err = isa_register_driver(&snd_cmi8330_driver, SNDRV_CARDS);
|
||||
if (err < 0)
|
||||
return err;
|
||||
#ifdef CONFIG_PNP
|
||||
if (!err)
|
||||
isa_registered = 1;
|
||||
|
||||
err = pnp_register_card_driver(&cmi8330_pnpc_driver);
|
||||
if (!err)
|
||||
pnp_registered = 1;
|
||||
|
||||
if (isa_registered)
|
||||
err = 0;
|
||||
#endif
|
||||
return 0;
|
||||
return err;
|
||||
}
|
||||
|
||||
static void __exit alsa_card_cmi8330_exit(void)
|
||||
@ -701,6 +706,8 @@ static void __exit alsa_card_cmi8330_exit(void)
|
||||
#ifdef CONFIG_PNP
|
||||
if (pnp_registered)
|
||||
pnp_unregister_card_driver(&cmi8330_pnpc_driver);
|
||||
|
||||
if (isa_registered)
|
||||
#endif
|
||||
isa_unregister_driver(&snd_cmi8330_driver);
|
||||
}
|
||||
|
@ -127,6 +127,7 @@ module_param_array(dma2, int, NULL, 0444);
|
||||
MODULE_PARM_DESC(dma2, "DMA2 # for " IDENT " driver.");
|
||||
|
||||
#ifdef CONFIG_PNP
|
||||
static int isa_registered;
|
||||
static int pnpc_registered;
|
||||
#ifdef CS4232
|
||||
static int pnp_registered;
|
||||
@ -770,9 +771,9 @@ static int __init alsa_card_cs423x_init(void)
|
||||
int err;
|
||||
|
||||
err = isa_register_driver(&cs423x_isa_driver, SNDRV_CARDS);
|
||||
if (err < 0)
|
||||
return err;
|
||||
#ifdef CONFIG_PNP
|
||||
if (!err)
|
||||
isa_registered = 1;
|
||||
#ifdef CS4232
|
||||
err = pnp_register_driver(&cs4232_pnp_driver);
|
||||
if (!err)
|
||||
@ -781,8 +782,14 @@ static int __init alsa_card_cs423x_init(void)
|
||||
err = pnp_register_card_driver(&cs423x_pnpc_driver);
|
||||
if (!err)
|
||||
pnpc_registered = 1;
|
||||
#endif /* CONFIG_PNP */
|
||||
return 0;
|
||||
#ifdef CS4232
|
||||
if (pnp_registered)
|
||||
err = 0;
|
||||
#endif
|
||||
if (isa_registered)
|
||||
err = 0;
|
||||
#endif
|
||||
return err;
|
||||
}
|
||||
|
||||
static void __exit alsa_card_cs423x_exit(void)
|
||||
@ -794,7 +801,8 @@ static void __exit alsa_card_cs423x_exit(void)
|
||||
if (pnp_registered)
|
||||
pnp_unregister_driver(&cs4232_pnp_driver);
|
||||
#endif
|
||||
#endif /* CONFIG_PNP */
|
||||
if (isa_registered)
|
||||
#endif
|
||||
isa_unregister_driver(&cs423x_isa_driver);
|
||||
}
|
||||
|
||||
|
@ -2036,7 +2036,9 @@ module_param_array(dma2, int, NULL, 0444);
|
||||
MODULE_PARM_DESC(dma2, "DMA 2 # for ES18xx driver.");
|
||||
|
||||
#ifdef CONFIG_PNP
|
||||
static int pnp_registered, pnpc_registered;
|
||||
static int isa_registered;
|
||||
static int pnp_registered;
|
||||
static int pnpc_registered;
|
||||
|
||||
static struct pnp_device_id snd_audiodrive_pnpbiosids[] = {
|
||||
{ .id = "ESS1869" },
|
||||
@ -2466,18 +2468,22 @@ static int __init alsa_card_es18xx_init(void)
|
||||
int err;
|
||||
|
||||
err = isa_register_driver(&snd_es18xx_isa_driver, SNDRV_CARDS);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
#ifdef CONFIG_PNP
|
||||
if (!err)
|
||||
isa_registered = 1;
|
||||
|
||||
err = pnp_register_driver(&es18xx_pnp_driver);
|
||||
if (!err)
|
||||
pnp_registered = 1;
|
||||
|
||||
err = pnp_register_card_driver(&es18xx_pnpc_driver);
|
||||
if (!err)
|
||||
pnpc_registered = 1;
|
||||
|
||||
if (isa_registered || pnp_registered)
|
||||
err = 0;
|
||||
#endif
|
||||
return 0;
|
||||
return err;
|
||||
}
|
||||
|
||||
static void __exit alsa_card_es18xx_exit(void)
|
||||
@ -2487,6 +2493,7 @@ static void __exit alsa_card_es18xx_exit(void)
|
||||
pnp_unregister_card_driver(&es18xx_pnpc_driver);
|
||||
if (pnp_registered)
|
||||
pnp_unregister_driver(&es18xx_pnp_driver);
|
||||
if (isa_registered)
|
||||
#endif
|
||||
isa_unregister_driver(&snd_es18xx_isa_driver);
|
||||
}
|
||||
|
@ -135,6 +135,7 @@ struct snd_interwave {
|
||||
|
||||
|
||||
#ifdef CONFIG_PNP
|
||||
static int isa_registered;
|
||||
static int pnp_registered;
|
||||
|
||||
static struct pnp_card_device_id snd_interwave_pnpids[] = {
|
||||
@ -934,15 +935,18 @@ static int __init alsa_card_interwave_init(void)
|
||||
int err;
|
||||
|
||||
err = isa_register_driver(&snd_interwave_driver, SNDRV_CARDS);
|
||||
if (err < 0)
|
||||
return err;
|
||||
#ifdef CONFIG_PNP
|
||||
/* ISA PnP cards */
|
||||
if (!err)
|
||||
isa_registered = 1;
|
||||
|
||||
err = pnp_register_card_driver(&interwave_pnpc_driver);
|
||||
if (!err)
|
||||
pnp_registered = 1;
|
||||
|
||||
if (isa_registered)
|
||||
err = 0;
|
||||
#endif
|
||||
return 0;
|
||||
return err;
|
||||
}
|
||||
|
||||
static void __exit alsa_card_interwave_exit(void)
|
||||
@ -950,6 +954,7 @@ static void __exit alsa_card_interwave_exit(void)
|
||||
#ifdef CONFIG_PNP
|
||||
if (pnp_registered)
|
||||
pnp_unregister_card_driver(&interwave_pnpc_driver);
|
||||
if (isa_registered)
|
||||
#endif
|
||||
isa_unregister_driver(&snd_interwave_driver);
|
||||
}
|
||||
|
@ -92,6 +92,7 @@ module_param_array(opl3sa3_ymode, int, NULL, 0444);
|
||||
MODULE_PARM_DESC(opl3sa3_ymode, "Speaker size selection for 3D Enhancement mode: Desktop/Large Notebook/Small Notebook/HiFi.");
|
||||
|
||||
#ifdef CONFIG_PNP
|
||||
static int isa_registered;
|
||||
static int pnp_registered;
|
||||
static int pnpc_registered;
|
||||
#endif
|
||||
@ -967,17 +968,22 @@ static int __init alsa_card_opl3sa2_init(void)
|
||||
int err;
|
||||
|
||||
err = isa_register_driver(&snd_opl3sa2_isa_driver, SNDRV_CARDS);
|
||||
if (err < 0)
|
||||
return err;
|
||||
#ifdef CONFIG_PNP
|
||||
if (!err)
|
||||
isa_registered = 1;
|
||||
|
||||
err = pnp_register_driver(&opl3sa2_pnp_driver);
|
||||
if (!err)
|
||||
pnp_registered = 1;
|
||||
|
||||
err = pnp_register_card_driver(&opl3sa2_pnpc_driver);
|
||||
if (!err)
|
||||
pnpc_registered = 1;
|
||||
|
||||
if (isa_registered || pnp_registered)
|
||||
err = 0;
|
||||
#endif
|
||||
return 0;
|
||||
return err;
|
||||
}
|
||||
|
||||
static void __exit alsa_card_opl3sa2_exit(void)
|
||||
@ -987,6 +993,7 @@ static void __exit alsa_card_opl3sa2_exit(void)
|
||||
pnp_unregister_card_driver(&opl3sa2_pnpc_driver);
|
||||
if (pnp_registered)
|
||||
pnp_unregister_driver(&opl3sa2_pnp_driver);
|
||||
if (isa_registered)
|
||||
#endif
|
||||
isa_unregister_driver(&snd_opl3sa2_isa_driver);
|
||||
}
|
||||
|
@ -129,6 +129,7 @@ MODULE_PARM_DESC(seq_ports, "Number of sequencer ports for WaveTable synth.");
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PNP
|
||||
static int isa_registered;
|
||||
static int pnp_registered;
|
||||
#endif
|
||||
|
||||
@ -702,15 +703,18 @@ static int __init alsa_card_sb16_init(void)
|
||||
int err;
|
||||
|
||||
err = isa_register_driver(&snd_sb16_isa_driver, SNDRV_CARDS);
|
||||
if (err < 0)
|
||||
return err;
|
||||
#ifdef CONFIG_PNP
|
||||
/* PnP cards at last */
|
||||
if (!err)
|
||||
isa_registered = 1;
|
||||
|
||||
err = pnp_register_card_driver(&sb16_pnpc_driver);
|
||||
if (!err)
|
||||
pnp_registered = 1;
|
||||
|
||||
if (isa_registered)
|
||||
err = 0;
|
||||
#endif
|
||||
return 0;
|
||||
return err;
|
||||
}
|
||||
|
||||
static void __exit alsa_card_sb16_exit(void)
|
||||
@ -718,6 +722,7 @@ static void __exit alsa_card_sb16_exit(void)
|
||||
#ifdef CONFIG_PNP
|
||||
if (pnp_registered)
|
||||
pnp_unregister_card_driver(&sb16_pnpc_driver);
|
||||
if (isa_registered)
|
||||
#endif
|
||||
isa_unregister_driver(&snd_sb16_isa_driver);
|
||||
}
|
||||
|
@ -69,7 +69,9 @@ module_param_array(dma, int, NULL, 0444);
|
||||
MODULE_PARM_DESC(dma, "DMA # for SoundScape driver.");
|
||||
|
||||
#ifdef CONFIG_PNP
|
||||
static int isa_registered;
|
||||
static int pnp_registered;
|
||||
|
||||
static struct pnp_card_device_id sscape_pnpids[] = {
|
||||
{ .id = "ENS3081", .devs = { { "ENS0000" } } },
|
||||
{ .id = "" } /* end */
|
||||
@ -1405,22 +1407,21 @@ static struct pnp_card_driver sscape_pnpc_driver = {
|
||||
|
||||
static int __init sscape_init(void)
|
||||
{
|
||||
int ret;
|
||||
int err;
|
||||
|
||||
/*
|
||||
* First check whether we were passed any parameters.
|
||||
* These MUST take precedence over ANY automatic way
|
||||
* of allocating cards, because the operator is
|
||||
* S-P-E-L-L-I-N-G it out for us...
|
||||
*/
|
||||
ret = isa_register_driver(&snd_sscape_driver, SNDRV_CARDS);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
err = isa_register_driver(&snd_sscape_driver, SNDRV_CARDS);
|
||||
#ifdef CONFIG_PNP
|
||||
if (pnp_register_card_driver(&sscape_pnpc_driver) == 0)
|
||||
if (!err)
|
||||
isa_registered = 1;
|
||||
|
||||
err = pnp_register_card_driver(&sscape_pnpc_driver);
|
||||
if (!err)
|
||||
pnp_registered = 1;
|
||||
|
||||
if (isa_registered)
|
||||
err = 0;
|
||||
#endif
|
||||
return 0;
|
||||
return err;
|
||||
}
|
||||
|
||||
static void __exit sscape_exit(void)
|
||||
@ -1428,6 +1429,7 @@ static void __exit sscape_exit(void)
|
||||
#ifdef CONFIG_PNP
|
||||
if (pnp_registered)
|
||||
pnp_unregister_card_driver(&sscape_pnpc_driver);
|
||||
if (isa_registered)
|
||||
#endif
|
||||
isa_unregister_driver(&snd_sscape_driver);
|
||||
}
|
||||
|
@ -86,6 +86,7 @@ module_param_array(use_cs4232_midi, bool, NULL, 0444);
|
||||
MODULE_PARM_DESC(use_cs4232_midi, "Use CS4232 MPU-401 interface (inaccessibly located inside your computer)");
|
||||
|
||||
#ifdef CONFIG_PNP
|
||||
static int isa_registered;
|
||||
static int pnp_registered;
|
||||
|
||||
static struct pnp_card_device_id snd_wavefront_pnpids[] = {
|
||||
@ -706,14 +707,18 @@ static int __init alsa_card_wavefront_init(void)
|
||||
int err;
|
||||
|
||||
err = isa_register_driver(&snd_wavefront_driver, SNDRV_CARDS);
|
||||
if (err < 0)
|
||||
return err;
|
||||
#ifdef CONFIG_PNP
|
||||
if (!err)
|
||||
isa_registered = 1;
|
||||
|
||||
err = pnp_register_card_driver(&wavefront_pnpc_driver);
|
||||
if (!err)
|
||||
pnp_registered = 1;
|
||||
|
||||
if (isa_registered)
|
||||
err = 0;
|
||||
#endif
|
||||
return 0;
|
||||
return err;
|
||||
}
|
||||
|
||||
static void __exit alsa_card_wavefront_exit(void)
|
||||
@ -721,6 +726,7 @@ static void __exit alsa_card_wavefront_exit(void)
|
||||
#ifdef CONFIG_PNP
|
||||
if (pnp_registered)
|
||||
pnp_unregister_card_driver(&wavefront_pnpc_driver);
|
||||
if (isa_registered)
|
||||
#endif
|
||||
isa_unregister_driver(&snd_wavefront_driver);
|
||||
}
|
||||
|
@ -1782,6 +1782,11 @@ static unsigned int ad1981_jacks_blacklist[] = {
|
||||
0x10140534, /* Thinkpad X31 */
|
||||
0x10140537, /* Thinkpad T41p */
|
||||
0x10140554, /* Thinkpad T42p/R50p */
|
||||
0x10140567, /* Thinkpad T43p 2668-G7U */
|
||||
0x10140581, /* Thinkpad X41-2527 */
|
||||
0x104380b0, /* Asus A7V8X-MX */
|
||||
0x11790241, /* Toshiba Satellite A-15 S127 */
|
||||
0x144dc01a, /* Samsung NP-X20C004/SEG */
|
||||
0 /* end */
|
||||
};
|
||||
|
||||
|
@ -707,6 +707,7 @@ static u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction)
|
||||
direction == HDA_OUTPUT ?
|
||||
AC_PAR_AMP_OUT_CAP :
|
||||
AC_PAR_AMP_IN_CAP);
|
||||
if (info->amp_caps)
|
||||
info->status |= INFO_AMP_CAPS;
|
||||
}
|
||||
return info->amp_caps;
|
||||
|
@ -93,6 +93,7 @@ enum {
|
||||
ALC262_HP_BPC_D7000_WL,
|
||||
ALC262_HP_BPC_D7000_WF,
|
||||
ALC262_BENQ_ED8,
|
||||
ALC262_SONY_ASSAMD,
|
||||
ALC262_AUTO,
|
||||
ALC262_MODEL_LAST /* last tag */
|
||||
};
|
||||
@ -118,6 +119,7 @@ enum {
|
||||
ALC861VD_3ST_DIG,
|
||||
ALC861VD_6ST_DIG,
|
||||
ALC861VD_LENOVO,
|
||||
ALC861VD_DALLAS,
|
||||
ALC861VD_AUTO,
|
||||
ALC861VD_MODEL_LAST,
|
||||
};
|
||||
@ -139,8 +141,10 @@ enum {
|
||||
ALC882_6ST_DIG,
|
||||
ALC882_ARIMA,
|
||||
ALC882_W2JC,
|
||||
ALC882_AUTO,
|
||||
ALC882_TARGA,
|
||||
ALC882_ASUS_A7J,
|
||||
ALC885_MACPRO,
|
||||
ALC882_AUTO,
|
||||
ALC882_MODEL_LAST,
|
||||
};
|
||||
|
||||
@ -152,11 +156,13 @@ enum {
|
||||
ALC883_6ST_DIG,
|
||||
ALC883_TARGA_DIG,
|
||||
ALC883_TARGA_2ch_DIG,
|
||||
ALC888_DEMO_BOARD,
|
||||
ALC883_ACER,
|
||||
ALC883_MEDION,
|
||||
ALC883_MEDION_MD2,
|
||||
ALC883_LAPTOP_EAPD,
|
||||
ALC883_LENOVO_101E_2ch,
|
||||
ALC883_LENOVO_NB0763,
|
||||
ALC888_LENOVO_MS7195_DIG,
|
||||
ALC883_AUTO,
|
||||
ALC883_MODEL_LAST,
|
||||
};
|
||||
@ -4752,6 +4758,35 @@ static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol,
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* 2ch mode
|
||||
*/
|
||||
static struct hda_verb alc882_3ST_ch2_init[] = {
|
||||
{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
|
||||
{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
|
||||
{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
|
||||
{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
|
||||
{ } /* end */
|
||||
};
|
||||
|
||||
/*
|
||||
* 6ch mode
|
||||
*/
|
||||
static struct hda_verb alc882_3ST_ch6_init[] = {
|
||||
{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
|
||||
{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
|
||||
{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
|
||||
{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
|
||||
{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
|
||||
{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
|
||||
{ } /* end */
|
||||
};
|
||||
|
||||
static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
|
||||
{ 2, alc882_3ST_ch2_init },
|
||||
{ 6, alc882_3ST_ch6_init },
|
||||
};
|
||||
|
||||
/*
|
||||
* 6ch mode
|
||||
*/
|
||||
@ -4824,6 +4859,40 @@ static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
|
||||
{ } /* end */
|
||||
};
|
||||
|
||||
static struct snd_kcontrol_new alc882_targa_mixer[] = {
|
||||
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
|
||||
HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
|
||||
HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
|
||||
HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
|
||||
HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
|
||||
HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
|
||||
HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
|
||||
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
|
||||
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
|
||||
HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
|
||||
HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
|
||||
{ } /* end */
|
||||
};
|
||||
|
||||
/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
|
||||
* Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
|
||||
*/
|
||||
static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
|
||||
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
|
||||
HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
|
||||
HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
|
||||
HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
|
||||
HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
|
||||
HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
|
||||
HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
|
||||
HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
|
||||
HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
|
||||
HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
|
||||
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
|
||||
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
|
||||
{ } /* end */
|
||||
};
|
||||
|
||||
static struct snd_kcontrol_new alc882_chmode_mixer[] = {
|
||||
{
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
|
||||
@ -4985,6 +5054,66 @@ static struct hda_verb alc882_macpro_init_verbs[] = {
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct hda_verb alc882_targa_verbs[] = {
|
||||
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
|
||||
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
|
||||
|
||||
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
|
||||
{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
|
||||
|
||||
{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
|
||||
{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
|
||||
{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
|
||||
|
||||
{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
|
||||
{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
|
||||
{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
|
||||
{0x01, AC_VERB_SET_GPIO_DATA, 0x03},
|
||||
{ } /* end */
|
||||
};
|
||||
|
||||
/* toggle speaker-output according to the hp-jack state */
|
||||
static void alc882_targa_automute(struct hda_codec *codec)
|
||||
{
|
||||
unsigned int present;
|
||||
|
||||
present = snd_hda_codec_read(codec, 0x14, 0,
|
||||
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
|
||||
snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0,
|
||||
0x80, present ? 0x80 : 0);
|
||||
snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
|
||||
0x80, present ? 0x80 : 0);
|
||||
snd_hda_codec_write(codec, 1, 0, AC_VERB_SET_GPIO_DATA, present ? 1 : 3);
|
||||
}
|
||||
|
||||
static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
|
||||
{
|
||||
/* Looks like the unsol event is incompatible with the standard
|
||||
* definition. 4bit tag is placed at 26 bit!
|
||||
*/
|
||||
if (((res >> 26) == ALC880_HP_EVENT)) {
|
||||
alc882_targa_automute(codec);
|
||||
}
|
||||
}
|
||||
|
||||
static struct hda_verb alc882_asus_a7j_verbs[] = {
|
||||
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
|
||||
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
|
||||
|
||||
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
|
||||
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
|
||||
{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
|
||||
|
||||
{0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
|
||||
{0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
|
||||
{0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
|
||||
|
||||
{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
|
||||
{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
|
||||
{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
|
||||
{ } /* end */
|
||||
};
|
||||
|
||||
static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
|
||||
{
|
||||
unsigned int gpiostate, gpiomask, gpiodir;
|
||||
@ -5152,7 +5281,9 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = {
|
||||
SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
|
||||
SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
|
||||
SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
|
||||
SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
|
||||
SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
|
||||
SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
|
||||
SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
|
||||
SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
|
||||
{}
|
||||
@ -5214,6 +5345,36 @@ static struct alc_config_preset alc882_presets[] = {
|
||||
.channel_mode = alc882_ch_modes,
|
||||
.input_mux = &alc882_capture_source,
|
||||
},
|
||||
[ALC882_TARGA] = {
|
||||
.mixers = { alc882_targa_mixer, alc882_chmode_mixer,
|
||||
alc882_capture_mixer },
|
||||
.init_verbs = { alc882_init_verbs, alc882_targa_verbs},
|
||||
.num_dacs = ARRAY_SIZE(alc882_dac_nids),
|
||||
.dac_nids = alc882_dac_nids,
|
||||
.dig_out_nid = ALC882_DIGOUT_NID,
|
||||
.num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
|
||||
.adc_nids = alc882_adc_nids,
|
||||
.num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
|
||||
.channel_mode = alc882_3ST_6ch_modes,
|
||||
.need_dac_fix = 1,
|
||||
.input_mux = &alc882_capture_source,
|
||||
.unsol_event = alc882_targa_unsol_event,
|
||||
.init_hook = alc882_targa_automute,
|
||||
},
|
||||
[ALC882_ASUS_A7J] = {
|
||||
.mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer,
|
||||
alc882_capture_mixer },
|
||||
.init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
|
||||
.num_dacs = ARRAY_SIZE(alc882_dac_nids),
|
||||
.dac_nids = alc882_dac_nids,
|
||||
.dig_out_nid = ALC882_DIGOUT_NID,
|
||||
.num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
|
||||
.adc_nids = alc882_adc_nids,
|
||||
.num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
|
||||
.channel_mode = alc882_3ST_6ch_modes,
|
||||
.need_dac_fix = 1,
|
||||
.input_mux = &alc882_capture_source,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@ -5441,6 +5602,16 @@ static struct hda_input_mux alc883_lenovo_101e_capture_source = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
|
||||
.num_items = 4,
|
||||
.items = {
|
||||
{ "Mic", 0x0 },
|
||||
{ "iMic", 0x1 },
|
||||
{ "Line", 0x2 },
|
||||
{ "CD", 0x4 },
|
||||
},
|
||||
};
|
||||
|
||||
#define alc883_mux_enum_info alc_mux_enum_info
|
||||
#define alc883_mux_enum_get alc_mux_enum_get
|
||||
|
||||
@ -5772,6 +5943,58 @@ static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
|
||||
{ } /* end */
|
||||
};
|
||||
|
||||
static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
|
||||
HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
|
||||
HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
|
||||
HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
|
||||
HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
|
||||
HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
|
||||
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
|
||||
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
|
||||
HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
|
||||
HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
|
||||
HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
|
||||
HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
|
||||
HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
|
||||
HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
|
||||
{
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
|
||||
/* .name = "Capture Source", */
|
||||
.name = "Input Source",
|
||||
.count = 2,
|
||||
.info = alc883_mux_enum_info,
|
||||
.get = alc883_mux_enum_get,
|
||||
.put = alc883_mux_enum_put,
|
||||
},
|
||||
{ } /* end */
|
||||
};
|
||||
|
||||
static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
|
||||
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
|
||||
HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
|
||||
HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
|
||||
HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
|
||||
HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
|
||||
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
|
||||
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
|
||||
HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
|
||||
HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
|
||||
HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
|
||||
HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
|
||||
HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
|
||||
HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
|
||||
{
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
|
||||
/* .name = "Capture Source", */
|
||||
.name = "Input Source",
|
||||
.count = 2,
|
||||
.info = alc883_mux_enum_info,
|
||||
.get = alc883_mux_enum_get,
|
||||
.put = alc883_mux_enum_put,
|
||||
},
|
||||
{ } /* end */
|
||||
};
|
||||
|
||||
static struct snd_kcontrol_new alc883_chmode_mixer[] = {
|
||||
{
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
|
||||
@ -5886,6 +6109,93 @@ static struct hda_verb alc883_lenovo_101e_verbs[] = {
|
||||
{ } /* end */
|
||||
};
|
||||
|
||||
static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
|
||||
{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
|
||||
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
|
||||
{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
|
||||
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
|
||||
{ } /* end */
|
||||
};
|
||||
|
||||
static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
|
||||
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
|
||||
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
|
||||
{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
|
||||
{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
|
||||
{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
|
||||
{ } /* end */
|
||||
};
|
||||
|
||||
/* toggle front-jack and RCA according to the hp-jack state */
|
||||
static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
|
||||
{
|
||||
unsigned int present;
|
||||
|
||||
present = snd_hda_codec_read(codec, 0x1b, 0,
|
||||
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
|
||||
snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
|
||||
0x80, present ? 0x80 : 0);
|
||||
snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
|
||||
0x80, present ? 0x80 : 0);
|
||||
snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
|
||||
0x80, present ? 0x80 : 0);
|
||||
snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
|
||||
0x80, present ? 0x80 : 0);
|
||||
|
||||
}
|
||||
|
||||
/* toggle RCA according to the front-jack state */
|
||||
static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
|
||||
{
|
||||
unsigned int present;
|
||||
|
||||
present = snd_hda_codec_read(codec, 0x14, 0,
|
||||
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
|
||||
snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
|
||||
0x80, present ? 0x80 : 0);
|
||||
snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
|
||||
0x80, present ? 0x80 : 0);
|
||||
|
||||
}
|
||||
static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
|
||||
unsigned int res)
|
||||
{
|
||||
if ((res >> 26) == ALC880_HP_EVENT)
|
||||
alc888_lenovo_ms7195_front_automute(codec);
|
||||
if ((res >> 26) == ALC880_FRONT_EVENT)
|
||||
alc888_lenovo_ms7195_rca_automute(codec);
|
||||
}
|
||||
|
||||
static struct hda_verb alc883_medion_md2_verbs[] = {
|
||||
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
|
||||
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
|
||||
|
||||
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
|
||||
|
||||
{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
|
||||
{ } /* end */
|
||||
};
|
||||
|
||||
/* toggle speaker-output according to the hp-jack state */
|
||||
static void alc883_medion_md2_automute(struct hda_codec *codec)
|
||||
{
|
||||
unsigned int present;
|
||||
|
||||
present = snd_hda_codec_read(codec, 0x14, 0,
|
||||
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
|
||||
snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
|
||||
0x80, present ? 0x80 : 0);
|
||||
snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
|
||||
0x80, present ? 0x80 : 0);
|
||||
}
|
||||
|
||||
static void alc883_medion_md2_unsol_event(struct hda_codec *codec,
|
||||
unsigned int res)
|
||||
{
|
||||
if ((res >> 26) == ALC880_HP_EVENT)
|
||||
alc883_medion_md2_automute(codec);
|
||||
}
|
||||
|
||||
/* toggle speaker-output according to the hp-jack state */
|
||||
static void alc883_tagra_automute(struct hda_codec *codec)
|
||||
{
|
||||
@ -6051,11 +6361,13 @@ static const char *alc883_models[ALC883_MODEL_LAST] = {
|
||||
[ALC883_6ST_DIG] = "6stack-dig",
|
||||
[ALC883_TARGA_DIG] = "targa-dig",
|
||||
[ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
|
||||
[ALC888_DEMO_BOARD] = "6stack-dig-demo",
|
||||
[ALC883_ACER] = "acer",
|
||||
[ALC883_MEDION] = "medion",
|
||||
[ALC883_MEDION_MD2] = "medion-md2",
|
||||
[ALC883_LAPTOP_EAPD] = "laptop-eapd",
|
||||
[ALC883_LENOVO_101E_2ch] = "lenovo-101e",
|
||||
[ALC883_LENOVO_NB0763] = "lenovo-nb0763",
|
||||
[ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
|
||||
[ALC883_AUTO] = "auto",
|
||||
};
|
||||
|
||||
@ -6082,7 +6394,10 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
|
||||
SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
|
||||
SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
|
||||
SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
|
||||
SND_PCI_QUIRK(0x17aa, 0x101e, "lenovo 101e", ALC883_LENOVO_101E_2ch),
|
||||
SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
|
||||
SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
|
||||
SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
|
||||
SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
|
||||
{}
|
||||
};
|
||||
|
||||
@ -6168,19 +6483,6 @@ static struct alc_config_preset alc883_presets[] = {
|
||||
.unsol_event = alc883_tagra_unsol_event,
|
||||
.init_hook = alc883_tagra_automute,
|
||||
},
|
||||
[ALC888_DEMO_BOARD] = {
|
||||
.mixers = { alc883_base_mixer, alc883_chmode_mixer },
|
||||
.init_verbs = { alc883_init_verbs },
|
||||
.num_dacs = ARRAY_SIZE(alc883_dac_nids),
|
||||
.dac_nids = alc883_dac_nids,
|
||||
.dig_out_nid = ALC883_DIGOUT_NID,
|
||||
.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
|
||||
.adc_nids = alc883_adc_nids,
|
||||
.dig_in_nid = ALC883_DIGIN_NID,
|
||||
.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
|
||||
.channel_mode = alc883_sixstack_modes,
|
||||
.input_mux = &alc883_capture_source,
|
||||
},
|
||||
[ALC883_ACER] = {
|
||||
.mixers = { alc883_base_mixer,
|
||||
alc883_chmode_mixer },
|
||||
@ -6211,6 +6513,20 @@ static struct alc_config_preset alc883_presets[] = {
|
||||
.channel_mode = alc883_sixstack_modes,
|
||||
.input_mux = &alc883_capture_source,
|
||||
},
|
||||
[ALC883_MEDION_MD2] = {
|
||||
.mixers = { alc883_medion_md2_mixer},
|
||||
.init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
|
||||
.num_dacs = ARRAY_SIZE(alc883_dac_nids),
|
||||
.dac_nids = alc883_dac_nids,
|
||||
.dig_out_nid = ALC883_DIGOUT_NID,
|
||||
.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
|
||||
.adc_nids = alc883_adc_nids,
|
||||
.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
|
||||
.channel_mode = alc883_3ST_2ch_modes,
|
||||
.input_mux = &alc883_capture_source,
|
||||
.unsol_event = alc883_medion_md2_unsol_event,
|
||||
.init_hook = alc883_medion_md2_automute,
|
||||
},
|
||||
[ALC883_LAPTOP_EAPD] = {
|
||||
.mixers = { alc883_base_mixer,
|
||||
alc883_chmode_mixer },
|
||||
@ -6236,6 +6552,35 @@ static struct alc_config_preset alc883_presets[] = {
|
||||
.unsol_event = alc883_lenovo_101e_unsol_event,
|
||||
.init_hook = alc883_lenovo_101e_all_automute,
|
||||
},
|
||||
[ALC883_LENOVO_NB0763] = {
|
||||
.mixers = { alc883_lenovo_nb0763_mixer },
|
||||
.init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
|
||||
.num_dacs = ARRAY_SIZE(alc883_dac_nids),
|
||||
.dac_nids = alc883_dac_nids,
|
||||
.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
|
||||
.adc_nids = alc883_adc_nids,
|
||||
.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
|
||||
.channel_mode = alc883_3ST_2ch_modes,
|
||||
.need_dac_fix = 1,
|
||||
.input_mux = &alc883_lenovo_nb0763_capture_source,
|
||||
.unsol_event = alc883_medion_md2_unsol_event,
|
||||
.init_hook = alc883_medion_md2_automute,
|
||||
},
|
||||
[ALC888_LENOVO_MS7195_DIG] = {
|
||||
.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
|
||||
.init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
|
||||
.num_dacs = ARRAY_SIZE(alc883_dac_nids),
|
||||
.dac_nids = alc883_dac_nids,
|
||||
.dig_out_nid = ALC883_DIGOUT_NID,
|
||||
.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
|
||||
.adc_nids = alc883_adc_nids,
|
||||
.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
|
||||
.channel_mode = alc883_3ST_6ch_modes,
|
||||
.need_dac_fix = 1,
|
||||
.input_mux = &alc883_capture_source,
|
||||
.unsol_event = alc883_lenovo_ms7195_unsol_event,
|
||||
.init_hook = alc888_lenovo_ms7195_front_automute,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@ -6499,6 +6844,18 @@ static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
|
||||
{ } /* end */
|
||||
};
|
||||
|
||||
static struct snd_kcontrol_new alc262_sony_mixer[] = {
|
||||
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
|
||||
HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
|
||||
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
|
||||
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
|
||||
HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
|
||||
HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
|
||||
{ } /* end */
|
||||
};
|
||||
|
||||
|
||||
|
||||
#define alc262_capture_mixer alc882_capture_mixer
|
||||
#define alc262_capture_alt_mixer alc882_capture_alt_mixer
|
||||
|
||||
@ -6597,6 +6954,15 @@ static struct hda_verb alc262_hippo1_unsol_verbs[] = {
|
||||
{}
|
||||
};
|
||||
|
||||
static struct hda_verb alc262_sony_unsol_verbs[] = {
|
||||
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
|
||||
{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
|
||||
{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
|
||||
|
||||
{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
|
||||
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
|
||||
};
|
||||
|
||||
/* mute/unmute internal speaker according to the hp jack and mute state */
|
||||
static void alc262_hippo_automute(struct hda_codec *codec, int force)
|
||||
{
|
||||
@ -7215,6 +7581,7 @@ static const char *alc262_models[ALC262_MODEL_LAST] = {
|
||||
[ALC262_HP_BPC] = "hp-bpc",
|
||||
[ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
|
||||
[ALC262_BENQ_ED8] = "benq",
|
||||
[ALC262_BENQ_ED8] = "sony-assamd",
|
||||
[ALC262_AUTO] = "auto",
|
||||
};
|
||||
|
||||
@ -7236,6 +7603,9 @@ static struct snd_pci_quirk alc262_cfg_tbl[] = {
|
||||
SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
|
||||
SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
|
||||
SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
|
||||
SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
|
||||
SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
|
||||
SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
|
||||
{}
|
||||
};
|
||||
|
||||
@ -7327,6 +7697,17 @@ static struct alc_config_preset alc262_presets[] = {
|
||||
.channel_mode = alc262_modes,
|
||||
.input_mux = &alc262_capture_source,
|
||||
},
|
||||
[ALC262_SONY_ASSAMD] = {
|
||||
.mixers = { alc262_sony_mixer },
|
||||
.init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
|
||||
.num_dacs = ARRAY_SIZE(alc262_dac_nids),
|
||||
.dac_nids = alc262_dac_nids,
|
||||
.hp_nid = 0x02,
|
||||
.num_channel_mode = ARRAY_SIZE(alc262_modes),
|
||||
.channel_mode = alc262_modes,
|
||||
.input_mux = &alc262_capture_source,
|
||||
.unsol_event = alc262_hippo_unsol_event,
|
||||
},
|
||||
};
|
||||
|
||||
static int patch_alc262(struct hda_codec *codec)
|
||||
@ -8599,6 +8980,15 @@ static struct hda_input_mux alc861vd_capture_source = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct hda_input_mux alc861vd_dallas_capture_source = {
|
||||
.num_items = 3,
|
||||
.items = {
|
||||
{ "Front Mic", 0x0 },
|
||||
{ "ATAPI Mic", 0x1 },
|
||||
{ "Line In", 0x5 },
|
||||
},
|
||||
};
|
||||
|
||||
#define alc861vd_mux_enum_info alc_mux_enum_info
|
||||
#define alc861vd_mux_enum_get alc_mux_enum_get
|
||||
|
||||
@ -8782,6 +9172,34 @@ static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
|
||||
{ } /* end */
|
||||
};
|
||||
|
||||
/* Pin assignment: Front=0x14, HP = 0x15,
|
||||
* Front Mic=0x18, ATAPI Mic = 0x19, Line In = 0x1d
|
||||
*/
|
||||
static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
|
||||
HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
|
||||
HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
|
||||
HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
|
||||
HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
|
||||
HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
|
||||
HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
|
||||
HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
|
||||
HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
|
||||
HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x05, HDA_INPUT),
|
||||
HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x05, HDA_INPUT),
|
||||
HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
|
||||
HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
|
||||
{
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
|
||||
/* .name = "Capture Source", */
|
||||
.name = "Input Source",
|
||||
.count = 1,
|
||||
.info = alc882_mux_enum_info,
|
||||
.get = alc882_mux_enum_get,
|
||||
.put = alc882_mux_enum_put,
|
||||
},
|
||||
{ } /* end */
|
||||
};
|
||||
|
||||
/*
|
||||
* generic initialization of ADC, input mixers and output mixers
|
||||
*/
|
||||
@ -8969,6 +9387,70 @@ static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
|
||||
}
|
||||
}
|
||||
|
||||
static struct hda_verb alc861vd_dallas_verbs[] = {
|
||||
{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
|
||||
{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
|
||||
{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
|
||||
{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
|
||||
|
||||
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
|
||||
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
|
||||
{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
|
||||
{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
|
||||
{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
|
||||
{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
|
||||
{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
|
||||
{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
|
||||
|
||||
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
|
||||
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
|
||||
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
|
||||
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
|
||||
{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
|
||||
{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
|
||||
{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
|
||||
{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
|
||||
|
||||
{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
|
||||
{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
|
||||
{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
|
||||
{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
|
||||
{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
|
||||
{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
|
||||
{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
|
||||
{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
|
||||
|
||||
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
|
||||
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
|
||||
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
|
||||
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
|
||||
|
||||
{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
|
||||
{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
|
||||
{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
|
||||
|
||||
{ } /* end */
|
||||
};
|
||||
|
||||
/* toggle speaker-output according to the hp-jack state */
|
||||
static void alc861vd_dallas_automute(struct hda_codec *codec)
|
||||
{
|
||||
unsigned int present;
|
||||
|
||||
present = snd_hda_codec_read(codec, 0x15, 0,
|
||||
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
|
||||
snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
|
||||
0x80, present ? 0x80 : 0);
|
||||
snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
|
||||
0x80, present ? 0x80 : 0);
|
||||
}
|
||||
|
||||
static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res)
|
||||
{
|
||||
if ((res >> 26) == ALC880_HP_EVENT)
|
||||
alc861vd_dallas_automute(codec);
|
||||
}
|
||||
|
||||
/* pcm configuration: identiacal with ALC880 */
|
||||
#define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
|
||||
#define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
|
||||
@ -8984,6 +9466,7 @@ static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
|
||||
[ALC861VD_3ST_DIG] = "3stack-digout",
|
||||
[ALC861VD_6ST_DIG] = "6stack-digout",
|
||||
[ALC861VD_LENOVO] = "lenovo",
|
||||
[ALC861VD_DALLAS] = "dallas",
|
||||
[ALC861VD_AUTO] = "auto",
|
||||
};
|
||||
|
||||
@ -8993,6 +9476,8 @@ static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
|
||||
SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
|
||||
SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
|
||||
|
||||
SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),
|
||||
SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
|
||||
SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
|
||||
SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
|
||||
{}
|
||||
@ -9059,6 +9544,19 @@ static struct alc_config_preset alc861vd_presets[] = {
|
||||
.unsol_event = alc861vd_lenovo_unsol_event,
|
||||
.init_hook = alc861vd_lenovo_automute,
|
||||
},
|
||||
[ALC861VD_DALLAS] = {
|
||||
.mixers = { alc861vd_dallas_mixer },
|
||||
.init_verbs = { alc861vd_dallas_verbs },
|
||||
.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
|
||||
.dac_nids = alc861vd_dac_nids,
|
||||
.num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
|
||||
.adc_nids = alc861vd_adc_nids,
|
||||
.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
|
||||
.channel_mode = alc861vd_3stack_2ch_modes,
|
||||
.input_mux = &alc861vd_dallas_capture_source,
|
||||
.unsol_event = alc861vd_dallas_unsol_event,
|
||||
.init_hook = alc861vd_dallas_automute,
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -467,6 +467,8 @@ static struct snd_pci_quirk stac9200_cfg_tbl[] = {
|
||||
"Dell XPS M1710", STAC_REF),
|
||||
SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cf,
|
||||
"Dell Precision M90", STAC_REF),
|
||||
SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d6,
|
||||
"unknown Dell", STAC_REF),
|
||||
{} /* terminator */
|
||||
};
|
||||
|
||||
|
@ -1797,6 +1797,18 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = {
|
||||
.name = "Dell Unknown", /* STAC9750/51 */
|
||||
.type = AC97_TUNE_HP_ONLY
|
||||
},
|
||||
{
|
||||
.subvendor = 0x1028,
|
||||
.subdevice = 0x0186,
|
||||
.name = "Dell Latitude D810", /* cf. Malone #41015 */
|
||||
.type = AC97_TUNE_HP_MUTE_LED
|
||||
},
|
||||
{
|
||||
.subvendor = 0x1028,
|
||||
.subdevice = 0x0188,
|
||||
.name = "Dell Inspiron 6000",
|
||||
.type = AC97_TUNE_HP_MUTE_LED /* cf. Malone #41015 */
|
||||
},
|
||||
{
|
||||
.subvendor = 0x1028,
|
||||
.subdevice = 0x0191,
|
||||
@ -1819,7 +1831,7 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = {
|
||||
.subvendor = 0x103c,
|
||||
.subdevice = 0x088c,
|
||||
.name = "HP nc8000",
|
||||
.type = AC97_TUNE_MUTE_LED
|
||||
.type = AC97_TUNE_HP_MUTE_LED
|
||||
},
|
||||
{
|
||||
.subvendor = 0x103c,
|
||||
@ -1911,6 +1923,12 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = {
|
||||
.name = "Fujitsu S6210", /* STAC9750/51 */
|
||||
.type = AC97_TUNE_HP_ONLY
|
||||
},
|
||||
{
|
||||
.subvendor = 0x10cf,
|
||||
.subdevice = 0x127e,
|
||||
.name = "Fujitsu Lifebook C1211D",
|
||||
.type = AC97_TUNE_HP_ONLY
|
||||
},
|
||||
{
|
||||
.subvendor = 0x10cf,
|
||||
.subdevice = 0x12ec,
|
||||
|
@ -43,8 +43,9 @@ static int ac97_prepare(struct snd_pcm_substream *substream)
|
||||
#define STD_AC97_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
|
||||
SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)
|
||||
|
||||
static struct snd_soc_codec_dai ac97_dai = {
|
||||
struct snd_soc_codec_dai ac97_dai = {
|
||||
.name = "AC97 HiFi",
|
||||
.type = SND_SOC_DAI_AC97,
|
||||
.playback = {
|
||||
.stream_name = "AC97 Playback",
|
||||
.channels_min = 1,
|
||||
|
@ -544,6 +544,7 @@ static int ac97_aux_prepare(struct snd_pcm_substream *substream)
|
||||
struct snd_soc_codec_dai wm9712_dai[] = {
|
||||
{
|
||||
.name = "AC97 HiFi",
|
||||
.type = SND_SOC_DAI_AC97_BUS,
|
||||
.playback = {
|
||||
.stream_name = "HiFi Playback",
|
||||
.channels_min = 1,
|
||||
|
@ -116,6 +116,7 @@ static int soc_ac97_dev_register(struct snd_soc_codec *codec)
|
||||
static inline const char* get_dai_name(int type)
|
||||
{
|
||||
switch(type) {
|
||||
case SND_SOC_DAI_AC97_BUS:
|
||||
case SND_SOC_DAI_AC97:
|
||||
return "AC97";
|
||||
case SND_SOC_DAI_I2S:
|
||||
@ -1099,7 +1100,8 @@ int snd_soc_register_card(struct snd_soc_device *socdev)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (socdev->machine->dai_link[i].cpu_dai->type == SND_SOC_DAI_AC97)
|
||||
if (socdev->machine->dai_link[i].codec_dai->type ==
|
||||
SND_SOC_DAI_AC97_BUS)
|
||||
ac97 = 1;
|
||||
}
|
||||
snprintf(codec->card->shortname, sizeof(codec->card->shortname),
|
||||
@ -1148,11 +1150,21 @@ EXPORT_SYMBOL_GPL(snd_soc_register_card);
|
||||
void snd_soc_free_pcms(struct snd_soc_device *socdev)
|
||||
{
|
||||
struct snd_soc_codec *codec = socdev->codec;
|
||||
#ifdef CONFIG_SND_SOC_AC97_BUS
|
||||
struct snd_soc_codec_dai *codec_dai;
|
||||
int i;
|
||||
#endif
|
||||
|
||||
mutex_lock(&codec->mutex);
|
||||
#ifdef CONFIG_SND_SOC_AC97_BUS
|
||||
if (codec->ac97)
|
||||
for(i = 0; i < codec->num_dai; i++) {
|
||||
codec_dai = &codec->dai[i];
|
||||
if (codec_dai->type == SND_SOC_DAI_AC97_BUS && codec->ac97) {
|
||||
soc_ac97_dev_unregister(codec);
|
||||
goto free_card;
|
||||
}
|
||||
}
|
||||
free_card:
|
||||
#endif
|
||||
|
||||
if (codec->card)
|
||||
|
@ -360,7 +360,7 @@ static int get_ctl_value(struct usb_mixer_elem_info *cval, int request, int vali
|
||||
request,
|
||||
USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
|
||||
validx, cval->mixer->ctrlif | (cval->id << 8),
|
||||
buf, val_len, 100) >= 0) {
|
||||
buf, val_len, 100) >= val_len) {
|
||||
*value_ret = convert_signed_value(cval, snd_usb_combine_bytes(buf, val_len));
|
||||
return 0;
|
||||
}
|
||||
|
@ -43,6 +43,15 @@
|
||||
* Logitech QuickCam: bDeviceClass is vendor-specific, so generic interface
|
||||
* class matches do not take effect without an explicit ID match.
|
||||
*/
|
||||
{
|
||||
.match_flags = USB_DEVICE_ID_MATCH_DEVICE |
|
||||
USB_DEVICE_ID_MATCH_INT_CLASS |
|
||||
USB_DEVICE_ID_MATCH_INT_SUBCLASS,
|
||||
.idVendor = 0x046d,
|
||||
.idProduct = 0x0850,
|
||||
.bInterfaceClass = USB_CLASS_AUDIO,
|
||||
.bInterfaceSubClass = USB_SUBCLASS_AUDIO_CONTROL
|
||||
},
|
||||
{
|
||||
.match_flags = USB_DEVICE_ID_MATCH_DEVICE |
|
||||
USB_DEVICE_ID_MATCH_INT_CLASS |
|
||||
|
Loading…
Reference in New Issue
Block a user