mirror of https://gitee.com/openkylin/linux.git
Merge branch 'linus' into sched/locking
Merge reason: Pick up this upstream commit: 6631e635c65d: block: don't flush plugged IO on forced preemtion scheduling As it modifies the scheduler and we'll queue up dependent patches. Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
commit
a4c98f8bbe
|
@ -387,26 +387,6 @@ Who: Tejun Heo <tj@kernel.org>
|
|||
|
||||
----------------------------
|
||||
|
||||
What: Support for lcd_switch and display_get in asus-laptop driver
|
||||
When: March 2010
|
||||
Why: These two features use non-standard interfaces. There are the
|
||||
only features that really need multiple path to guess what's
|
||||
the right method name on a specific laptop.
|
||||
|
||||
Removing them will allow to remove a lot of code an significantly
|
||||
clean the drivers.
|
||||
|
||||
This will affect the backlight code which won't be able to know
|
||||
if the backlight is on or off. The platform display file will also be
|
||||
write only (like the one in eeepc-laptop).
|
||||
|
||||
This should'nt affect a lot of user because they usually know
|
||||
when their display is on or off.
|
||||
|
||||
Who: Corentin Chary <corentin.chary@gmail.com>
|
||||
|
||||
----------------------------
|
||||
|
||||
What: sysfs-class-rfkill state file
|
||||
When: Feb 2014
|
||||
Files: net/rfkill/core.c
|
||||
|
|
|
@ -6916,6 +6916,13 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/mjg59/platform-drivers-x86.
|
|||
S: Maintained
|
||||
F: drivers/platform/x86
|
||||
|
||||
XEN NETWORK BACKEND DRIVER
|
||||
M: Ian Campbell <ian.campbell@citrix.com>
|
||||
L: xen-devel@lists.xensource.com (moderated for non-subscribers)
|
||||
L: netdev@vger.kernel.org
|
||||
S: Supported
|
||||
F: drivers/net/xen-netback/*
|
||||
|
||||
XEN PCI SUBSYSTEM
|
||||
M: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
|
||||
L: xen-devel@lists.xensource.com (moderated for non-subscribers)
|
||||
|
|
2
Makefile
2
Makefile
|
@ -1,7 +1,7 @@
|
|||
VERSION = 2
|
||||
PATCHLEVEL = 6
|
||||
SUBLEVEL = 39
|
||||
EXTRAVERSION = -rc2
|
||||
EXTRAVERSION = -rc3
|
||||
NAME = Flesh-Eating Bats with Fangs
|
||||
|
||||
# *DOCUMENTATION*
|
||||
|
|
|
@ -94,6 +94,13 @@ struct tag_ethernet {
|
|||
|
||||
#define ETH_INVALID_PHY 0xff
|
||||
|
||||
/* board information */
|
||||
#define ATAG_BOARDINFO 0x54410008
|
||||
|
||||
struct tag_boardinfo {
|
||||
u32 board_number;
|
||||
};
|
||||
|
||||
struct tag {
|
||||
struct tag_header hdr;
|
||||
union {
|
||||
|
@ -102,6 +109,7 @@ struct tag {
|
|||
struct tag_cmdline cmdline;
|
||||
struct tag_clock clock;
|
||||
struct tag_ethernet ethernet;
|
||||
struct tag_boardinfo boardinfo;
|
||||
} u;
|
||||
};
|
||||
|
||||
|
@ -128,6 +136,7 @@ extern struct tag *bootloader_tags;
|
|||
|
||||
extern resource_size_t fbmem_start;
|
||||
extern resource_size_t fbmem_size;
|
||||
extern u32 board_number;
|
||||
|
||||
void setup_processor(void);
|
||||
|
||||
|
|
|
@ -390,6 +390,21 @@ static int __init parse_tag_clock(struct tag *tag)
|
|||
}
|
||||
__tagtable(ATAG_CLOCK, parse_tag_clock);
|
||||
|
||||
/*
|
||||
* The board_number correspond to the bd->bi_board_number in U-Boot. This
|
||||
* parameter is only available during initialisation and can be used in some
|
||||
* kind of board identification.
|
||||
*/
|
||||
u32 __initdata board_number;
|
||||
|
||||
static int __init parse_tag_boardinfo(struct tag *tag)
|
||||
{
|
||||
board_number = tag->u.boardinfo.board_number;
|
||||
|
||||
return 0;
|
||||
}
|
||||
__tagtable(ATAG_BOARDINFO, parse_tag_boardinfo);
|
||||
|
||||
/*
|
||||
* Scan the tag table for this tag, and call its parse function. The
|
||||
* tag table is built by the linker from all the __tagtable
|
||||
|
|
|
@ -95,28 +95,6 @@ void _exception(long signr, struct pt_regs *regs, int code,
|
|||
info.si_code = code;
|
||||
info.si_addr = (void __user *)addr;
|
||||
force_sig_info(signr, &info, current);
|
||||
|
||||
/*
|
||||
* Init gets no signals that it doesn't have a handler for.
|
||||
* That's all very well, but if it has caused a synchronous
|
||||
* exception and we ignore the resulting signal, it will just
|
||||
* generate the same exception over and over again and we get
|
||||
* nowhere. Better to kill it and let the kernel panic.
|
||||
*/
|
||||
if (is_global_init(current)) {
|
||||
__sighandler_t handler;
|
||||
|
||||
spin_lock_irq(¤t->sighand->siglock);
|
||||
handler = current->sighand->action[signr-1].sa.sa_handler;
|
||||
spin_unlock_irq(¤t->sighand->siglock);
|
||||
if (handler == SIG_DFL) {
|
||||
/* init has generated a synchronous exception
|
||||
and it doesn't have a handler for the signal */
|
||||
printk(KERN_CRIT "init has generated signal %ld "
|
||||
"but has no handler for it\n", signr);
|
||||
do_exit(signr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
asmlinkage void do_nmi(unsigned long ecr, struct pt_regs *regs)
|
||||
|
|
|
@ -35,22 +35,30 @@ void at32_clk_register(struct clk *clk)
|
|||
spin_unlock(&clk_list_lock);
|
||||
}
|
||||
|
||||
static struct clk *__clk_get(struct device *dev, const char *id)
|
||||
{
|
||||
struct clk *clk;
|
||||
|
||||
list_for_each_entry(clk, &at32_clock_list, list) {
|
||||
if (clk->dev == dev && strcmp(id, clk->name) == 0) {
|
||||
return clk;
|
||||
}
|
||||
}
|
||||
|
||||
return ERR_PTR(-ENOENT);
|
||||
}
|
||||
|
||||
struct clk *clk_get(struct device *dev, const char *id)
|
||||
{
|
||||
struct clk *clk;
|
||||
|
||||
spin_lock(&clk_list_lock);
|
||||
|
||||
list_for_each_entry(clk, &at32_clock_list, list) {
|
||||
if (clk->dev == dev && strcmp(id, clk->name) == 0) {
|
||||
spin_unlock(&clk_list_lock);
|
||||
return clk;
|
||||
}
|
||||
}
|
||||
|
||||
clk = __clk_get(dev, id);
|
||||
spin_unlock(&clk_list_lock);
|
||||
return ERR_PTR(-ENOENT);
|
||||
|
||||
return clk;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(clk_get);
|
||||
|
||||
void clk_put(struct clk *clk)
|
||||
|
@ -257,15 +265,15 @@ static int clk_show(struct seq_file *s, void *unused)
|
|||
spin_lock(&clk_list_lock);
|
||||
|
||||
/* show clock tree as derived from the three oscillators */
|
||||
clk = clk_get(NULL, "osc32k");
|
||||
clk = __clk_get(NULL, "osc32k");
|
||||
dump_clock(clk, &r);
|
||||
clk_put(clk);
|
||||
|
||||
clk = clk_get(NULL, "osc0");
|
||||
clk = __clk_get(NULL, "osc0");
|
||||
dump_clock(clk, &r);
|
||||
clk_put(clk);
|
||||
|
||||
clk = clk_get(NULL, "osc1");
|
||||
clk = __clk_get(NULL, "osc1");
|
||||
dump_clock(clk, &r);
|
||||
clk_put(clk);
|
||||
|
||||
|
|
|
@ -61,34 +61,34 @@ struct eic {
|
|||
static struct eic *nmi_eic;
|
||||
static bool nmi_enabled;
|
||||
|
||||
static void eic_ack_irq(struct irq_chip *d)
|
||||
static void eic_ack_irq(struct irq_data *d)
|
||||
{
|
||||
struct eic *eic = irq_data_get_irq_chip_data(data);
|
||||
struct eic *eic = irq_data_get_irq_chip_data(d);
|
||||
eic_writel(eic, ICR, 1 << (d->irq - eic->first_irq));
|
||||
}
|
||||
|
||||
static void eic_mask_irq(struct irq_chip *d)
|
||||
static void eic_mask_irq(struct irq_data *d)
|
||||
{
|
||||
struct eic *eic = irq_data_get_irq_chip_data(data);
|
||||
struct eic *eic = irq_data_get_irq_chip_data(d);
|
||||
eic_writel(eic, IDR, 1 << (d->irq - eic->first_irq));
|
||||
}
|
||||
|
||||
static void eic_mask_ack_irq(struct irq_chip *d)
|
||||
static void eic_mask_ack_irq(struct irq_data *d)
|
||||
{
|
||||
struct eic *eic = irq_data_get_irq_chip_data(data);
|
||||
struct eic *eic = irq_data_get_irq_chip_data(d);
|
||||
eic_writel(eic, ICR, 1 << (d->irq - eic->first_irq));
|
||||
eic_writel(eic, IDR, 1 << (d->irq - eic->first_irq));
|
||||
}
|
||||
|
||||
static void eic_unmask_irq(struct irq_chip *d)
|
||||
static void eic_unmask_irq(struct irq_data *d)
|
||||
{
|
||||
struct eic *eic = irq_data_get_irq_chip_data(data);
|
||||
struct eic *eic = irq_data_get_irq_chip_data(d);
|
||||
eic_writel(eic, IER, 1 << (d->irq - eic->first_irq));
|
||||
}
|
||||
|
||||
static int eic_set_irq_type(struct irq_chip *d, unsigned int flow_type)
|
||||
static int eic_set_irq_type(struct irq_data *d, unsigned int flow_type)
|
||||
{
|
||||
struct eic *eic = irq_data_get_irq_chip_data(data);
|
||||
struct eic *eic = irq_data_get_irq_chip_data(d);
|
||||
unsigned int irq = d->irq;
|
||||
unsigned int i = irq - eic->first_irq;
|
||||
u32 mode, edge, level;
|
||||
|
@ -191,7 +191,7 @@ static int __init eic_probe(struct platform_device *pdev)
|
|||
|
||||
regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
int_irq = platform_get_irq(pdev, 0);
|
||||
if (!regs || !int_irq) {
|
||||
if (!regs || (int)int_irq <= 0) {
|
||||
dev_dbg(&pdev->dev, "missing regs and/or irq resource\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
|
|
|
@ -257,7 +257,7 @@ static void gpio_irq_mask(struct irq_data *d)
|
|||
pio_writel(pio, IDR, 1 << (gpio & 0x1f));
|
||||
}
|
||||
|
||||
static void gpio_irq_unmask(struct irq_data *d))
|
||||
static void gpio_irq_unmask(struct irq_data *d)
|
||||
{
|
||||
unsigned gpio = irq_to_gpio(d->irq);
|
||||
struct pio_device *pio = &pio_dev[gpio >> 5];
|
||||
|
|
|
@ -53,7 +53,7 @@ cpu_enter_idle:
|
|||
st.w r8[TI_flags], r9
|
||||
unmask_interrupts
|
||||
sleep CPU_SLEEP_IDLE
|
||||
.size cpu_idle_sleep, . - cpu_idle_sleep
|
||||
.size cpu_enter_idle, . - cpu_enter_idle
|
||||
|
||||
/*
|
||||
* Common return path for PM functions that don't run from
|
||||
|
|
|
@ -343,10 +343,14 @@
|
|||
#define __NR_fanotify_init 337
|
||||
#define __NR_fanotify_mark 338
|
||||
#define __NR_prlimit64 339
|
||||
#define __NR_name_to_handle_at 340
|
||||
#define __NR_open_by_handle_at 341
|
||||
#define __NR_clock_adjtime 342
|
||||
#define __NR_syncfs 343
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#define NR_syscalls 340
|
||||
#define NR_syscalls 344
|
||||
|
||||
#define __ARCH_WANT_IPC_PARSE_VERSION
|
||||
#define __ARCH_WANT_OLD_READDIR
|
||||
|
|
|
@ -750,4 +750,8 @@ sys_call_table:
|
|||
.long sys_fanotify_init
|
||||
.long sys_fanotify_mark
|
||||
.long sys_prlimit64
|
||||
.long sys_name_to_handle_at /* 340 */
|
||||
.long sys_open_by_handle_at
|
||||
.long sys_clock_adjtime
|
||||
.long sys_syncfs
|
||||
|
||||
|
|
|
@ -358,6 +358,10 @@ ENTRY(sys_call_table)
|
|||
.long sys_fanotify_init
|
||||
.long sys_fanotify_mark
|
||||
.long sys_prlimit64
|
||||
.long sys_name_to_handle_at /* 340 */
|
||||
.long sys_open_by_handle_at
|
||||
.long sys_clock_adjtime
|
||||
.long sys_syncfs
|
||||
|
||||
.rept NR_syscalls-(.-sys_call_table)/4
|
||||
.long sys_ni_syscall
|
||||
|
|
|
@ -527,7 +527,7 @@ static int ibmebus_bus_pm_resume_noirq(struct device *dev)
|
|||
|
||||
#endif /* !CONFIG_SUSPEND */
|
||||
|
||||
#ifdef CONFIG_HIBERNATION
|
||||
#ifdef CONFIG_HIBERNATE_CALLBACKS
|
||||
|
||||
static int ibmebus_bus_pm_freeze(struct device *dev)
|
||||
{
|
||||
|
@ -665,7 +665,7 @@ static int ibmebus_bus_pm_restore_noirq(struct device *dev)
|
|||
return ret;
|
||||
}
|
||||
|
||||
#else /* !CONFIG_HIBERNATION */
|
||||
#else /* !CONFIG_HIBERNATE_CALLBACKS */
|
||||
|
||||
#define ibmebus_bus_pm_freeze NULL
|
||||
#define ibmebus_bus_pm_thaw NULL
|
||||
|
@ -676,7 +676,7 @@ static int ibmebus_bus_pm_restore_noirq(struct device *dev)
|
|||
#define ibmebus_bus_pm_poweroff_noirq NULL
|
||||
#define ibmebus_bus_pm_restore_noirq NULL
|
||||
|
||||
#endif /* !CONFIG_HIBERNATION */
|
||||
#endif /* !CONFIG_HIBERNATE_CALLBACKS */
|
||||
|
||||
static struct dev_pm_ops ibmebus_bus_dev_pm_ops = {
|
||||
.prepare = ibmebus_bus_pm_prepare,
|
||||
|
|
|
@ -39,6 +39,7 @@ config XEN_MAX_DOMAIN_MEMORY
|
|||
config XEN_SAVE_RESTORE
|
||||
bool
|
||||
depends on XEN
|
||||
select HIBERNATE_CALLBACKS
|
||||
default y
|
||||
|
||||
config XEN_DEBUG_FS
|
||||
|
|
|
@ -238,6 +238,7 @@ static void xen_cpuid(unsigned int *ax, unsigned int *bx,
|
|||
static __init void xen_init_cpuid_mask(void)
|
||||
{
|
||||
unsigned int ax, bx, cx, dx;
|
||||
unsigned int xsave_mask;
|
||||
|
||||
cpuid_leaf1_edx_mask =
|
||||
~((1 << X86_FEATURE_MCE) | /* disable MCE */
|
||||
|
@ -249,24 +250,16 @@ static __init void xen_init_cpuid_mask(void)
|
|||
cpuid_leaf1_edx_mask &=
|
||||
~((1 << X86_FEATURE_APIC) | /* disable local APIC */
|
||||
(1 << X86_FEATURE_ACPI)); /* disable ACPI */
|
||||
|
||||
ax = 1;
|
||||
cx = 0;
|
||||
xen_cpuid(&ax, &bx, &cx, &dx);
|
||||
|
||||
/* cpuid claims we support xsave; try enabling it to see what happens */
|
||||
if (cx & (1 << (X86_FEATURE_XSAVE % 32))) {
|
||||
unsigned long cr4;
|
||||
xsave_mask =
|
||||
(1 << (X86_FEATURE_XSAVE % 32)) |
|
||||
(1 << (X86_FEATURE_OSXSAVE % 32));
|
||||
|
||||
set_in_cr4(X86_CR4_OSXSAVE);
|
||||
|
||||
cr4 = read_cr4();
|
||||
|
||||
if ((cr4 & X86_CR4_OSXSAVE) == 0)
|
||||
cpuid_leaf1_ecx_mask &= ~(1 << (X86_FEATURE_XSAVE % 32));
|
||||
|
||||
clear_in_cr4(X86_CR4_OSXSAVE);
|
||||
}
|
||||
/* Xen will set CR4.OSXSAVE if supported and not disabled by force */
|
||||
if ((cx & xsave_mask) != xsave_mask)
|
||||
cpuid_leaf1_ecx_mask &= ~xsave_mask; /* disable XSAVE & OSXSAVE */
|
||||
}
|
||||
|
||||
static void xen_set_debugreg(int reg, unsigned long val)
|
||||
|
|
|
@ -565,13 +565,13 @@ pte_t xen_make_pte_debug(pteval_t pte)
|
|||
if (io_page &&
|
||||
(xen_initial_domain() || addr >= ISA_END_ADDRESS)) {
|
||||
other_addr = pfn_to_mfn(addr >> PAGE_SHIFT) << PAGE_SHIFT;
|
||||
WARN(addr != other_addr,
|
||||
WARN_ONCE(addr != other_addr,
|
||||
"0x%lx is using VM_IO, but it is 0x%lx!\n",
|
||||
(unsigned long)addr, (unsigned long)other_addr);
|
||||
} else {
|
||||
pteval_t iomap_set = (_pte.pte & PTE_FLAGS_MASK) & _PAGE_IOMAP;
|
||||
other_addr = (_pte.pte & PTE_PFN_MASK);
|
||||
WARN((addr == other_addr) && (!io_page) && (!iomap_set),
|
||||
WARN_ONCE((addr == other_addr) && (!io_page) && (!iomap_set),
|
||||
"0x%lx is missing VM_IO (and wasn't fixed)!\n",
|
||||
(unsigned long)addr);
|
||||
}
|
||||
|
|
|
@ -214,7 +214,7 @@ static int amba_pm_resume_noirq(struct device *dev)
|
|||
|
||||
#endif /* !CONFIG_SUSPEND */
|
||||
|
||||
#ifdef CONFIG_HIBERNATION
|
||||
#ifdef CONFIG_HIBERNATE_CALLBACKS
|
||||
|
||||
static int amba_pm_freeze(struct device *dev)
|
||||
{
|
||||
|
@ -352,7 +352,7 @@ static int amba_pm_restore_noirq(struct device *dev)
|
|||
return ret;
|
||||
}
|
||||
|
||||
#else /* !CONFIG_HIBERNATION */
|
||||
#else /* !CONFIG_HIBERNATE_CALLBACKS */
|
||||
|
||||
#define amba_pm_freeze NULL
|
||||
#define amba_pm_thaw NULL
|
||||
|
@ -363,7 +363,7 @@ static int amba_pm_restore_noirq(struct device *dev)
|
|||
#define amba_pm_poweroff_noirq NULL
|
||||
#define amba_pm_restore_noirq NULL
|
||||
|
||||
#endif /* !CONFIG_HIBERNATION */
|
||||
#endif /* !CONFIG_HIBERNATE_CALLBACKS */
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
|
||||
|
|
|
@ -149,6 +149,7 @@ static void platform_device_release(struct device *dev)
|
|||
|
||||
of_device_node_put(&pa->pdev.dev);
|
||||
kfree(pa->pdev.dev.platform_data);
|
||||
kfree(pa->pdev.mfd_cell);
|
||||
kfree(pa->pdev.resource);
|
||||
kfree(pa);
|
||||
}
|
||||
|
@ -771,7 +772,7 @@ int __weak platform_pm_resume_noirq(struct device *dev)
|
|||
|
||||
#endif /* !CONFIG_SUSPEND */
|
||||
|
||||
#ifdef CONFIG_HIBERNATION
|
||||
#ifdef CONFIG_HIBERNATE_CALLBACKS
|
||||
|
||||
static int platform_pm_freeze(struct device *dev)
|
||||
{
|
||||
|
@ -909,7 +910,7 @@ static int platform_pm_restore_noirq(struct device *dev)
|
|||
return ret;
|
||||
}
|
||||
|
||||
#else /* !CONFIG_HIBERNATION */
|
||||
#else /* !CONFIG_HIBERNATE_CALLBACKS */
|
||||
|
||||
#define platform_pm_freeze NULL
|
||||
#define platform_pm_thaw NULL
|
||||
|
@ -920,7 +921,7 @@ static int platform_pm_restore_noirq(struct device *dev)
|
|||
#define platform_pm_poweroff_noirq NULL
|
||||
#define platform_pm_restore_noirq NULL
|
||||
|
||||
#endif /* !CONFIG_HIBERNATION */
|
||||
#endif /* !CONFIG_HIBERNATE_CALLBACKS */
|
||||
|
||||
#ifdef CONFIG_PM_RUNTIME
|
||||
|
||||
|
|
|
@ -233,7 +233,7 @@ static int pm_op(struct device *dev,
|
|||
}
|
||||
break;
|
||||
#endif /* CONFIG_SUSPEND */
|
||||
#ifdef CONFIG_HIBERNATION
|
||||
#ifdef CONFIG_HIBERNATE_CALLBACKS
|
||||
case PM_EVENT_FREEZE:
|
||||
case PM_EVENT_QUIESCE:
|
||||
if (ops->freeze) {
|
||||
|
@ -260,7 +260,7 @@ static int pm_op(struct device *dev,
|
|||
suspend_report_result(ops->restore, error);
|
||||
}
|
||||
break;
|
||||
#endif /* CONFIG_HIBERNATION */
|
||||
#endif /* CONFIG_HIBERNATE_CALLBACKS */
|
||||
default:
|
||||
error = -EINVAL;
|
||||
}
|
||||
|
@ -308,7 +308,7 @@ static int pm_noirq_op(struct device *dev,
|
|||
}
|
||||
break;
|
||||
#endif /* CONFIG_SUSPEND */
|
||||
#ifdef CONFIG_HIBERNATION
|
||||
#ifdef CONFIG_HIBERNATE_CALLBACKS
|
||||
case PM_EVENT_FREEZE:
|
||||
case PM_EVENT_QUIESCE:
|
||||
if (ops->freeze_noirq) {
|
||||
|
@ -335,7 +335,7 @@ static int pm_noirq_op(struct device *dev,
|
|||
suspend_report_result(ops->restore_noirq, error);
|
||||
}
|
||||
break;
|
||||
#endif /* CONFIG_HIBERNATION */
|
||||
#endif /* CONFIG_HIBERNATE_CALLBACKS */
|
||||
default:
|
||||
error = -EINVAL;
|
||||
}
|
||||
|
|
|
@ -1448,7 +1448,7 @@ static const struct of_device_id fsldma_of_ids[] = {
|
|||
{}
|
||||
};
|
||||
|
||||
static struct of_platform_driver fsldma_of_driver = {
|
||||
static struct platform_driver fsldma_of_driver = {
|
||||
.driver = {
|
||||
.name = "fsl-elo-dma",
|
||||
.owner = THIS_MODULE,
|
||||
|
|
|
@ -116,6 +116,7 @@ static int ioh_gpio_direction_output(struct gpio_chip *gpio, unsigned nr,
|
|||
reg_val |= (1 << nr);
|
||||
else
|
||||
reg_val &= ~(1 << nr);
|
||||
iowrite32(reg_val, &chip->reg->regs[chip->ch].po);
|
||||
|
||||
mutex_unlock(&chip->lock);
|
||||
|
||||
|
|
|
@ -558,7 +558,7 @@ static int __devinit pca953x_probe(struct i2c_client *client,
|
|||
|
||||
ret = gpiochip_add(&chip->gpio_chip);
|
||||
if (ret)
|
||||
goto out_failed;
|
||||
goto out_failed_irq;
|
||||
|
||||
if (pdata->setup) {
|
||||
ret = pdata->setup(client, chip->gpio_chip.base,
|
||||
|
@ -570,8 +570,9 @@ static int __devinit pca953x_probe(struct i2c_client *client,
|
|||
i2c_set_clientdata(client, chip);
|
||||
return 0;
|
||||
|
||||
out_failed:
|
||||
out_failed_irq:
|
||||
pca953x_irq_teardown(chip);
|
||||
out_failed:
|
||||
kfree(chip->dyn_pdata);
|
||||
kfree(chip);
|
||||
return ret;
|
||||
|
|
|
@ -105,6 +105,7 @@ static int pch_gpio_direction_output(struct gpio_chip *gpio, unsigned nr,
|
|||
reg_val |= (1 << nr);
|
||||
else
|
||||
reg_val &= ~(1 << nr);
|
||||
iowrite32(reg_val, &chip->reg->po);
|
||||
|
||||
mutex_unlock(&chip->lock);
|
||||
|
||||
|
|
|
@ -96,6 +96,7 @@ config DRM_I915
|
|||
# i915 depends on ACPI_VIDEO when ACPI is enabled
|
||||
# but for select to work, need to select ACPI_VIDEO's dependencies, ick
|
||||
select BACKLIGHT_CLASS_DEVICE if ACPI
|
||||
select VIDEO_OUTPUT_CONTROL if ACPI
|
||||
select INPUT if ACPI
|
||||
select ACPI_VIDEO if ACPI
|
||||
select ACPI_BUTTON if ACPI
|
||||
|
|
|
@ -269,7 +269,7 @@ struct init_tbl_entry {
|
|||
int (*handler)(struct nvbios *, uint16_t, struct init_exec *);
|
||||
};
|
||||
|
||||
static int parse_init_table(struct nvbios *, unsigned int, struct init_exec *);
|
||||
static int parse_init_table(struct nvbios *, uint16_t, struct init_exec *);
|
||||
|
||||
#define MACRO_INDEX_SIZE 2
|
||||
#define MACRO_SIZE 8
|
||||
|
@ -2010,6 +2010,27 @@ init_sub_direct(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
|
|||
return 3;
|
||||
}
|
||||
|
||||
static int
|
||||
init_jump(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
|
||||
{
|
||||
/*
|
||||
* INIT_JUMP opcode: 0x5C ('\')
|
||||
*
|
||||
* offset (8 bit): opcode
|
||||
* offset + 1 (16 bit): offset (in bios)
|
||||
*
|
||||
* Continue execution of init table from 'offset'
|
||||
*/
|
||||
|
||||
uint16_t jmp_offset = ROM16(bios->data[offset + 1]);
|
||||
|
||||
if (!iexec->execute)
|
||||
return 3;
|
||||
|
||||
BIOSLOG(bios, "0x%04X: Jump to 0x%04X\n", offset, jmp_offset);
|
||||
return jmp_offset - offset;
|
||||
}
|
||||
|
||||
static int
|
||||
init_i2c_if(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
|
||||
{
|
||||
|
@ -3659,6 +3680,7 @@ static struct init_tbl_entry itbl_entry[] = {
|
|||
{ "INIT_ZM_REG_SEQUENCE" , 0x58, init_zm_reg_sequence },
|
||||
/* INIT_INDIRECT_REG (0x5A, 7, 0, 0) removed due to no example of use */
|
||||
{ "INIT_SUB_DIRECT" , 0x5B, init_sub_direct },
|
||||
{ "INIT_JUMP" , 0x5C, init_jump },
|
||||
{ "INIT_I2C_IF" , 0x5E, init_i2c_if },
|
||||
{ "INIT_COPY_NV_REG" , 0x5F, init_copy_nv_reg },
|
||||
{ "INIT_ZM_INDEX_IO" , 0x62, init_zm_index_io },
|
||||
|
@ -3700,8 +3722,7 @@ static struct init_tbl_entry itbl_entry[] = {
|
|||
#define MAX_TABLE_OPS 1000
|
||||
|
||||
static int
|
||||
parse_init_table(struct nvbios *bios, unsigned int offset,
|
||||
struct init_exec *iexec)
|
||||
parse_init_table(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
|
||||
{
|
||||
/*
|
||||
* Parses all commands in an init table.
|
||||
|
@ -6333,6 +6354,32 @@ apply_dcb_encoder_quirks(struct drm_device *dev, int idx, u32 *conn, u32 *conf)
|
|||
}
|
||||
}
|
||||
|
||||
/* XFX GT-240X-YA
|
||||
*
|
||||
* So many things wrong here, replace the entire encoder table..
|
||||
*/
|
||||
if (nv_match_device(dev, 0x0ca3, 0x1682, 0x3003)) {
|
||||
if (idx == 0) {
|
||||
*conn = 0x02001300; /* VGA, connector 1 */
|
||||
*conf = 0x00000028;
|
||||
} else
|
||||
if (idx == 1) {
|
||||
*conn = 0x01010312; /* DVI, connector 0 */
|
||||
*conf = 0x00020030;
|
||||
} else
|
||||
if (idx == 2) {
|
||||
*conn = 0x01010310; /* VGA, connector 0 */
|
||||
*conf = 0x00000028;
|
||||
} else
|
||||
if (idx == 3) {
|
||||
*conn = 0x02022362; /* HDMI, connector 2 */
|
||||
*conf = 0x00020010;
|
||||
} else {
|
||||
*conn = 0x0000000e; /* EOL */
|
||||
*conf = 0x00000000;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -1190,7 +1190,7 @@ extern int nv50_graph_load_context(struct nouveau_channel *);
|
|||
extern int nv50_graph_unload_context(struct drm_device *);
|
||||
extern int nv50_grctx_init(struct nouveau_grctx *);
|
||||
extern void nv50_graph_tlb_flush(struct drm_device *dev);
|
||||
extern void nv86_graph_tlb_flush(struct drm_device *dev);
|
||||
extern void nv84_graph_tlb_flush(struct drm_device *dev);
|
||||
extern struct nouveau_enum nv50_data_error_names[];
|
||||
|
||||
/* nvc0_graph.c */
|
||||
|
|
|
@ -552,6 +552,7 @@ nouveau_mem_timing_init(struct drm_device *dev)
|
|||
u8 tRC; /* Byte 9 */
|
||||
u8 tUNK_10, tUNK_11, tUNK_12, tUNK_13, tUNK_14;
|
||||
u8 tUNK_18, tUNK_19, tUNK_20, tUNK_21;
|
||||
u8 magic_number = 0; /* Yeah... sorry*/
|
||||
u8 *mem = NULL, *entry;
|
||||
int i, recordlen, entries;
|
||||
|
||||
|
@ -596,6 +597,12 @@ nouveau_mem_timing_init(struct drm_device *dev)
|
|||
if (!memtimings->timing)
|
||||
return;
|
||||
|
||||
/* Get "some number" from the timing reg for NV_40
|
||||
* Used in calculations later */
|
||||
if(dev_priv->card_type == NV_40) {
|
||||
magic_number = (nv_rd32(dev,0x100228) & 0x0f000000) >> 24;
|
||||
}
|
||||
|
||||
entry = mem + mem[1];
|
||||
for (i = 0; i < entries; i++, entry += recordlen) {
|
||||
struct nouveau_pm_memtiming *timing = &pm->memtimings.timing[i];
|
||||
|
@ -635,36 +642,51 @@ nouveau_mem_timing_init(struct drm_device *dev)
|
|||
|
||||
/* XXX: I don't trust the -1's and +1's... they must come
|
||||
* from somewhere! */
|
||||
timing->reg_100224 = ((tUNK_0 + tUNK_19 + 1) << 24 |
|
||||
timing->reg_100224 = (tUNK_0 + tUNK_19 + 1 + magic_number) << 24 |
|
||||
tUNK_18 << 16 |
|
||||
(tUNK_1 + tUNK_19 + 1) << 8 |
|
||||
(tUNK_2 - 1));
|
||||
(tUNK_1 + tUNK_19 + 1 + magic_number) << 8;
|
||||
if(dev_priv->chipset == 0xa8) {
|
||||
timing->reg_100224 |= (tUNK_2 - 1);
|
||||
} else {
|
||||
timing->reg_100224 |= (tUNK_2 + 2 - magic_number);
|
||||
}
|
||||
|
||||
timing->reg_100228 = (tUNK_12 << 16 | tUNK_11 << 8 | tUNK_10);
|
||||
if(recordlen > 19) {
|
||||
timing->reg_100228 += (tUNK_19 - 1) << 24;
|
||||
}/* I cannot back-up this else-statement right now
|
||||
else {
|
||||
timing->reg_100228 += tUNK_12 << 24;
|
||||
}*/
|
||||
if(dev_priv->chipset >= 0xa3 && dev_priv->chipset < 0xaa) {
|
||||
timing->reg_100228 |= (tUNK_19 - 1) << 24;
|
||||
}
|
||||
|
||||
/* XXX: reg_10022c */
|
||||
timing->reg_10022c = tUNK_2 - 1;
|
||||
if(dev_priv->card_type == NV_40) {
|
||||
/* NV40: don't know what the rest of the regs are..
|
||||
* And don't need to know either */
|
||||
timing->reg_100228 |= 0x20200000 | magic_number << 24;
|
||||
} else if(dev_priv->card_type >= NV_50) {
|
||||
/* XXX: reg_10022c */
|
||||
timing->reg_10022c = tUNK_2 - 1;
|
||||
|
||||
timing->reg_100230 = (tUNK_20 << 24 | tUNK_21 << 16 |
|
||||
tUNK_13 << 8 | tUNK_13);
|
||||
timing->reg_100230 = (tUNK_20 << 24 | tUNK_21 << 16 |
|
||||
tUNK_13 << 8 | tUNK_13);
|
||||
|
||||
/* XXX: +6? */
|
||||
timing->reg_100234 = (tRAS << 24 | (tUNK_19 + 6) << 8 | tRC);
|
||||
timing->reg_100234 += max(tUNK_10,tUNK_11) << 16;
|
||||
timing->reg_100234 = (tRAS << 24 | tRC);
|
||||
timing->reg_100234 += max(tUNK_10,tUNK_11) << 16;
|
||||
|
||||
/* XXX; reg_100238, reg_10023c
|
||||
* reg: 0x00??????
|
||||
* reg_10023c:
|
||||
* 0 for pre-NV50 cards
|
||||
* 0x????0202 for NV50+ cards (empirical evidence) */
|
||||
if(dev_priv->card_type >= NV_50) {
|
||||
if(dev_priv->chipset < 0xa3) {
|
||||
timing->reg_100234 |= (tUNK_2 + 2) << 8;
|
||||
} else {
|
||||
/* XXX: +6? */
|
||||
timing->reg_100234 |= (tUNK_19 + 6) << 8;
|
||||
}
|
||||
|
||||
/* XXX; reg_100238, reg_10023c
|
||||
* reg_100238: 0x00??????
|
||||
* reg_10023c: 0x!!??0202 for NV50+ cards (empirical evidence) */
|
||||
timing->reg_10023c = 0x202;
|
||||
if(dev_priv->chipset < 0xa3) {
|
||||
timing->reg_10023c |= 0x4000000 | (tUNK_2 - 1) << 16;
|
||||
} else {
|
||||
/* currently unknown
|
||||
* 10023c seen as 06xxxxxx, 0bxxxxxx or 0fxxxxxx */
|
||||
}
|
||||
}
|
||||
|
||||
NV_DEBUG(dev, "Entry %d: 220: %08x %08x %08x %08x\n", i,
|
||||
|
@ -675,7 +697,7 @@ nouveau_mem_timing_init(struct drm_device *dev)
|
|||
timing->reg_100238, timing->reg_10023c);
|
||||
}
|
||||
|
||||
memtimings->nr_timing = entries;
|
||||
memtimings->nr_timing = entries;
|
||||
memtimings->supported = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -134,7 +134,7 @@ nouveau_perf_init(struct drm_device *dev)
|
|||
case 0x13:
|
||||
case 0x15:
|
||||
perflvl->fanspeed = entry[55];
|
||||
perflvl->voltage = entry[56];
|
||||
perflvl->voltage = (recordlen > 56) ? entry[56] : 0;
|
||||
perflvl->core = ROM32(entry[1]) * 10;
|
||||
perflvl->memory = ROM32(entry[5]) * 20;
|
||||
break;
|
||||
|
|
|
@ -376,15 +376,11 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
|
|||
engine->graph.destroy_context = nv50_graph_destroy_context;
|
||||
engine->graph.load_context = nv50_graph_load_context;
|
||||
engine->graph.unload_context = nv50_graph_unload_context;
|
||||
if (dev_priv->chipset != 0x86)
|
||||
if (dev_priv->chipset == 0x50 ||
|
||||
dev_priv->chipset == 0xac)
|
||||
engine->graph.tlb_flush = nv50_graph_tlb_flush;
|
||||
else {
|
||||
/* from what i can see nvidia do this on every
|
||||
* pre-NVA3 board except NVAC, but, we've only
|
||||
* ever seen problems on NV86
|
||||
*/
|
||||
engine->graph.tlb_flush = nv86_graph_tlb_flush;
|
||||
}
|
||||
else
|
||||
engine->graph.tlb_flush = nv84_graph_tlb_flush;
|
||||
engine->fifo.channels = 128;
|
||||
engine->fifo.init = nv50_fifo_init;
|
||||
engine->fifo.takedown = nv50_fifo_takedown;
|
||||
|
|
|
@ -581,12 +581,13 @@ static void nv04_dfp_restore(struct drm_encoder *encoder)
|
|||
int head = nv_encoder->restore.head;
|
||||
|
||||
if (nv_encoder->dcb->type == OUTPUT_LVDS) {
|
||||
struct drm_display_mode *native_mode = nouveau_encoder_connector_get(nv_encoder)->native_mode;
|
||||
if (native_mode)
|
||||
call_lvds_script(dev, nv_encoder->dcb, head, LVDS_PANEL_ON,
|
||||
native_mode->clock);
|
||||
else
|
||||
NV_ERROR(dev, "Not restoring LVDS without native mode\n");
|
||||
struct nouveau_connector *connector =
|
||||
nouveau_encoder_connector_get(nv_encoder);
|
||||
|
||||
if (connector && connector->native_mode)
|
||||
call_lvds_script(dev, nv_encoder->dcb, head,
|
||||
LVDS_PANEL_ON,
|
||||
connector->native_mode->clock);
|
||||
|
||||
} else if (nv_encoder->dcb->type == OUTPUT_TMDS) {
|
||||
int clock = nouveau_hw_pllvals_to_clk
|
||||
|
|
|
@ -469,9 +469,6 @@ nv50_crtc_wait_complete(struct drm_crtc *crtc)
|
|||
|
||||
start = ptimer->read(dev);
|
||||
do {
|
||||
nv_wr32(dev, 0x61002c, 0x370);
|
||||
nv_wr32(dev, 0x000140, 1);
|
||||
|
||||
if (nv_ro32(disp->ntfy, 0x000))
|
||||
return 0;
|
||||
} while (ptimer->read(dev) - start < 2000000000ULL);
|
||||
|
|
|
@ -186,6 +186,7 @@ nv50_evo_channel_init(struct nouveau_channel *evo)
|
|||
nv_mask(dev, 0x610028, 0x00000000, 0x00010001 << id);
|
||||
|
||||
evo->dma.max = (4096/4) - 2;
|
||||
evo->dma.max &= ~7;
|
||||
evo->dma.put = 0;
|
||||
evo->dma.cur = evo->dma.put;
|
||||
evo->dma.free = evo->dma.max - evo->dma.cur;
|
||||
|
|
|
@ -503,7 +503,7 @@ nv50_graph_tlb_flush(struct drm_device *dev)
|
|||
}
|
||||
|
||||
void
|
||||
nv86_graph_tlb_flush(struct drm_device *dev)
|
||||
nv84_graph_tlb_flush(struct drm_device *dev)
|
||||
{
|
||||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||
struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer;
|
||||
|
|
|
@ -104,20 +104,26 @@ nvc0_vm_flush(struct nouveau_vm *vm)
|
|||
struct nouveau_instmem_engine *pinstmem = &dev_priv->engine.instmem;
|
||||
struct drm_device *dev = vm->dev;
|
||||
struct nouveau_vm_pgd *vpgd;
|
||||
u32 r100c80, engine;
|
||||
u32 engine = (dev_priv->chan_vm == vm) ? 1 : 5;
|
||||
|
||||
pinstmem->flush(vm->dev);
|
||||
|
||||
if (vm == dev_priv->chan_vm)
|
||||
engine = 1;
|
||||
else
|
||||
engine = 5;
|
||||
|
||||
spin_lock(&dev_priv->ramin_lock);
|
||||
list_for_each_entry(vpgd, &vm->pgd_list, head) {
|
||||
r100c80 = nv_rd32(dev, 0x100c80);
|
||||
/* looks like maybe a "free flush slots" counter, the
|
||||
* faster you write to 0x100cbc to more it decreases
|
||||
*/
|
||||
if (!nv_wait_ne(dev, 0x100c80, 0x00ff0000, 0x00000000)) {
|
||||
NV_ERROR(dev, "vm timeout 0: 0x%08x %d\n",
|
||||
nv_rd32(dev, 0x100c80), engine);
|
||||
}
|
||||
nv_wr32(dev, 0x100cb8, vpgd->obj->vinst >> 8);
|
||||
nv_wr32(dev, 0x100cbc, 0x80000000 | engine);
|
||||
if (!nv_wait(dev, 0x100c80, 0xffffffff, r100c80))
|
||||
NV_ERROR(dev, "vm flush timeout eng %d\n", engine);
|
||||
/* wait for flush to be queued? */
|
||||
if (!nv_wait(dev, 0x100c80, 0x00008000, 0x00008000)) {
|
||||
NV_ERROR(dev, "vm timeout 1: 0x%08x %d\n",
|
||||
nv_rd32(dev, 0x100c80), engine);
|
||||
}
|
||||
}
|
||||
spin_unlock(&dev_priv->ramin_lock);
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "atom.h"
|
||||
#include "atom-names.h"
|
||||
#include "atom-bits.h"
|
||||
#include "radeon.h"
|
||||
|
||||
#define ATOM_COND_ABOVE 0
|
||||
#define ATOM_COND_ABOVEOREQUAL 1
|
||||
|
@ -101,7 +102,9 @@ static void debug_print_spaces(int n)
|
|||
static uint32_t atom_iio_execute(struct atom_context *ctx, int base,
|
||||
uint32_t index, uint32_t data)
|
||||
{
|
||||
struct radeon_device *rdev = ctx->card->dev->dev_private;
|
||||
uint32_t temp = 0xCDCDCDCD;
|
||||
|
||||
while (1)
|
||||
switch (CU8(base)) {
|
||||
case ATOM_IIO_NOP:
|
||||
|
@ -112,7 +115,8 @@ static uint32_t atom_iio_execute(struct atom_context *ctx, int base,
|
|||
base += 3;
|
||||
break;
|
||||
case ATOM_IIO_WRITE:
|
||||
(void)ctx->card->ioreg_read(ctx->card, CU16(base + 1));
|
||||
if (rdev->family == CHIP_RV515)
|
||||
(void)ctx->card->ioreg_read(ctx->card, CU16(base + 1));
|
||||
ctx->card->ioreg_write(ctx->card, CU16(base + 1), temp);
|
||||
base += 3;
|
||||
break;
|
||||
|
|
|
@ -531,6 +531,12 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
|
|||
pll->flags |= RADEON_PLL_PREFER_HIGH_FB_DIV;
|
||||
else
|
||||
pll->flags |= RADEON_PLL_PREFER_LOW_REF_DIV;
|
||||
|
||||
if ((rdev->family == CHIP_R600) ||
|
||||
(rdev->family == CHIP_RV610) ||
|
||||
(rdev->family == CHIP_RV630) ||
|
||||
(rdev->family == CHIP_RV670))
|
||||
pll->flags |= RADEON_PLL_PREFER_MINM_OVER_MAXP;
|
||||
} else {
|
||||
pll->flags |= RADEON_PLL_LEGACY;
|
||||
|
||||
|
|
|
@ -120,11 +120,16 @@ void evergreen_pm_misc(struct radeon_device *rdev)
|
|||
struct radeon_power_state *ps = &rdev->pm.power_state[req_ps_idx];
|
||||
struct radeon_voltage *voltage = &ps->clock_info[req_cm_idx].voltage;
|
||||
|
||||
if ((voltage->type == VOLTAGE_SW) && voltage->voltage) {
|
||||
if (voltage->voltage != rdev->pm.current_vddc) {
|
||||
radeon_atom_set_voltage(rdev, voltage->voltage);
|
||||
if (voltage->type == VOLTAGE_SW) {
|
||||
if (voltage->voltage && (voltage->voltage != rdev->pm.current_vddc)) {
|
||||
radeon_atom_set_voltage(rdev, voltage->voltage, SET_VOLTAGE_TYPE_ASIC_VDDC);
|
||||
rdev->pm.current_vddc = voltage->voltage;
|
||||
DRM_DEBUG("Setting: v: %d\n", voltage->voltage);
|
||||
DRM_DEBUG("Setting: vddc: %d\n", voltage->voltage);
|
||||
}
|
||||
if (voltage->vddci && (voltage->vddci != rdev->pm.current_vddci)) {
|
||||
radeon_atom_set_voltage(rdev, voltage->vddci, SET_VOLTAGE_TYPE_ASIC_VDDCI);
|
||||
rdev->pm.current_vddci = voltage->vddci;
|
||||
DRM_DEBUG("Setting: vddci: %d\n", voltage->vddci);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3036,9 +3041,6 @@ int evergreen_init(struct radeon_device *rdev)
|
|||
{
|
||||
int r;
|
||||
|
||||
r = radeon_dummy_page_init(rdev);
|
||||
if (r)
|
||||
return r;
|
||||
/* This don't do much */
|
||||
r = radeon_gem_init(rdev);
|
||||
if (r)
|
||||
|
@ -3150,7 +3152,6 @@ void evergreen_fini(struct radeon_device *rdev)
|
|||
radeon_atombios_fini(rdev);
|
||||
kfree(rdev->bios);
|
||||
rdev->bios = NULL;
|
||||
radeon_dummy_page_fini(rdev);
|
||||
}
|
||||
|
||||
static void evergreen_pcie_gen2_enable(struct radeon_device *rdev)
|
||||
|
|
|
@ -587,7 +587,7 @@ void r600_pm_misc(struct radeon_device *rdev)
|
|||
|
||||
if ((voltage->type == VOLTAGE_SW) && voltage->voltage) {
|
||||
if (voltage->voltage != rdev->pm.current_vddc) {
|
||||
radeon_atom_set_voltage(rdev, voltage->voltage);
|
||||
radeon_atom_set_voltage(rdev, voltage->voltage, SET_VOLTAGE_TYPE_ASIC_VDDC);
|
||||
rdev->pm.current_vddc = voltage->voltage;
|
||||
DRM_DEBUG_DRIVER("Setting: v: %d\n", voltage->voltage);
|
||||
}
|
||||
|
@ -2509,9 +2509,6 @@ int r600_init(struct radeon_device *rdev)
|
|||
{
|
||||
int r;
|
||||
|
||||
r = radeon_dummy_page_init(rdev);
|
||||
if (r)
|
||||
return r;
|
||||
if (r600_debugfs_mc_info_init(rdev)) {
|
||||
DRM_ERROR("Failed to register debugfs file for mc !\n");
|
||||
}
|
||||
|
@ -2625,7 +2622,6 @@ void r600_fini(struct radeon_device *rdev)
|
|||
radeon_atombios_fini(rdev);
|
||||
kfree(rdev->bios);
|
||||
rdev->bios = NULL;
|
||||
radeon_dummy_page_fini(rdev);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -177,7 +177,7 @@ void radeon_pm_suspend(struct radeon_device *rdev);
|
|||
void radeon_pm_resume(struct radeon_device *rdev);
|
||||
void radeon_combios_get_power_modes(struct radeon_device *rdev);
|
||||
void radeon_atombios_get_power_modes(struct radeon_device *rdev);
|
||||
void radeon_atom_set_voltage(struct radeon_device *rdev, u16 level);
|
||||
void radeon_atom_set_voltage(struct radeon_device *rdev, u16 voltage_level, u8 voltage_type);
|
||||
void rs690_pm_info(struct radeon_device *rdev);
|
||||
extern int rv6xx_get_temp(struct radeon_device *rdev);
|
||||
extern int rv770_get_temp(struct radeon_device *rdev);
|
||||
|
@ -767,7 +767,9 @@ struct radeon_voltage {
|
|||
u8 vddci_id; /* index into vddci voltage table */
|
||||
bool vddci_enabled;
|
||||
/* r6xx+ sw */
|
||||
u32 voltage;
|
||||
u16 voltage;
|
||||
/* evergreen+ vddci */
|
||||
u16 vddci;
|
||||
};
|
||||
|
||||
/* clock mode flags */
|
||||
|
@ -835,10 +837,12 @@ struct radeon_pm {
|
|||
int default_power_state_index;
|
||||
u32 current_sclk;
|
||||
u32 current_mclk;
|
||||
u32 current_vddc;
|
||||
u16 current_vddc;
|
||||
u16 current_vddci;
|
||||
u32 default_sclk;
|
||||
u32 default_mclk;
|
||||
u32 default_vddc;
|
||||
u16 default_vddc;
|
||||
u16 default_vddci;
|
||||
struct radeon_i2c_chan *i2c_bus;
|
||||
/* selected pm method */
|
||||
enum radeon_pm_method pm_method;
|
||||
|
|
|
@ -94,7 +94,7 @@ static void radeon_register_accessor_init(struct radeon_device *rdev)
|
|||
rdev->mc_rreg = &rs600_mc_rreg;
|
||||
rdev->mc_wreg = &rs600_mc_wreg;
|
||||
}
|
||||
if ((rdev->family >= CHIP_R600) && (rdev->family <= CHIP_HEMLOCK)) {
|
||||
if (rdev->family >= CHIP_R600) {
|
||||
rdev->pciep_rreg = &r600_pciep_rreg;
|
||||
rdev->pciep_wreg = &r600_pciep_wreg;
|
||||
}
|
||||
|
|
|
@ -2176,24 +2176,27 @@ static void radeon_atombios_add_pplib_thermal_controller(struct radeon_device *r
|
|||
}
|
||||
}
|
||||
|
||||
static u16 radeon_atombios_get_default_vddc(struct radeon_device *rdev)
|
||||
static void radeon_atombios_get_default_voltages(struct radeon_device *rdev,
|
||||
u16 *vddc, u16 *vddci)
|
||||
{
|
||||
struct radeon_mode_info *mode_info = &rdev->mode_info;
|
||||
int index = GetIndexIntoMasterTable(DATA, FirmwareInfo);
|
||||
u8 frev, crev;
|
||||
u16 data_offset;
|
||||
union firmware_info *firmware_info;
|
||||
u16 vddc = 0;
|
||||
|
||||
*vddc = 0;
|
||||
*vddci = 0;
|
||||
|
||||
if (atom_parse_data_header(mode_info->atom_context, index, NULL,
|
||||
&frev, &crev, &data_offset)) {
|
||||
firmware_info =
|
||||
(union firmware_info *)(mode_info->atom_context->bios +
|
||||
data_offset);
|
||||
vddc = le16_to_cpu(firmware_info->info_14.usBootUpVDDCVoltage);
|
||||
*vddc = le16_to_cpu(firmware_info->info_14.usBootUpVDDCVoltage);
|
||||
if ((frev == 2) && (crev >= 2))
|
||||
*vddci = le16_to_cpu(firmware_info->info_22.usBootUpVDDCIVoltage);
|
||||
}
|
||||
|
||||
return vddc;
|
||||
}
|
||||
|
||||
static void radeon_atombios_parse_pplib_non_clock_info(struct radeon_device *rdev,
|
||||
|
@ -2203,7 +2206,9 @@ static void radeon_atombios_parse_pplib_non_clock_info(struct radeon_device *rde
|
|||
int j;
|
||||
u32 misc = le32_to_cpu(non_clock_info->ulCapsAndSettings);
|
||||
u32 misc2 = le16_to_cpu(non_clock_info->usClassification);
|
||||
u16 vddc = radeon_atombios_get_default_vddc(rdev);
|
||||
u16 vddc, vddci;
|
||||
|
||||
radeon_atombios_get_default_voltages(rdev, &vddc, &vddci);
|
||||
|
||||
rdev->pm.power_state[state_index].misc = misc;
|
||||
rdev->pm.power_state[state_index].misc2 = misc2;
|
||||
|
@ -2244,6 +2249,7 @@ static void radeon_atombios_parse_pplib_non_clock_info(struct radeon_device *rde
|
|||
rdev->pm.default_sclk = rdev->pm.power_state[state_index].clock_info[0].sclk;
|
||||
rdev->pm.default_mclk = rdev->pm.power_state[state_index].clock_info[0].mclk;
|
||||
rdev->pm.default_vddc = rdev->pm.power_state[state_index].clock_info[0].voltage.voltage;
|
||||
rdev->pm.default_vddci = rdev->pm.power_state[state_index].clock_info[0].voltage.vddci;
|
||||
} else {
|
||||
/* patch the table values with the default slck/mclk from firmware info */
|
||||
for (j = 0; j < mode_index; j++) {
|
||||
|
@ -2286,6 +2292,8 @@ static bool radeon_atombios_parse_pplib_clock_info(struct radeon_device *rdev,
|
|||
VOLTAGE_SW;
|
||||
rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage =
|
||||
le16_to_cpu(clock_info->evergreen.usVDDC);
|
||||
rdev->pm.power_state[state_index].clock_info[mode_index].voltage.vddci =
|
||||
le16_to_cpu(clock_info->evergreen.usVDDCI);
|
||||
} else {
|
||||
sclk = le16_to_cpu(clock_info->r600.usEngineClockLow);
|
||||
sclk |= clock_info->r600.ucEngineClockHigh << 16;
|
||||
|
@ -2577,25 +2585,25 @@ union set_voltage {
|
|||
struct _SET_VOLTAGE_PARAMETERS_V2 v2;
|
||||
};
|
||||
|
||||
void radeon_atom_set_voltage(struct radeon_device *rdev, u16 level)
|
||||
void radeon_atom_set_voltage(struct radeon_device *rdev, u16 voltage_level, u8 voltage_type)
|
||||
{
|
||||
union set_voltage args;
|
||||
int index = GetIndexIntoMasterTable(COMMAND, SetVoltage);
|
||||
u8 frev, crev, volt_index = level;
|
||||
u8 frev, crev, volt_index = voltage_level;
|
||||
|
||||
if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
|
||||
return;
|
||||
|
||||
switch (crev) {
|
||||
case 1:
|
||||
args.v1.ucVoltageType = SET_VOLTAGE_TYPE_ASIC_VDDC;
|
||||
args.v1.ucVoltageType = voltage_type;
|
||||
args.v1.ucVoltageMode = SET_ASIC_VOLTAGE_MODE_ALL_SOURCE;
|
||||
args.v1.ucVoltageIndex = volt_index;
|
||||
break;
|
||||
case 2:
|
||||
args.v2.ucVoltageType = SET_VOLTAGE_TYPE_ASIC_VDDC;
|
||||
args.v2.ucVoltageType = voltage_type;
|
||||
args.v2.ucVoltageMode = SET_ASIC_VOLTAGE_MODE_SET_VOLTAGE;
|
||||
args.v2.usVoltageLevel = cpu_to_le16(level);
|
||||
args.v2.usVoltageLevel = cpu_to_le16(voltage_level);
|
||||
break;
|
||||
default:
|
||||
DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
|
||||
|
|
|
@ -79,7 +79,7 @@ static bool radeon_fence_poll_locked(struct radeon_device *rdev)
|
|||
scratch_index = R600_WB_EVENT_OFFSET + rdev->fence_drv.scratch_reg - rdev->scratch.reg_base;
|
||||
else
|
||||
scratch_index = RADEON_WB_SCRATCH_OFFSET + rdev->fence_drv.scratch_reg - rdev->scratch.reg_base;
|
||||
seq = rdev->wb.wb[scratch_index/4];
|
||||
seq = le32_to_cpu(rdev->wb.wb[scratch_index/4]);
|
||||
} else
|
||||
seq = RREG32(rdev->fence_drv.scratch_reg);
|
||||
if (seq != rdev->fence_drv.last_seq) {
|
||||
|
|
|
@ -285,4 +285,6 @@ void radeon_gart_fini(struct radeon_device *rdev)
|
|||
rdev->gart.pages = NULL;
|
||||
rdev->gart.pages_addr = NULL;
|
||||
rdev->gart.ttm_alloced = NULL;
|
||||
|
||||
radeon_dummy_page_fini(rdev);
|
||||
}
|
||||
|
|
|
@ -1062,7 +1062,7 @@ void radeon_i2c_get_byte(struct radeon_i2c_chan *i2c_bus,
|
|||
*val = in_buf[0];
|
||||
DRM_DEBUG("val = 0x%02x\n", *val);
|
||||
} else {
|
||||
DRM_ERROR("i2c 0x%02x 0x%02x read failed\n",
|
||||
DRM_DEBUG("i2c 0x%02x 0x%02x read failed\n",
|
||||
addr, *val);
|
||||
}
|
||||
}
|
||||
|
@ -1084,7 +1084,7 @@ void radeon_i2c_put_byte(struct radeon_i2c_chan *i2c_bus,
|
|||
out_buf[1] = val;
|
||||
|
||||
if (i2c_transfer(&i2c_bus->adapter, &msg, 1) != 1)
|
||||
DRM_ERROR("i2c 0x%02x 0x%02x write failed\n",
|
||||
DRM_DEBUG("i2c 0x%02x 0x%02x write failed\n",
|
||||
addr, val);
|
||||
}
|
||||
|
||||
|
|
|
@ -269,7 +269,7 @@ static const struct drm_encoder_helper_funcs radeon_legacy_lvds_helper_funcs = {
|
|||
.disable = radeon_legacy_encoder_disable,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
|
||||
#if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) || defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE)
|
||||
|
||||
#define MAX_RADEON_LEVEL 0xFF
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "drmP.h"
|
||||
#include "radeon.h"
|
||||
#include "avivod.h"
|
||||
#include "atom.h"
|
||||
#ifdef CONFIG_ACPI
|
||||
#include <linux/acpi.h>
|
||||
#endif
|
||||
|
@ -535,7 +536,11 @@ void radeon_pm_resume(struct radeon_device *rdev)
|
|||
/* set up the default clocks if the MC ucode is loaded */
|
||||
if (ASIC_IS_DCE5(rdev) && rdev->mc_fw) {
|
||||
if (rdev->pm.default_vddc)
|
||||
radeon_atom_set_voltage(rdev, rdev->pm.default_vddc);
|
||||
radeon_atom_set_voltage(rdev, rdev->pm.default_vddc,
|
||||
SET_VOLTAGE_TYPE_ASIC_VDDC);
|
||||
if (rdev->pm.default_vddci)
|
||||
radeon_atom_set_voltage(rdev, rdev->pm.default_vddci,
|
||||
SET_VOLTAGE_TYPE_ASIC_VDDCI);
|
||||
if (rdev->pm.default_sclk)
|
||||
radeon_set_engine_clock(rdev, rdev->pm.default_sclk);
|
||||
if (rdev->pm.default_mclk)
|
||||
|
@ -548,6 +553,7 @@ void radeon_pm_resume(struct radeon_device *rdev)
|
|||
rdev->pm.current_sclk = rdev->pm.default_sclk;
|
||||
rdev->pm.current_mclk = rdev->pm.default_mclk;
|
||||
rdev->pm.current_vddc = rdev->pm.power_state[rdev->pm.default_power_state_index].clock_info[0].voltage.voltage;
|
||||
rdev->pm.current_vddci = rdev->pm.power_state[rdev->pm.default_power_state_index].clock_info[0].voltage.vddci;
|
||||
if (rdev->pm.pm_method == PM_METHOD_DYNPM
|
||||
&& rdev->pm.dynpm_state == DYNPM_STATE_SUSPENDED) {
|
||||
rdev->pm.dynpm_state = DYNPM_STATE_ACTIVE;
|
||||
|
@ -585,7 +591,8 @@ int radeon_pm_init(struct radeon_device *rdev)
|
|||
/* set up the default clocks if the MC ucode is loaded */
|
||||
if (ASIC_IS_DCE5(rdev) && rdev->mc_fw) {
|
||||
if (rdev->pm.default_vddc)
|
||||
radeon_atom_set_voltage(rdev, rdev->pm.default_vddc);
|
||||
radeon_atom_set_voltage(rdev, rdev->pm.default_vddc,
|
||||
SET_VOLTAGE_TYPE_ASIC_VDDC);
|
||||
if (rdev->pm.default_sclk)
|
||||
radeon_set_engine_clock(rdev, rdev->pm.default_sclk);
|
||||
if (rdev->pm.default_mclk)
|
||||
|
|
|
@ -248,7 +248,7 @@ void radeon_ib_pool_fini(struct radeon_device *rdev)
|
|||
void radeon_ring_free_size(struct radeon_device *rdev)
|
||||
{
|
||||
if (rdev->wb.enabled)
|
||||
rdev->cp.rptr = rdev->wb.wb[RADEON_WB_CP_RPTR_OFFSET/4];
|
||||
rdev->cp.rptr = le32_to_cpu(rdev->wb.wb[RADEON_WB_CP_RPTR_OFFSET/4]);
|
||||
else {
|
||||
if (rdev->family >= CHIP_R600)
|
||||
rdev->cp.rptr = RREG32(R600_CP_RB_RPTR);
|
||||
|
|
|
@ -114,7 +114,7 @@ void rs600_pm_misc(struct radeon_device *rdev)
|
|||
udelay(voltage->delay);
|
||||
}
|
||||
} else if (voltage->type == VOLTAGE_VDDC)
|
||||
radeon_atom_set_voltage(rdev, voltage->vddc_id);
|
||||
radeon_atom_set_voltage(rdev, voltage->vddc_id, SET_VOLTAGE_TYPE_ASIC_VDDC);
|
||||
|
||||
dyn_pwrmgt_sclk_length = RREG32_PLL(DYN_PWRMGT_SCLK_LENGTH);
|
||||
dyn_pwrmgt_sclk_length &= ~REDUCED_POWER_SCLK_HILEN(0xf);
|
||||
|
|
|
@ -106,7 +106,7 @@ void rv770_pm_misc(struct radeon_device *rdev)
|
|||
|
||||
if ((voltage->type == VOLTAGE_SW) && voltage->voltage) {
|
||||
if (voltage->voltage != rdev->pm.current_vddc) {
|
||||
radeon_atom_set_voltage(rdev, voltage->voltage);
|
||||
radeon_atom_set_voltage(rdev, voltage->voltage, SET_VOLTAGE_TYPE_ASIC_VDDC);
|
||||
rdev->pm.current_vddc = voltage->voltage;
|
||||
DRM_DEBUG("Setting: v: %d\n", voltage->voltage);
|
||||
}
|
||||
|
@ -1255,9 +1255,6 @@ int rv770_init(struct radeon_device *rdev)
|
|||
{
|
||||
int r;
|
||||
|
||||
r = radeon_dummy_page_init(rdev);
|
||||
if (r)
|
||||
return r;
|
||||
/* This don't do much */
|
||||
r = radeon_gem_init(rdev);
|
||||
if (r)
|
||||
|
@ -1372,7 +1369,6 @@ void rv770_fini(struct radeon_device *rdev)
|
|||
radeon_atombios_fini(rdev);
|
||||
kfree(rdev->bios);
|
||||
rdev->bios = NULL;
|
||||
radeon_dummy_page_fini(rdev);
|
||||
}
|
||||
|
||||
static void rv770_pcie_gen2_enable(struct radeon_device *rdev)
|
||||
|
|
|
@ -683,22 +683,14 @@ int ttm_get_pages(struct list_head *pages, int flags,
|
|||
gfp_flags |= GFP_HIGHUSER;
|
||||
|
||||
for (r = 0; r < count; ++r) {
|
||||
if ((flags & TTM_PAGE_FLAG_DMA32) && dma_address) {
|
||||
void *addr;
|
||||
addr = dma_alloc_coherent(NULL, PAGE_SIZE,
|
||||
&dma_address[r],
|
||||
gfp_flags);
|
||||
if (addr == NULL)
|
||||
return -ENOMEM;
|
||||
p = virt_to_page(addr);
|
||||
} else
|
||||
p = alloc_page(gfp_flags);
|
||||
p = alloc_page(gfp_flags);
|
||||
if (!p) {
|
||||
|
||||
printk(KERN_ERR TTM_PFX
|
||||
"Unable to allocate page.");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
list_add(&p->lru, pages);
|
||||
}
|
||||
return 0;
|
||||
|
@ -746,24 +738,12 @@ void ttm_put_pages(struct list_head *pages, unsigned page_count, int flags,
|
|||
unsigned long irq_flags;
|
||||
struct ttm_page_pool *pool = ttm_get_pool(flags, cstate);
|
||||
struct page *p, *tmp;
|
||||
unsigned r;
|
||||
|
||||
if (pool == NULL) {
|
||||
/* No pool for this memory type so free the pages */
|
||||
|
||||
r = page_count-1;
|
||||
list_for_each_entry_safe(p, tmp, pages, lru) {
|
||||
if ((flags & TTM_PAGE_FLAG_DMA32) && dma_address) {
|
||||
void *addr = page_address(p);
|
||||
WARN_ON(!addr || !dma_address[r]);
|
||||
if (addr)
|
||||
dma_free_coherent(NULL, PAGE_SIZE,
|
||||
addr,
|
||||
dma_address[r]);
|
||||
dma_address[r] = 0;
|
||||
} else
|
||||
__free_page(p);
|
||||
r--;
|
||||
__free_page(p);
|
||||
}
|
||||
/* Make the pages list empty */
|
||||
INIT_LIST_HEAD(pages);
|
||||
|
|
|
@ -5,6 +5,7 @@ config STUB_POULSBO
|
|||
# Poulsbo stub depends on ACPI_VIDEO when ACPI is enabled
|
||||
# but for select to work, need to select ACPI_VIDEO's dependencies, ick
|
||||
select BACKLIGHT_CLASS_DEVICE if ACPI
|
||||
select VIDEO_OUTPUT_CONTROL if ACPI
|
||||
select INPUT if ACPI
|
||||
select ACPI_VIDEO if ACPI
|
||||
select THERMAL if ACPI
|
||||
|
|
|
@ -55,6 +55,19 @@ int mfd_cell_disable(struct platform_device *pdev)
|
|||
}
|
||||
EXPORT_SYMBOL(mfd_cell_disable);
|
||||
|
||||
static int mfd_platform_add_cell(struct platform_device *pdev,
|
||||
const struct mfd_cell *cell)
|
||||
{
|
||||
if (!cell)
|
||||
return 0;
|
||||
|
||||
pdev->mfd_cell = kmemdup(cell, sizeof(*cell), GFP_KERNEL);
|
||||
if (!pdev->mfd_cell)
|
||||
return -ENOMEM;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mfd_add_device(struct device *parent, int id,
|
||||
const struct mfd_cell *cell,
|
||||
struct resource *mem_base,
|
||||
|
@ -75,7 +88,7 @@ static int mfd_add_device(struct device *parent, int id,
|
|||
|
||||
pdev->dev.parent = parent;
|
||||
|
||||
ret = platform_device_add_data(pdev, cell, sizeof(*cell));
|
||||
ret = mfd_platform_add_cell(pdev, cell);
|
||||
if (ret)
|
||||
goto fail_res;
|
||||
|
||||
|
@ -123,7 +136,6 @@ static int mfd_add_device(struct device *parent, int id,
|
|||
|
||||
return 0;
|
||||
|
||||
/* platform_device_del(pdev); */
|
||||
fail_res:
|
||||
kfree(res);
|
||||
fail_device:
|
||||
|
|
|
@ -154,7 +154,7 @@ struct be_eq_obj {
|
|||
u16 min_eqd; /* in usecs */
|
||||
u16 max_eqd; /* in usecs */
|
||||
u16 cur_eqd; /* in usecs */
|
||||
u8 msix_vec_idx;
|
||||
u8 eq_idx;
|
||||
|
||||
struct napi_struct napi;
|
||||
};
|
||||
|
@ -291,7 +291,7 @@ struct be_adapter {
|
|||
u32 num_rx_qs;
|
||||
u32 big_page_size; /* Compounded page size shared by rx wrbs */
|
||||
|
||||
u8 msix_vec_next_idx;
|
||||
u8 eq_next_idx;
|
||||
struct be_drv_stats drv_stats;
|
||||
|
||||
struct vlan_group *vlan_grp;
|
||||
|
|
|
@ -1497,7 +1497,7 @@ static int be_tx_queues_create(struct be_adapter *adapter)
|
|||
if (be_cmd_eq_create(adapter, eq, adapter->tx_eq.cur_eqd))
|
||||
goto tx_eq_free;
|
||||
|
||||
adapter->tx_eq.msix_vec_idx = adapter->msix_vec_next_idx++;
|
||||
adapter->tx_eq.eq_idx = adapter->eq_next_idx++;
|
||||
|
||||
|
||||
/* Alloc TX eth compl queue */
|
||||
|
@ -1590,7 +1590,7 @@ static int be_rx_queues_create(struct be_adapter *adapter)
|
|||
if (rc)
|
||||
goto err;
|
||||
|
||||
rxo->rx_eq.msix_vec_idx = adapter->msix_vec_next_idx++;
|
||||
rxo->rx_eq.eq_idx = adapter->eq_next_idx++;
|
||||
|
||||
/* CQ */
|
||||
cq = &rxo->cq;
|
||||
|
@ -1666,11 +1666,11 @@ static irqreturn_t be_intx(int irq, void *dev)
|
|||
if (!isr)
|
||||
return IRQ_NONE;
|
||||
|
||||
if ((1 << adapter->tx_eq.msix_vec_idx & isr))
|
||||
if ((1 << adapter->tx_eq.eq_idx & isr))
|
||||
event_handle(adapter, &adapter->tx_eq);
|
||||
|
||||
for_all_rx_queues(adapter, rxo, i) {
|
||||
if ((1 << rxo->rx_eq.msix_vec_idx & isr))
|
||||
if ((1 << rxo->rx_eq.eq_idx & isr))
|
||||
event_handle(adapter, &rxo->rx_eq);
|
||||
}
|
||||
}
|
||||
|
@ -1951,7 +1951,7 @@ static void be_sriov_disable(struct be_adapter *adapter)
|
|||
static inline int be_msix_vec_get(struct be_adapter *adapter,
|
||||
struct be_eq_obj *eq_obj)
|
||||
{
|
||||
return adapter->msix_entries[eq_obj->msix_vec_idx].vector;
|
||||
return adapter->msix_entries[eq_obj->eq_idx].vector;
|
||||
}
|
||||
|
||||
static int be_request_irq(struct be_adapter *adapter,
|
||||
|
@ -2345,6 +2345,7 @@ static int be_clear(struct be_adapter *adapter)
|
|||
be_mcc_queues_destroy(adapter);
|
||||
be_rx_queues_destroy(adapter);
|
||||
be_tx_queues_destroy(adapter);
|
||||
adapter->eq_next_idx = 0;
|
||||
|
||||
if (be_physfn(adapter) && adapter->sriov_enabled)
|
||||
for (vf = 0; vf < num_vfs; vf++)
|
||||
|
@ -3141,12 +3142,14 @@ static int be_resume(struct pci_dev *pdev)
|
|||
static void be_shutdown(struct pci_dev *pdev)
|
||||
{
|
||||
struct be_adapter *adapter = pci_get_drvdata(pdev);
|
||||
struct net_device *netdev = adapter->netdev;
|
||||
|
||||
if (netif_running(netdev))
|
||||
if (!adapter)
|
||||
return;
|
||||
|
||||
if (netif_running(adapter->netdev))
|
||||
cancel_delayed_work_sync(&adapter->work);
|
||||
|
||||
netif_device_detach(netdev);
|
||||
netif_device_detach(adapter->netdev);
|
||||
|
||||
be_cmd_reset_function(adapter);
|
||||
|
||||
|
|
|
@ -2219,13 +2219,9 @@ bfa_nw_ioc_get_mac(struct bfa_ioc *ioc)
|
|||
static void
|
||||
bfa_ioc_recover(struct bfa_ioc *ioc)
|
||||
{
|
||||
u16 bdf;
|
||||
|
||||
bdf = (ioc->pcidev.pci_slot << 8 | ioc->pcidev.pci_func << 3 |
|
||||
ioc->pcidev.device_id);
|
||||
|
||||
pr_crit("Firmware heartbeat failure at %d", bdf);
|
||||
BUG_ON(1);
|
||||
pr_crit("Heart Beat of IOC has failed\n");
|
||||
bfa_ioc_stats(ioc, ioc_hbfails);
|
||||
bfa_fsm_send_event(ioc, IOC_E_HBFAIL);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -931,7 +931,8 @@ static int mcp251x_open(struct net_device *net)
|
|||
priv->tx_len = 0;
|
||||
|
||||
ret = request_threaded_irq(spi->irq, NULL, mcp251x_can_ist,
|
||||
IRQF_TRIGGER_FALLING, DEVICE_NAME, priv);
|
||||
pdata->irq_flags ? pdata->irq_flags : IRQF_TRIGGER_FALLING,
|
||||
DEVICE_NAME, priv);
|
||||
if (ret) {
|
||||
dev_err(&spi->dev, "failed to acquire irq %d\n", spi->irq);
|
||||
if (pdata->transceiver_enable)
|
||||
|
|
|
@ -345,6 +345,8 @@ int mlx4_en_activate_rx_rings(struct mlx4_en_priv *priv)
|
|||
err = mlx4_en_init_allocator(priv, ring);
|
||||
if (err) {
|
||||
en_err(priv, "Failed initializing ring allocator\n");
|
||||
if (ring->stride <= TXBB_SIZE)
|
||||
ring->buf -= TXBB_SIZE;
|
||||
ring_ind--;
|
||||
goto err_allocator;
|
||||
}
|
||||
|
@ -369,6 +371,8 @@ int mlx4_en_activate_rx_rings(struct mlx4_en_priv *priv)
|
|||
ring_ind = priv->rx_ring_num - 1;
|
||||
err_allocator:
|
||||
while (ring_ind >= 0) {
|
||||
if (priv->rx_ring[ring_ind].stride <= TXBB_SIZE)
|
||||
priv->rx_ring[ring_ind].buf -= TXBB_SIZE;
|
||||
mlx4_en_destroy_allocator(priv, &priv->rx_ring[ring_ind]);
|
||||
ring_ind--;
|
||||
}
|
||||
|
|
|
@ -944,6 +944,10 @@ static int mlx4_setup_hca(struct mlx4_dev *dev)
|
|||
}
|
||||
|
||||
for (port = 1; port <= dev->caps.num_ports; port++) {
|
||||
enum mlx4_port_type port_type = 0;
|
||||
mlx4_SENSE_PORT(dev, port, &port_type);
|
||||
if (port_type)
|
||||
dev->caps.port_type[port] = port_type;
|
||||
ib_port_default_caps = 0;
|
||||
err = mlx4_get_port_ib_caps(dev, port, &ib_port_default_caps);
|
||||
if (err)
|
||||
|
@ -958,6 +962,7 @@ static int mlx4_setup_hca(struct mlx4_dev *dev)
|
|||
goto err_mcg_table_free;
|
||||
}
|
||||
}
|
||||
mlx4_set_port_mask(dev);
|
||||
|
||||
return 0;
|
||||
|
||||
|
|
|
@ -431,6 +431,8 @@ void mlx4_srq_event(struct mlx4_dev *dev, u32 srqn, int event_type);
|
|||
|
||||
void mlx4_handle_catas_err(struct mlx4_dev *dev);
|
||||
|
||||
int mlx4_SENSE_PORT(struct mlx4_dev *dev, int port,
|
||||
enum mlx4_port_type *type);
|
||||
void mlx4_do_sense_ports(struct mlx4_dev *dev,
|
||||
enum mlx4_port_type *stype,
|
||||
enum mlx4_port_type *defaults);
|
||||
|
|
|
@ -38,8 +38,8 @@
|
|||
|
||||
#include "mlx4.h"
|
||||
|
||||
static int mlx4_SENSE_PORT(struct mlx4_dev *dev, int port,
|
||||
enum mlx4_port_type *type)
|
||||
int mlx4_SENSE_PORT(struct mlx4_dev *dev, int port,
|
||||
enum mlx4_port_type *type)
|
||||
{
|
||||
u64 out_param;
|
||||
int err = 0;
|
||||
|
|
|
@ -317,7 +317,7 @@ static void pppoe_flush_dev(struct net_device *dev)
|
|||
lock_sock(sk);
|
||||
|
||||
if (po->pppoe_dev == dev &&
|
||||
sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND)) {
|
||||
sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND | PPPOX_ZOMBIE)) {
|
||||
pppox_unbind_sock(sk);
|
||||
sk->sk_state = PPPOX_ZOMBIE;
|
||||
sk->sk_state_change(sk);
|
||||
|
|
|
@ -1818,6 +1818,7 @@ static int __devinit smsc911x_init(struct net_device *dev)
|
|||
SMSC_TRACE(PROBE, "PHY will be autodetected.");
|
||||
|
||||
spin_lock_init(&pdata->dev_lock);
|
||||
spin_lock_init(&pdata->mac_lock);
|
||||
|
||||
if (pdata->ioaddr == 0) {
|
||||
SMSC_WARNING(PROBE, "pdata->ioaddr: 0x00000000");
|
||||
|
@ -1895,8 +1896,11 @@ static int __devinit smsc911x_init(struct net_device *dev)
|
|||
/* workaround for platforms without an eeprom, where the mac address
|
||||
* is stored elsewhere and set by the bootloader. This saves the
|
||||
* mac address before resetting the device */
|
||||
if (pdata->config.flags & SMSC911X_SAVE_MAC_ADDRESS)
|
||||
if (pdata->config.flags & SMSC911X_SAVE_MAC_ADDRESS) {
|
||||
spin_lock_irq(&pdata->mac_lock);
|
||||
smsc911x_read_mac_address(dev);
|
||||
spin_unlock_irq(&pdata->mac_lock);
|
||||
}
|
||||
|
||||
/* Reset the LAN911x */
|
||||
if (smsc911x_soft_reset(pdata))
|
||||
|
@ -2059,8 +2063,6 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev)
|
|||
SMSC_TRACE(PROBE, "Network interface: \"%s\"", dev->name);
|
||||
}
|
||||
|
||||
spin_lock_init(&pdata->mac_lock);
|
||||
|
||||
retval = smsc911x_mii_init(pdev, dev);
|
||||
if (retval) {
|
||||
SMSC_WARNING(PROBE,
|
||||
|
|
|
@ -1313,6 +1313,21 @@ static const struct usb_device_id products[] = {
|
|||
USB_DEVICE(0x0424, 0x9909),
|
||||
.driver_info = (unsigned long) &smsc95xx_info,
|
||||
},
|
||||
{
|
||||
/* SMSC LAN9530 USB Ethernet Device */
|
||||
USB_DEVICE(0x0424, 0x9530),
|
||||
.driver_info = (unsigned long) &smsc95xx_info,
|
||||
},
|
||||
{
|
||||
/* SMSC LAN9730 USB Ethernet Device */
|
||||
USB_DEVICE(0x0424, 0x9730),
|
||||
.driver_info = (unsigned long) &smsc95xx_info,
|
||||
},
|
||||
{
|
||||
/* SMSC LAN89530 USB Ethernet Device */
|
||||
USB_DEVICE(0x0424, 0x9E08),
|
||||
.driver_info = (unsigned long) &smsc95xx_info,
|
||||
},
|
||||
{ }, /* END */
|
||||
};
|
||||
MODULE_DEVICE_TABLE(usb, products);
|
||||
|
|
|
@ -2546,6 +2546,7 @@ static struct {
|
|||
{ AR_SREV_VERSION_9287, "9287" },
|
||||
{ AR_SREV_VERSION_9271, "9271" },
|
||||
{ AR_SREV_VERSION_9300, "9300" },
|
||||
{ AR_SREV_VERSION_9485, "9485" },
|
||||
};
|
||||
|
||||
/* For devices with external radios */
|
||||
|
|
|
@ -1536,7 +1536,7 @@ static void dma_rx(struct b43_dmaring *ring, int *slot)
|
|||
dmaaddr = meta->dmaaddr;
|
||||
goto drop_recycle_buffer;
|
||||
}
|
||||
if (unlikely(len > ring->rx_buffersize)) {
|
||||
if (unlikely(len + ring->frameoffset > ring->rx_buffersize)) {
|
||||
/* The data did not fit into one descriptor buffer
|
||||
* and is split over multiple buffers.
|
||||
* This should never happen, as we try to allocate buffers
|
||||
|
|
|
@ -163,7 +163,7 @@ struct b43_dmadesc_generic {
|
|||
/* DMA engine tuning knobs */
|
||||
#define B43_TXRING_SLOTS 256
|
||||
#define B43_RXRING_SLOTS 64
|
||||
#define B43_DMA0_RX_BUFFERSIZE IEEE80211_MAX_FRAME_LEN
|
||||
#define B43_DMA0_RX_BUFFERSIZE (B43_DMA0_RX_FRAMEOFFSET + IEEE80211_MAX_FRAME_LEN)
|
||||
|
||||
/* Pointer poison */
|
||||
#define B43_DMA_PTR_POISON ((void *)ERR_PTR(-ENOMEM))
|
||||
|
|
|
@ -241,7 +241,7 @@ struct iwl_eeprom_enhanced_txpwr {
|
|||
|
||||
/* 6x00 Specific */
|
||||
#define EEPROM_6000_TX_POWER_VERSION (4)
|
||||
#define EEPROM_6000_EEPROM_VERSION (0x434)
|
||||
#define EEPROM_6000_EEPROM_VERSION (0x423)
|
||||
|
||||
/* 6x50 Specific */
|
||||
#define EEPROM_6050_TX_POWER_VERSION (4)
|
||||
|
|
|
@ -56,6 +56,7 @@ static struct usb_device_id p54u_table[] __devinitdata = {
|
|||
{USB_DEVICE(0x0846, 0x4210)}, /* Netgear WG121 the second ? */
|
||||
{USB_DEVICE(0x0846, 0x4220)}, /* Netgear WG111 */
|
||||
{USB_DEVICE(0x09aa, 0x1000)}, /* Spinnaker Proto board */
|
||||
{USB_DEVICE(0x0bf8, 0x1007)}, /* Fujitsu E-5400 USB */
|
||||
{USB_DEVICE(0x0cde, 0x0006)}, /* Medion 40900, Roper Europe */
|
||||
{USB_DEVICE(0x0db0, 0x6826)}, /* MSI UB54G (MS-6826) */
|
||||
{USB_DEVICE(0x107b, 0x55f2)}, /* Gateway WGU-210 (Gemtek) */
|
||||
|
@ -68,6 +69,7 @@ static struct usb_device_id p54u_table[] __devinitdata = {
|
|||
{USB_DEVICE(0x1915, 0x2235)}, /* Linksys WUSB54G Portable OEM */
|
||||
{USB_DEVICE(0x2001, 0x3701)}, /* DLink DWL-G120 Spinnaker */
|
||||
{USB_DEVICE(0x2001, 0x3703)}, /* DLink DWL-G122 */
|
||||
{USB_DEVICE(0x2001, 0x3762)}, /* Conceptronic C54U */
|
||||
{USB_DEVICE(0x5041, 0x2234)}, /* Linksys WUSB54G */
|
||||
{USB_DEVICE(0x5041, 0x2235)}, /* Linksys WUSB54G Portable */
|
||||
|
||||
|
|
|
@ -1062,8 +1062,10 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev)
|
|||
* Stop all work.
|
||||
*/
|
||||
cancel_work_sync(&rt2x00dev->intf_work);
|
||||
cancel_work_sync(&rt2x00dev->rxdone_work);
|
||||
cancel_work_sync(&rt2x00dev->txdone_work);
|
||||
if (rt2x00_is_usb(rt2x00dev)) {
|
||||
cancel_work_sync(&rt2x00dev->rxdone_work);
|
||||
cancel_work_sync(&rt2x00dev->txdone_work);
|
||||
}
|
||||
destroy_workqueue(rt2x00dev->workqueue);
|
||||
|
||||
/*
|
||||
|
|
|
@ -685,7 +685,7 @@ static int efuse_pg_packet_read(struct ieee80211_hw *hw, u8 offset, u8 *data)
|
|||
|
||||
u8 efuse_data, word_cnts = 0;
|
||||
u16 efuse_addr = 0;
|
||||
u8 hworden;
|
||||
u8 hworden = 0;
|
||||
u8 tmpdata[8];
|
||||
|
||||
if (data == NULL)
|
||||
|
|
|
@ -303,7 +303,7 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw,
|
|||
u16 box_reg, box_extreg;
|
||||
u8 u1b_tmp;
|
||||
bool isfw_read = false;
|
||||
u8 buf_index;
|
||||
u8 buf_index = 0;
|
||||
bool bwrite_sucess = false;
|
||||
u8 wait_h2c_limmit = 100;
|
||||
u8 wait_writeh2c_limmit = 100;
|
||||
|
|
|
@ -246,7 +246,7 @@ static void _rtl_usb_io_handler_init(struct device *dev,
|
|||
|
||||
static void _rtl_usb_io_handler_release(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_priv __maybe_unused *rtlpriv = rtl_priv(hw);
|
||||
|
||||
mutex_destroy(&rtlpriv->io.bb_mutex);
|
||||
}
|
||||
|
|
|
@ -340,7 +340,7 @@ module_init(wl1271_init);
|
|||
module_exit(wl1271_exit);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Luciano Coelho <luciano.coelho@nokia.com>");
|
||||
MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>");
|
||||
MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>");
|
||||
MODULE_FIRMWARE(WL1271_FW_NAME);
|
||||
MODULE_FIRMWARE(WL1271_AP_FW_NAME);
|
||||
|
|
|
@ -487,7 +487,7 @@ module_init(wl1271_init);
|
|||
module_exit(wl1271_exit);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Luciano Coelho <luciano.coelho@nokia.com>");
|
||||
MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>");
|
||||
MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>");
|
||||
MODULE_FIRMWARE(WL1271_FW_NAME);
|
||||
MODULE_FIRMWARE(WL1271_AP_FW_NAME);
|
||||
|
|
|
@ -204,7 +204,10 @@ static int wl1271_tm_cmd_nvs_push(struct wl1271 *wl, struct nlattr *tb[])
|
|||
|
||||
kfree(wl->nvs);
|
||||
|
||||
wl->nvs = kzalloc(sizeof(struct wl1271_nvs_file), GFP_KERNEL);
|
||||
if (len != sizeof(struct wl1271_nvs_file))
|
||||
return -EINVAL;
|
||||
|
||||
wl->nvs = kzalloc(len, GFP_KERNEL);
|
||||
if (!wl->nvs) {
|
||||
wl1271_error("could not allocate memory for the nvs file");
|
||||
ret = -ENOMEM;
|
||||
|
|
|
@ -643,7 +643,7 @@ static void rx_urb_complete(struct urb *urb)
|
|||
usb = urb->context;
|
||||
rx = &usb->rx;
|
||||
|
||||
zd_usb_reset_rx_idle_timer(usb);
|
||||
tasklet_schedule(&rx->reset_timer_tasklet);
|
||||
|
||||
if (length%rx->usb_packet_size > rx->usb_packet_size-4) {
|
||||
/* If there is an old first fragment, we don't care. */
|
||||
|
@ -812,6 +812,7 @@ void zd_usb_disable_rx(struct zd_usb *usb)
|
|||
__zd_usb_disable_rx(usb);
|
||||
mutex_unlock(&rx->setup_mutex);
|
||||
|
||||
tasklet_kill(&rx->reset_timer_tasklet);
|
||||
cancel_delayed_work_sync(&rx->idle_work);
|
||||
}
|
||||
|
||||
|
@ -1106,6 +1107,13 @@ static void zd_rx_idle_timer_handler(struct work_struct *work)
|
|||
zd_usb_reset_rx(usb);
|
||||
}
|
||||
|
||||
static void zd_usb_reset_rx_idle_timer_tasklet(unsigned long param)
|
||||
{
|
||||
struct zd_usb *usb = (struct zd_usb *)param;
|
||||
|
||||
zd_usb_reset_rx_idle_timer(usb);
|
||||
}
|
||||
|
||||
void zd_usb_reset_rx_idle_timer(struct zd_usb *usb)
|
||||
{
|
||||
struct zd_usb_rx *rx = &usb->rx;
|
||||
|
@ -1127,6 +1135,7 @@ static inline void init_usb_interrupt(struct zd_usb *usb)
|
|||
static inline void init_usb_rx(struct zd_usb *usb)
|
||||
{
|
||||
struct zd_usb_rx *rx = &usb->rx;
|
||||
|
||||
spin_lock_init(&rx->lock);
|
||||
mutex_init(&rx->setup_mutex);
|
||||
if (interface_to_usbdev(usb->intf)->speed == USB_SPEED_HIGH) {
|
||||
|
@ -1136,11 +1145,14 @@ static inline void init_usb_rx(struct zd_usb *usb)
|
|||
}
|
||||
ZD_ASSERT(rx->fragment_length == 0);
|
||||
INIT_DELAYED_WORK(&rx->idle_work, zd_rx_idle_timer_handler);
|
||||
rx->reset_timer_tasklet.func = zd_usb_reset_rx_idle_timer_tasklet;
|
||||
rx->reset_timer_tasklet.data = (unsigned long)usb;
|
||||
}
|
||||
|
||||
static inline void init_usb_tx(struct zd_usb *usb)
|
||||
{
|
||||
struct zd_usb_tx *tx = &usb->tx;
|
||||
|
||||
spin_lock_init(&tx->lock);
|
||||
atomic_set(&tx->enabled, 0);
|
||||
tx->stopped = 0;
|
||||
|
@ -1671,6 +1683,10 @@ static void iowrite16v_urb_complete(struct urb *urb)
|
|||
|
||||
if (urb->status && !usb->cmd_error)
|
||||
usb->cmd_error = urb->status;
|
||||
|
||||
if (!usb->cmd_error &&
|
||||
urb->actual_length != urb->transfer_buffer_length)
|
||||
usb->cmd_error = -EIO;
|
||||
}
|
||||
|
||||
static int zd_submit_waiting_urb(struct zd_usb *usb, bool last)
|
||||
|
@ -1805,7 +1821,7 @@ int zd_usb_iowrite16v_async(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs,
|
|||
usb_fill_int_urb(urb, udev, usb_sndintpipe(udev, EP_REGS_OUT),
|
||||
req, req_len, iowrite16v_urb_complete, usb,
|
||||
ep->desc.bInterval);
|
||||
urb->transfer_flags |= URB_FREE_BUFFER | URB_SHORT_NOT_OK;
|
||||
urb->transfer_flags |= URB_FREE_BUFFER;
|
||||
|
||||
/* Submit previous URB */
|
||||
r = zd_submit_waiting_urb(usb, false);
|
||||
|
|
|
@ -183,6 +183,7 @@ struct zd_usb_rx {
|
|||
spinlock_t lock;
|
||||
struct mutex setup_mutex;
|
||||
struct delayed_work idle_work;
|
||||
struct tasklet_struct reset_timer_tasklet;
|
||||
u8 fragment[2 * USB_MAX_RX_SIZE];
|
||||
unsigned int fragment_length;
|
||||
unsigned int usb_packet_size;
|
||||
|
|
|
@ -781,7 +781,7 @@ static int pci_pm_resume(struct device *dev)
|
|||
|
||||
#endif /* !CONFIG_SUSPEND */
|
||||
|
||||
#ifdef CONFIG_HIBERNATION
|
||||
#ifdef CONFIG_HIBERNATE_CALLBACKS
|
||||
|
||||
static int pci_pm_freeze(struct device *dev)
|
||||
{
|
||||
|
@ -970,7 +970,7 @@ static int pci_pm_restore(struct device *dev)
|
|||
return error;
|
||||
}
|
||||
|
||||
#else /* !CONFIG_HIBERNATION */
|
||||
#else /* !CONFIG_HIBERNATE_CALLBACKS */
|
||||
|
||||
#define pci_pm_freeze NULL
|
||||
#define pci_pm_freeze_noirq NULL
|
||||
|
@ -981,7 +981,7 @@ static int pci_pm_restore(struct device *dev)
|
|||
#define pci_pm_restore NULL
|
||||
#define pci_pm_restore_noirq NULL
|
||||
|
||||
#endif /* !CONFIG_HIBERNATION */
|
||||
#endif /* !CONFIG_HIBERNATE_CALLBACKS */
|
||||
|
||||
#ifdef CONFIG_PM_RUNTIME
|
||||
|
||||
|
|
|
@ -676,10 +676,10 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
|
|||
min_align = align1 >> 1;
|
||||
align += aligns[order];
|
||||
}
|
||||
size0 = calculate_memsize(size, min_size, 0, resource_size(b_res), align);
|
||||
size0 = calculate_memsize(size, min_size, 0, resource_size(b_res), min_align);
|
||||
size1 = !add_size ? size :
|
||||
calculate_memsize(size, min_size+add_size, 0,
|
||||
resource_size(b_res), align);
|
||||
resource_size(b_res), min_align);
|
||||
if (!size0 && !size1) {
|
||||
if (b_res->start || b_res->end)
|
||||
dev_info(&bus->self->dev, "disabling bridge window "
|
||||
|
|
|
@ -187,7 +187,8 @@ config MSI_LAPTOP
|
|||
depends on ACPI
|
||||
depends on BACKLIGHT_CLASS_DEVICE
|
||||
depends on RFKILL
|
||||
depends on SERIO_I8042
|
||||
depends on INPUT && SERIO_I8042
|
||||
select INPUT_SPARSEKMAP
|
||||
---help---
|
||||
This is a driver for laptops built by MSI (MICRO-STAR
|
||||
INTERNATIONAL):
|
||||
|
|
|
@ -89,7 +89,7 @@ MODULE_LICENSE("GPL");
|
|||
#define ACERWMID_EVENT_GUID "676AA15E-6A47-4D9F-A2CC-1E6D18D14026"
|
||||
|
||||
MODULE_ALIAS("wmi:67C3371D-95A3-4C37-BB61-DD47B491DAAB");
|
||||
MODULE_ALIAS("wmi:6AF4F258-B401-42Fd-BE91-3D4AC2D7C0D3");
|
||||
MODULE_ALIAS("wmi:6AF4F258-B401-42FD-BE91-3D4AC2D7C0D3");
|
||||
MODULE_ALIAS("wmi:676AA15E-6A47-4D9F-A2CC-1E6D18D14026");
|
||||
|
||||
enum acer_wmi_event_ids {
|
||||
|
|
|
@ -201,8 +201,8 @@ static int asus_wmi_input_init(struct asus_wmi *asus)
|
|||
if (!asus->inputdev)
|
||||
return -ENOMEM;
|
||||
|
||||
asus->inputdev->name = asus->driver->input_phys;
|
||||
asus->inputdev->phys = asus->driver->input_name;
|
||||
asus->inputdev->name = asus->driver->input_name;
|
||||
asus->inputdev->phys = asus->driver->input_phys;
|
||||
asus->inputdev->id.bustype = BUS_HOST;
|
||||
asus->inputdev->dev.parent = &asus->platform_device->dev;
|
||||
|
||||
|
|
|
@ -67,9 +67,11 @@ static const struct key_entry eeepc_wmi_keymap[] = {
|
|||
{ KE_KEY, 0x82, { KEY_CAMERA } },
|
||||
{ KE_KEY, 0x83, { KEY_CAMERA_ZOOMIN } },
|
||||
{ KE_KEY, 0x88, { KEY_WLAN } },
|
||||
{ KE_KEY, 0xbd, { KEY_CAMERA } },
|
||||
{ KE_KEY, 0xcc, { KEY_SWITCHVIDEOMODE } },
|
||||
{ KE_KEY, 0xe0, { KEY_PROG1 } }, /* Task Manager */
|
||||
{ KE_KEY, 0xe1, { KEY_F14 } }, /* Change Resolution */
|
||||
{ KE_KEY, 0xe8, { KEY_SCREENLOCK } },
|
||||
{ KE_KEY, 0xe9, { KEY_BRIGHTNESS_ZERO } },
|
||||
{ KE_KEY, 0xeb, { KEY_CAMERA_ZOOMOUT } },
|
||||
{ KE_KEY, 0xec, { KEY_CAMERA_UP } },
|
||||
|
|
|
@ -74,6 +74,19 @@ struct pmic_gpio {
|
|||
u32 trigger_type;
|
||||
};
|
||||
|
||||
static void pmic_program_irqtype(int gpio, int type)
|
||||
{
|
||||
if (type & IRQ_TYPE_EDGE_RISING)
|
||||
intel_scu_ipc_update_register(GPIO0 + gpio, 0x20, 0x20);
|
||||
else
|
||||
intel_scu_ipc_update_register(GPIO0 + gpio, 0x00, 0x20);
|
||||
|
||||
if (type & IRQ_TYPE_EDGE_FALLING)
|
||||
intel_scu_ipc_update_register(GPIO0 + gpio, 0x10, 0x10);
|
||||
else
|
||||
intel_scu_ipc_update_register(GPIO0 + gpio, 0x00, 0x10);
|
||||
};
|
||||
|
||||
static int pmic_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
|
||||
{
|
||||
if (offset > 8) {
|
||||
|
@ -166,16 +179,38 @@ static int pmic_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
|
|||
return pg->irq_base + offset;
|
||||
}
|
||||
|
||||
static void pmic_bus_lock(struct irq_data *data)
|
||||
{
|
||||
struct pmic_gpio *pg = irq_data_get_irq_chip_data(data);
|
||||
|
||||
mutex_lock(&pg->buslock);
|
||||
}
|
||||
|
||||
static void pmic_bus_sync_unlock(struct irq_data *data)
|
||||
{
|
||||
struct pmic_gpio *pg = irq_data_get_irq_chip_data(data);
|
||||
|
||||
if (pg->update_type) {
|
||||
unsigned int gpio = pg->update_type & ~GPIO_UPDATE_TYPE;
|
||||
|
||||
pmic_program_irqtype(gpio, pg->trigger_type);
|
||||
pg->update_type = 0;
|
||||
}
|
||||
mutex_unlock(&pg->buslock);
|
||||
}
|
||||
|
||||
/* the gpiointr register is read-clear, so just do nothing. */
|
||||
static void pmic_irq_unmask(struct irq_data *data) { }
|
||||
|
||||
static void pmic_irq_mask(struct irq_data *data) { }
|
||||
|
||||
static struct irq_chip pmic_irqchip = {
|
||||
.name = "PMIC-GPIO",
|
||||
.irq_mask = pmic_irq_mask,
|
||||
.irq_unmask = pmic_irq_unmask,
|
||||
.irq_set_type = pmic_irq_type,
|
||||
.name = "PMIC-GPIO",
|
||||
.irq_mask = pmic_irq_mask,
|
||||
.irq_unmask = pmic_irq_unmask,
|
||||
.irq_set_type = pmic_irq_type,
|
||||
.irq_bus_lock = pmic_bus_lock,
|
||||
.irq_bus_sync_unlock = pmic_bus_sync_unlock,
|
||||
};
|
||||
|
||||
static irqreturn_t pmic_irq_handler(int irq, void *data)
|
||||
|
|
|
@ -570,6 +570,16 @@ static struct dmi_system_id __initdata samsung_dmi_table[] = {
|
|||
},
|
||||
.callback = dmi_check_cb,
|
||||
},
|
||||
{
|
||||
.ident = "R410 Plus",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR,
|
||||
"SAMSUNG ELECTRONICS CO., LTD."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "R410P"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "R460"),
|
||||
},
|
||||
.callback = dmi_check_cb,
|
||||
},
|
||||
{
|
||||
.ident = "R518",
|
||||
.matches = {
|
||||
|
@ -591,12 +601,12 @@ static struct dmi_system_id __initdata samsung_dmi_table[] = {
|
|||
.callback = dmi_check_cb,
|
||||
},
|
||||
{
|
||||
.ident = "N150/N210/N220",
|
||||
.ident = "N150/N210/N220/N230",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR,
|
||||
"SAMSUNG ELECTRONICS CO., LTD."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "N150/N210/N220"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "N150/N210/N220"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "N150/N210/N220/N230"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "N150/N210/N220/N230"),
|
||||
},
|
||||
.callback = dmi_check_cb,
|
||||
},
|
||||
|
@ -771,6 +781,7 @@ static int __init samsung_init(void)
|
|||
|
||||
/* create a backlight device to talk to this one */
|
||||
memset(&props, 0, sizeof(struct backlight_properties));
|
||||
props.type = BACKLIGHT_PLATFORM;
|
||||
props.max_brightness = sabi_config->max_brightness;
|
||||
backlight_device = backlight_device_register("samsung", &sdev->dev,
|
||||
NULL, &backlight_ops,
|
||||
|
|
|
@ -138,6 +138,8 @@ MODULE_PARM_DESC(kbd_backlight_timeout,
|
|||
"1 for 30 seconds, 2 for 60 seconds and 3 to disable timeout "
|
||||
"(default: 0)");
|
||||
|
||||
static void sony_nc_kbd_backlight_resume(void);
|
||||
|
||||
enum sony_nc_rfkill {
|
||||
SONY_WIFI,
|
||||
SONY_BLUETOOTH,
|
||||
|
@ -771,11 +773,6 @@ static int sony_nc_handles_setup(struct platform_device *pd)
|
|||
if (!handles)
|
||||
return -ENOMEM;
|
||||
|
||||
sysfs_attr_init(&handles->devattr.attr);
|
||||
handles->devattr.attr.name = "handles";
|
||||
handles->devattr.attr.mode = S_IRUGO;
|
||||
handles->devattr.show = sony_nc_handles_show;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(handles->cap); i++) {
|
||||
if (!acpi_callsetfunc(sony_nc_acpi_handle,
|
||||
"SN00", i + 0x20, &result)) {
|
||||
|
@ -785,11 +782,18 @@ static int sony_nc_handles_setup(struct platform_device *pd)
|
|||
}
|
||||
}
|
||||
|
||||
/* allow reading capabilities via sysfs */
|
||||
if (device_create_file(&pd->dev, &handles->devattr)) {
|
||||
kfree(handles);
|
||||
handles = NULL;
|
||||
return -1;
|
||||
if (debug) {
|
||||
sysfs_attr_init(&handles->devattr.attr);
|
||||
handles->devattr.attr.name = "handles";
|
||||
handles->devattr.attr.mode = S_IRUGO;
|
||||
handles->devattr.show = sony_nc_handles_show;
|
||||
|
||||
/* allow reading capabilities via sysfs */
|
||||
if (device_create_file(&pd->dev, &handles->devattr)) {
|
||||
kfree(handles);
|
||||
handles = NULL;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -798,7 +802,8 @@ static int sony_nc_handles_setup(struct platform_device *pd)
|
|||
static int sony_nc_handles_cleanup(struct platform_device *pd)
|
||||
{
|
||||
if (handles) {
|
||||
device_remove_file(&pd->dev, &handles->devattr);
|
||||
if (debug)
|
||||
device_remove_file(&pd->dev, &handles->devattr);
|
||||
kfree(handles);
|
||||
handles = NULL;
|
||||
}
|
||||
|
@ -808,6 +813,11 @@ static int sony_nc_handles_cleanup(struct platform_device *pd)
|
|||
static int sony_find_snc_handle(int handle)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* not initialized yet, return early */
|
||||
if (!handles)
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < 0x10; i++) {
|
||||
if (handles->cap[i] == handle) {
|
||||
dprintk("found handle 0x%.4x (offset: 0x%.2x)\n",
|
||||
|
@ -1168,6 +1178,9 @@ static int sony_nc_resume(struct acpi_device *device)
|
|||
/* re-read rfkill state */
|
||||
sony_nc_rfkill_update();
|
||||
|
||||
/* restore kbd backlight states */
|
||||
sony_nc_kbd_backlight_resume();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1355,6 +1368,7 @@ static void sony_nc_rfkill_setup(struct acpi_device *device)
|
|||
#define KBDBL_HANDLER 0x137
|
||||
#define KBDBL_PRESENT 0xB00
|
||||
#define SET_MODE 0xC00
|
||||
#define SET_STATE 0xD00
|
||||
#define SET_TIMEOUT 0xE00
|
||||
|
||||
struct kbd_backlight {
|
||||
|
@ -1377,6 +1391,10 @@ static ssize_t __sony_nc_kbd_backlight_mode_set(u8 value)
|
|||
(value << 0x10) | SET_MODE, &result))
|
||||
return -EIO;
|
||||
|
||||
/* Try to turn the light on/off immediately */
|
||||
sony_call_snc_handle(KBDBL_HANDLER, (value << 0x10) | SET_STATE,
|
||||
&result);
|
||||
|
||||
kbdbl_handle->mode = value;
|
||||
|
||||
return 0;
|
||||
|
@ -1458,7 +1476,7 @@ static int sony_nc_kbd_backlight_setup(struct platform_device *pd)
|
|||
{
|
||||
int result;
|
||||
|
||||
if (sony_call_snc_handle(0x137, KBDBL_PRESENT, &result))
|
||||
if (sony_call_snc_handle(KBDBL_HANDLER, KBDBL_PRESENT, &result))
|
||||
return 0;
|
||||
if (!(result & 0x02))
|
||||
return 0;
|
||||
|
@ -1501,13 +1519,36 @@ static int sony_nc_kbd_backlight_setup(struct platform_device *pd)
|
|||
static int sony_nc_kbd_backlight_cleanup(struct platform_device *pd)
|
||||
{
|
||||
if (kbdbl_handle) {
|
||||
int result;
|
||||
|
||||
device_remove_file(&pd->dev, &kbdbl_handle->mode_attr);
|
||||
device_remove_file(&pd->dev, &kbdbl_handle->timeout_attr);
|
||||
|
||||
/* restore the default hw behaviour */
|
||||
sony_call_snc_handle(KBDBL_HANDLER, 0x1000 | SET_MODE, &result);
|
||||
sony_call_snc_handle(KBDBL_HANDLER, SET_TIMEOUT, &result);
|
||||
|
||||
kfree(kbdbl_handle);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sony_nc_kbd_backlight_resume(void)
|
||||
{
|
||||
int ignore = 0;
|
||||
|
||||
if (!kbdbl_handle)
|
||||
return;
|
||||
|
||||
if (kbdbl_handle->mode == 0)
|
||||
sony_call_snc_handle(KBDBL_HANDLER, SET_MODE, &ignore);
|
||||
|
||||
if (kbdbl_handle->timeout != 0)
|
||||
sony_call_snc_handle(KBDBL_HANDLER,
|
||||
(kbdbl_handle->timeout << 0x10) | SET_TIMEOUT,
|
||||
&ignore);
|
||||
}
|
||||
|
||||
static void sony_nc_backlight_setup(void)
|
||||
{
|
||||
acpi_handle unused;
|
||||
|
|
|
@ -8618,8 +8618,7 @@ static bool __pure __init tpacpi_is_valid_fw_id(const char* const s,
|
|||
tpacpi_is_fw_digit(s[1]) &&
|
||||
s[2] == t && s[3] == 'T' &&
|
||||
tpacpi_is_fw_digit(s[4]) &&
|
||||
tpacpi_is_fw_digit(s[5]) &&
|
||||
s[6] == 'W' && s[7] == 'W';
|
||||
tpacpi_is_fw_digit(s[5]);
|
||||
}
|
||||
|
||||
/* returns 0 - probe ok, or < 0 - probe error.
|
||||
|
|
|
@ -1555,7 +1555,7 @@ static int stop_queue(struct pl022 *pl022)
|
|||
* A wait_queue on the pl022->busy could be used, but then the common
|
||||
* execution path (pump_messages) would be required to call wake_up or
|
||||
* friends on every SPI message. Do this instead */
|
||||
while (!list_empty(&pl022->queue) && pl022->busy && limit--) {
|
||||
while ((!list_empty(&pl022->queue) || pl022->busy) && limit--) {
|
||||
spin_unlock_irqrestore(&pl022->queue_lock, flags);
|
||||
msleep(10);
|
||||
spin_lock_irqsave(&pl022->queue_lock, flags);
|
||||
|
|
|
@ -821,7 +821,7 @@ static int stop_queue(struct dw_spi *dws)
|
|||
|
||||
spin_lock_irqsave(&dws->lock, flags);
|
||||
dws->run = QUEUE_STOPPED;
|
||||
while (!list_empty(&dws->queue) && dws->busy && limit--) {
|
||||
while ((!list_empty(&dws->queue) || dws->busy) && limit--) {
|
||||
spin_unlock_irqrestore(&dws->lock, flags);
|
||||
msleep(10);
|
||||
spin_lock_irqsave(&dws->lock, flags);
|
||||
|
|
|
@ -1493,7 +1493,7 @@ static int stop_queue(struct driver_data *drv_data)
|
|||
* execution path (pump_messages) would be required to call wake_up or
|
||||
* friends on every SPI message. Do this instead */
|
||||
drv_data->run = QUEUE_STOPPED;
|
||||
while (!list_empty(&drv_data->queue) && drv_data->busy && limit--) {
|
||||
while ((!list_empty(&drv_data->queue) || drv_data->busy) && limit--) {
|
||||
spin_unlock_irqrestore(&drv_data->lock, flags);
|
||||
msleep(10);
|
||||
spin_lock_irqsave(&drv_data->lock, flags);
|
||||
|
|
|
@ -1284,7 +1284,7 @@ static inline int bfin_spi_stop_queue(struct bfin_spi_master_data *drv_data)
|
|||
* friends on every SPI message. Do this instead
|
||||
*/
|
||||
drv_data->running = false;
|
||||
while (!list_empty(&drv_data->queue) && drv_data->busy && limit--) {
|
||||
while ((!list_empty(&drv_data->queue) || drv_data->busy) && limit--) {
|
||||
spin_unlock_irqrestore(&drv_data->lock, flags);
|
||||
msleep(10);
|
||||
spin_lock_irqsave(&drv_data->lock, flags);
|
||||
|
|
|
@ -131,8 +131,6 @@ source "drivers/staging/wlags49_h2/Kconfig"
|
|||
|
||||
source "drivers/staging/wlags49_h25/Kconfig"
|
||||
|
||||
source "drivers/staging/samsung-laptop/Kconfig"
|
||||
|
||||
source "drivers/staging/sm7xx/Kconfig"
|
||||
|
||||
source "drivers/staging/dt3155v4l/Kconfig"
|
||||
|
|
|
@ -48,7 +48,6 @@ obj-$(CONFIG_XVMALLOC) += zram/
|
|||
obj-$(CONFIG_ZCACHE) += zcache/
|
||||
obj-$(CONFIG_WLAGS49_H2) += wlags49_h2/
|
||||
obj-$(CONFIG_WLAGS49_H25) += wlags49_h25/
|
||||
obj-$(CONFIG_SAMSUNG_LAPTOP) += samsung-laptop/
|
||||
obj-$(CONFIG_FB_SM7XX) += sm7xx/
|
||||
obj-$(CONFIG_VIDEO_DT3155) += dt3155v4l/
|
||||
obj-$(CONFIG_CRYSTALHD) += crystalhd/
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
config SAMSUNG_LAPTOP
|
||||
tristate "Samsung Laptop driver"
|
||||
default n
|
||||
depends on RFKILL && BACKLIGHT_CLASS_DEVICE && X86
|
||||
help
|
||||
This module implements a driver for the N128 Samsung Laptop
|
||||
providing control over the Wireless LED and the LCD backlight
|
||||
|
||||
To compile this driver as a module, choose
|
||||
M here: the module will be called samsung-laptop.
|
|
@ -1 +0,0 @@
|
|||
obj-$(CONFIG_SAMSUNG_LAPTOP) += samsung-laptop.o
|
|
@ -1,5 +0,0 @@
|
|||
TODO:
|
||||
- review from other developers
|
||||
- figure out ACPI video issues
|
||||
|
||||
Please send patches to Greg Kroah-Hartman <gregkh@suse.de>
|
|
@ -1,843 +0,0 @@
|
|||
/*
|
||||
* Samsung Laptop driver
|
||||
*
|
||||
* Copyright (C) 2009,2011 Greg Kroah-Hartman (gregkh@suse.de)
|
||||
* Copyright (C) 2009,2011 Novell Inc.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/backlight.h>
|
||||
#include <linux/fb.h>
|
||||
#include <linux/dmi.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/rfkill.h>
|
||||
|
||||
/*
|
||||
* This driver is needed because a number of Samsung laptops do not hook
|
||||
* their control settings through ACPI. So we have to poke around in the
|
||||
* BIOS to do things like brightness values, and "special" key controls.
|
||||
*/
|
||||
|
||||
/*
|
||||
* We have 0 - 8 as valid brightness levels. The specs say that level 0 should
|
||||
* be reserved by the BIOS (which really doesn't make much sense), we tell
|
||||
* userspace that the value is 0 - 7 and then just tell the hardware 1 - 8
|
||||
*/
|
||||
#define MAX_BRIGHT 0x07
|
||||
|
||||
|
||||
#define SABI_IFACE_MAIN 0x00
|
||||
#define SABI_IFACE_SUB 0x02
|
||||
#define SABI_IFACE_COMPLETE 0x04
|
||||
#define SABI_IFACE_DATA 0x05
|
||||
|
||||
/* Structure to get data back to the calling function */
|
||||
struct sabi_retval {
|
||||
u8 retval[20];
|
||||
};
|
||||
|
||||
struct sabi_header_offsets {
|
||||
u8 port;
|
||||
u8 re_mem;
|
||||
u8 iface_func;
|
||||
u8 en_mem;
|
||||
u8 data_offset;
|
||||
u8 data_segment;
|
||||
};
|
||||
|
||||
struct sabi_commands {
|
||||
/*
|
||||
* Brightness is 0 - 8, as described above.
|
||||
* Value 0 is for the BIOS to use
|
||||
*/
|
||||
u8 get_brightness;
|
||||
u8 set_brightness;
|
||||
|
||||
/*
|
||||
* first byte:
|
||||
* 0x00 - wireless is off
|
||||
* 0x01 - wireless is on
|
||||
* second byte:
|
||||
* 0x02 - 3G is off
|
||||
* 0x03 - 3G is on
|
||||
* TODO, verify 3G is correct, that doesn't seem right...
|
||||
*/
|
||||
u8 get_wireless_button;
|
||||
u8 set_wireless_button;
|
||||
|
||||
/* 0 is off, 1 is on */
|
||||
u8 get_backlight;
|
||||
u8 set_backlight;
|
||||
|
||||
/*
|
||||
* 0x80 or 0x00 - no action
|
||||
* 0x81 - recovery key pressed
|
||||
*/
|
||||
u8 get_recovery_mode;
|
||||
u8 set_recovery_mode;
|
||||
|
||||
/*
|
||||
* on seclinux: 0 is low, 1 is high,
|
||||
* on swsmi: 0 is normal, 1 is silent, 2 is turbo
|
||||
*/
|
||||
u8 get_performance_level;
|
||||
u8 set_performance_level;
|
||||
|
||||
/*
|
||||
* Tell the BIOS that Linux is running on this machine.
|
||||
* 81 is on, 80 is off
|
||||
*/
|
||||
u8 set_linux;
|
||||
};
|
||||
|
||||
struct sabi_performance_level {
|
||||
const char *name;
|
||||
u8 value;
|
||||
};
|
||||
|
||||
struct sabi_config {
|
||||
const char *test_string;
|
||||
u16 main_function;
|
||||
const struct sabi_header_offsets header_offsets;
|
||||
const struct sabi_commands commands;
|
||||
const struct sabi_performance_level performance_levels[4];
|
||||
u8 min_brightness;
|
||||
u8 max_brightness;
|
||||
};
|
||||
|
||||
static const struct sabi_config sabi_configs[] = {
|
||||
{
|
||||
.test_string = "SECLINUX",
|
||||
|
||||
.main_function = 0x4c49,
|
||||
|
||||
.header_offsets = {
|
||||
.port = 0x00,
|
||||
.re_mem = 0x02,
|
||||
.iface_func = 0x03,
|
||||
.en_mem = 0x04,
|
||||
.data_offset = 0x05,
|
||||
.data_segment = 0x07,
|
||||
},
|
||||
|
||||
.commands = {
|
||||
.get_brightness = 0x00,
|
||||
.set_brightness = 0x01,
|
||||
|
||||
.get_wireless_button = 0x02,
|
||||
.set_wireless_button = 0x03,
|
||||
|
||||
.get_backlight = 0x04,
|
||||
.set_backlight = 0x05,
|
||||
|
||||
.get_recovery_mode = 0x06,
|
||||
.set_recovery_mode = 0x07,
|
||||
|
||||
.get_performance_level = 0x08,
|
||||
.set_performance_level = 0x09,
|
||||
|
||||
.set_linux = 0x0a,
|
||||
},
|
||||
|
||||
.performance_levels = {
|
||||
{
|
||||
.name = "silent",
|
||||
.value = 0,
|
||||
},
|
||||
{
|
||||
.name = "normal",
|
||||
.value = 1,
|
||||
},
|
||||
{ },
|
||||
},
|
||||
.min_brightness = 1,
|
||||
.max_brightness = 8,
|
||||
},
|
||||
{
|
||||
.test_string = "SwSmi@",
|
||||
|
||||
.main_function = 0x5843,
|
||||
|
||||
.header_offsets = {
|
||||
.port = 0x00,
|
||||
.re_mem = 0x04,
|
||||
.iface_func = 0x02,
|
||||
.en_mem = 0x03,
|
||||
.data_offset = 0x05,
|
||||
.data_segment = 0x07,
|
||||
},
|
||||
|
||||
.commands = {
|
||||
.get_brightness = 0x10,
|
||||
.set_brightness = 0x11,
|
||||
|
||||
.get_wireless_button = 0x12,
|
||||
.set_wireless_button = 0x13,
|
||||
|
||||
.get_backlight = 0x2d,
|
||||
.set_backlight = 0x2e,
|
||||
|
||||
.get_recovery_mode = 0xff,
|
||||
.set_recovery_mode = 0xff,
|
||||
|
||||
.get_performance_level = 0x31,
|
||||
.set_performance_level = 0x32,
|
||||
|
||||
.set_linux = 0xff,
|
||||
},
|
||||
|
||||
.performance_levels = {
|
||||
{
|
||||
.name = "normal",
|
||||
.value = 0,
|
||||
},
|
||||
{
|
||||
.name = "silent",
|
||||
.value = 1,
|
||||
},
|
||||
{
|
||||
.name = "overclock",
|
||||
.value = 2,
|
||||
},
|
||||
{ },
|
||||
},
|
||||
.min_brightness = 0,
|
||||
.max_brightness = 8,
|
||||
},
|
||||
{ },
|
||||
};
|
||||
|
||||
static const struct sabi_config *sabi_config;
|
||||
|
||||
static void __iomem *sabi;
|
||||
static void __iomem *sabi_iface;
|
||||
static void __iomem *f0000_segment;
|
||||
static struct backlight_device *backlight_device;
|
||||
static struct mutex sabi_mutex;
|
||||
static struct platform_device *sdev;
|
||||
static struct rfkill *rfk;
|
||||
|
||||
static int force;
|
||||
module_param(force, bool, 0);
|
||||
MODULE_PARM_DESC(force,
|
||||
"Disable the DMI check and forces the driver to be loaded");
|
||||
|
||||
static int debug;
|
||||
module_param(debug, bool, S_IRUGO | S_IWUSR);
|
||||
MODULE_PARM_DESC(debug, "Debug enabled or not");
|
||||
|
||||
static int sabi_get_command(u8 command, struct sabi_retval *sretval)
|
||||
{
|
||||
int retval = 0;
|
||||
u16 port = readw(sabi + sabi_config->header_offsets.port);
|
||||
u8 complete, iface_data;
|
||||
|
||||
mutex_lock(&sabi_mutex);
|
||||
|
||||
/* enable memory to be able to write to it */
|
||||
outb(readb(sabi + sabi_config->header_offsets.en_mem), port);
|
||||
|
||||
/* write out the command */
|
||||
writew(sabi_config->main_function, sabi_iface + SABI_IFACE_MAIN);
|
||||
writew(command, sabi_iface + SABI_IFACE_SUB);
|
||||
writeb(0, sabi_iface + SABI_IFACE_COMPLETE);
|
||||
outb(readb(sabi + sabi_config->header_offsets.iface_func), port);
|
||||
|
||||
/* write protect memory to make it safe */
|
||||
outb(readb(sabi + sabi_config->header_offsets.re_mem), port);
|
||||
|
||||
/* see if the command actually succeeded */
|
||||
complete = readb(sabi_iface + SABI_IFACE_COMPLETE);
|
||||
iface_data = readb(sabi_iface + SABI_IFACE_DATA);
|
||||
if (complete != 0xaa || iface_data == 0xff) {
|
||||
pr_warn("SABI get command 0x%02x failed with completion flag 0x%02x and data 0x%02x\n",
|
||||
command, complete, iface_data);
|
||||
retval = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
/*
|
||||
* Save off the data into a structure so the caller use it.
|
||||
* Right now we only want the first 4 bytes,
|
||||
* There are commands that need more, but not for the ones we
|
||||
* currently care about.
|
||||
*/
|
||||
sretval->retval[0] = readb(sabi_iface + SABI_IFACE_DATA);
|
||||
sretval->retval[1] = readb(sabi_iface + SABI_IFACE_DATA + 1);
|
||||
sretval->retval[2] = readb(sabi_iface + SABI_IFACE_DATA + 2);
|
||||
sretval->retval[3] = readb(sabi_iface + SABI_IFACE_DATA + 3);
|
||||
|
||||
exit:
|
||||
mutex_unlock(&sabi_mutex);
|
||||
return retval;
|
||||
|
||||
}
|
||||
|
||||
static int sabi_set_command(u8 command, u8 data)
|
||||
{
|
||||
int retval = 0;
|
||||
u16 port = readw(sabi + sabi_config->header_offsets.port);
|
||||
u8 complete, iface_data;
|
||||
|
||||
mutex_lock(&sabi_mutex);
|
||||
|
||||
/* enable memory to be able to write to it */
|
||||
outb(readb(sabi + sabi_config->header_offsets.en_mem), port);
|
||||
|
||||
/* write out the command */
|
||||
writew(sabi_config->main_function, sabi_iface + SABI_IFACE_MAIN);
|
||||
writew(command, sabi_iface + SABI_IFACE_SUB);
|
||||
writeb(0, sabi_iface + SABI_IFACE_COMPLETE);
|
||||
writeb(data, sabi_iface + SABI_IFACE_DATA);
|
||||
outb(readb(sabi + sabi_config->header_offsets.iface_func), port);
|
||||
|
||||
/* write protect memory to make it safe */
|
||||
outb(readb(sabi + sabi_config->header_offsets.re_mem), port);
|
||||
|
||||
/* see if the command actually succeeded */
|
||||
complete = readb(sabi_iface + SABI_IFACE_COMPLETE);
|
||||
iface_data = readb(sabi_iface + SABI_IFACE_DATA);
|
||||
if (complete != 0xaa || iface_data == 0xff) {
|
||||
pr_warn("SABI set command 0x%02x failed with completion flag 0x%02x and data 0x%02x\n",
|
||||
command, complete, iface_data);
|
||||
retval = -EINVAL;
|
||||
}
|
||||
|
||||
mutex_unlock(&sabi_mutex);
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void test_backlight(void)
|
||||
{
|
||||
struct sabi_retval sretval;
|
||||
|
||||
sabi_get_command(sabi_config->commands.get_backlight, &sretval);
|
||||
printk(KERN_DEBUG "backlight = 0x%02x\n", sretval.retval[0]);
|
||||
|
||||
sabi_set_command(sabi_config->commands.set_backlight, 0);
|
||||
printk(KERN_DEBUG "backlight should be off\n");
|
||||
|
||||
sabi_get_command(sabi_config->commands.get_backlight, &sretval);
|
||||
printk(KERN_DEBUG "backlight = 0x%02x\n", sretval.retval[0]);
|
||||
|
||||
msleep(1000);
|
||||
|
||||
sabi_set_command(sabi_config->commands.set_backlight, 1);
|
||||
printk(KERN_DEBUG "backlight should be on\n");
|
||||
|
||||
sabi_get_command(sabi_config->commands.get_backlight, &sretval);
|
||||
printk(KERN_DEBUG "backlight = 0x%02x\n", sretval.retval[0]);
|
||||
}
|
||||
|
||||
static void test_wireless(void)
|
||||
{
|
||||
struct sabi_retval sretval;
|
||||
|
||||
sabi_get_command(sabi_config->commands.get_wireless_button, &sretval);
|
||||
printk(KERN_DEBUG "wireless led = 0x%02x\n", sretval.retval[0]);
|
||||
|
||||
sabi_set_command(sabi_config->commands.set_wireless_button, 0);
|
||||
printk(KERN_DEBUG "wireless led should be off\n");
|
||||
|
||||
sabi_get_command(sabi_config->commands.get_wireless_button, &sretval);
|
||||
printk(KERN_DEBUG "wireless led = 0x%02x\n", sretval.retval[0]);
|
||||
|
||||
msleep(1000);
|
||||
|
||||
sabi_set_command(sabi_config->commands.set_wireless_button, 1);
|
||||
printk(KERN_DEBUG "wireless led should be on\n");
|
||||
|
||||
sabi_get_command(sabi_config->commands.get_wireless_button, &sretval);
|
||||
printk(KERN_DEBUG "wireless led = 0x%02x\n", sretval.retval[0]);
|
||||
}
|
||||
|
||||
static u8 read_brightness(void)
|
||||
{
|
||||
struct sabi_retval sretval;
|
||||
int user_brightness = 0;
|
||||
int retval;
|
||||
|
||||
retval = sabi_get_command(sabi_config->commands.get_brightness,
|
||||
&sretval);
|
||||
if (!retval) {
|
||||
user_brightness = sretval.retval[0];
|
||||
if (user_brightness != 0)
|
||||
user_brightness -= sabi_config->min_brightness;
|
||||
}
|
||||
return user_brightness;
|
||||
}
|
||||
|
||||
static void set_brightness(u8 user_brightness)
|
||||
{
|
||||
u8 user_level = user_brightness - sabi_config->min_brightness;
|
||||
|
||||
sabi_set_command(sabi_config->commands.set_brightness, user_level);
|
||||
}
|
||||
|
||||
static int get_brightness(struct backlight_device *bd)
|
||||
{
|
||||
return (int)read_brightness();
|
||||
}
|
||||
|
||||
static int update_status(struct backlight_device *bd)
|
||||
{
|
||||
set_brightness(bd->props.brightness);
|
||||
|
||||
if (bd->props.power == FB_BLANK_UNBLANK)
|
||||
sabi_set_command(sabi_config->commands.set_backlight, 1);
|
||||
else
|
||||
sabi_set_command(sabi_config->commands.set_backlight, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct backlight_ops backlight_ops = {
|
||||
.get_brightness = get_brightness,
|
||||
.update_status = update_status,
|
||||
};
|
||||
|
||||
static int rfkill_set(void *data, bool blocked)
|
||||
{
|
||||
/* Do something with blocked...*/
|
||||
/*
|
||||
* blocked == false is on
|
||||
* blocked == true is off
|
||||
*/
|
||||
if (blocked)
|
||||
sabi_set_command(sabi_config->commands.set_wireless_button, 0);
|
||||
else
|
||||
sabi_set_command(sabi_config->commands.set_wireless_button, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct rfkill_ops rfkill_ops = {
|
||||
.set_block = rfkill_set,
|
||||
};
|
||||
|
||||
static int init_wireless(struct platform_device *sdev)
|
||||
{
|
||||
int retval;
|
||||
|
||||
rfk = rfkill_alloc("samsung-wifi", &sdev->dev, RFKILL_TYPE_WLAN,
|
||||
&rfkill_ops, NULL);
|
||||
if (!rfk)
|
||||
return -ENOMEM;
|
||||
|
||||
retval = rfkill_register(rfk);
|
||||
if (retval) {
|
||||
rfkill_destroy(rfk);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void destroy_wireless(void)
|
||||
{
|
||||
rfkill_unregister(rfk);
|
||||
rfkill_destroy(rfk);
|
||||
}
|
||||
|
||||
static ssize_t get_performance_level(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct sabi_retval sretval;
|
||||
int retval;
|
||||
int i;
|
||||
|
||||
/* Read the state */
|
||||
retval = sabi_get_command(sabi_config->commands.get_performance_level,
|
||||
&sretval);
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
/* The logic is backwards, yeah, lots of fun... */
|
||||
for (i = 0; sabi_config->performance_levels[i].name; ++i) {
|
||||
if (sretval.retval[0] == sabi_config->performance_levels[i].value)
|
||||
return sprintf(buf, "%s\n", sabi_config->performance_levels[i].name);
|
||||
}
|
||||
return sprintf(buf, "%s\n", "unknown");
|
||||
}
|
||||
|
||||
static ssize_t set_performance_level(struct device *dev,
|
||||
struct device_attribute *attr, const char *buf,
|
||||
size_t count)
|
||||
{
|
||||
if (count >= 1) {
|
||||
int i;
|
||||
for (i = 0; sabi_config->performance_levels[i].name; ++i) {
|
||||
const struct sabi_performance_level *level =
|
||||
&sabi_config->performance_levels[i];
|
||||
if (!strncasecmp(level->name, buf, strlen(level->name))) {
|
||||
sabi_set_command(sabi_config->commands.set_performance_level,
|
||||
level->value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!sabi_config->performance_levels[i].name)
|
||||
return -EINVAL;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
static DEVICE_ATTR(performance_level, S_IWUSR | S_IRUGO,
|
||||
get_performance_level, set_performance_level);
|
||||
|
||||
|
||||
static int __init dmi_check_cb(const struct dmi_system_id *id)
|
||||
{
|
||||
pr_info("found laptop model '%s'\n",
|
||||
id->ident);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct dmi_system_id __initdata samsung_dmi_table[] = {
|
||||
{
|
||||
.ident = "N128",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR,
|
||||
"SAMSUNG ELECTRONICS CO., LTD."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "N128"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "N128"),
|
||||
},
|
||||
.callback = dmi_check_cb,
|
||||
},
|
||||
{
|
||||
.ident = "N130",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR,
|
||||
"SAMSUNG ELECTRONICS CO., LTD."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "N130"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "N130"),
|
||||
},
|
||||
.callback = dmi_check_cb,
|
||||
},
|
||||
{
|
||||
.ident = "X125",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR,
|
||||
"SAMSUNG ELECTRONICS CO., LTD."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "X125"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "X125"),
|
||||
},
|
||||
.callback = dmi_check_cb,
|
||||
},
|
||||
{
|
||||
.ident = "X120/X170",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR,
|
||||
"SAMSUNG ELECTRONICS CO., LTD."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "X120/X170"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "X120/X170"),
|
||||
},
|
||||
.callback = dmi_check_cb,
|
||||
},
|
||||
{
|
||||
.ident = "NC10",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR,
|
||||
"SAMSUNG ELECTRONICS CO., LTD."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "NC10"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "NC10"),
|
||||
},
|
||||
.callback = dmi_check_cb,
|
||||
},
|
||||
{
|
||||
.ident = "NP-Q45",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR,
|
||||
"SAMSUNG ELECTRONICS CO., LTD."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "SQ45S70S"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "SQ45S70S"),
|
||||
},
|
||||
.callback = dmi_check_cb,
|
||||
},
|
||||
{
|
||||
.ident = "X360",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR,
|
||||
"SAMSUNG ELECTRONICS CO., LTD."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "X360"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "X360"),
|
||||
},
|
||||
.callback = dmi_check_cb,
|
||||
},
|
||||
{
|
||||
.ident = "R410 Plus",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR,
|
||||
"SAMSUNG ELECTRONICS CO., LTD."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "R410P"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "R460"),
|
||||
},
|
||||
.callback = dmi_check_cb,
|
||||
},
|
||||
{
|
||||
.ident = "R518",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR,
|
||||
"SAMSUNG ELECTRONICS CO., LTD."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "R518"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "R518"),
|
||||
},
|
||||
.callback = dmi_check_cb,
|
||||
},
|
||||
{
|
||||
.ident = "R519/R719",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR,
|
||||
"SAMSUNG ELECTRONICS CO., LTD."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "R519/R719"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "R519/R719"),
|
||||
},
|
||||
.callback = dmi_check_cb,
|
||||
},
|
||||
{
|
||||
.ident = "N150/N210/N220/N230",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR,
|
||||
"SAMSUNG ELECTRONICS CO., LTD."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "N150/N210/N220/N230"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "N150/N210/N220/N230"),
|
||||
},
|
||||
.callback = dmi_check_cb,
|
||||
},
|
||||
{
|
||||
.ident = "N150P/N210P/N220P",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR,
|
||||
"SAMSUNG ELECTRONICS CO., LTD."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "N150P/N210P/N220P"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "N150P/N210P/N220P"),
|
||||
},
|
||||
.callback = dmi_check_cb,
|
||||
},
|
||||
{
|
||||
.ident = "R530/R730",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "R530/R730"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "R530/R730"),
|
||||
},
|
||||
.callback = dmi_check_cb,
|
||||
},
|
||||
{
|
||||
.ident = "NF110/NF210/NF310",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "NF110/NF210/NF310"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "NF110/NF210/NF310"),
|
||||
},
|
||||
.callback = dmi_check_cb,
|
||||
},
|
||||
{
|
||||
.ident = "N145P/N250P/N260P",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "N145P/N250P/N260P"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "N145P/N250P/N260P"),
|
||||
},
|
||||
.callback = dmi_check_cb,
|
||||
},
|
||||
{
|
||||
.ident = "R70/R71",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR,
|
||||
"SAMSUNG ELECTRONICS CO., LTD."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "R70/R71"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "R70/R71"),
|
||||
},
|
||||
.callback = dmi_check_cb,
|
||||
},
|
||||
{
|
||||
.ident = "P460",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "P460"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "P460"),
|
||||
},
|
||||
.callback = dmi_check_cb,
|
||||
},
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(dmi, samsung_dmi_table);
|
||||
|
||||
static int find_signature(void __iomem *memcheck, const char *testStr)
|
||||
{
|
||||
int i = 0;
|
||||
int loca;
|
||||
|
||||
for (loca = 0; loca < 0xffff; loca++) {
|
||||
char temp = readb(memcheck + loca);
|
||||
|
||||
if (temp == testStr[i]) {
|
||||
if (i == strlen(testStr)-1)
|
||||
break;
|
||||
++i;
|
||||
} else {
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
return loca;
|
||||
}
|
||||
|
||||
static int __init samsung_init(void)
|
||||
{
|
||||
struct backlight_properties props;
|
||||
struct sabi_retval sretval;
|
||||
unsigned int ifaceP;
|
||||
int i;
|
||||
int loca;
|
||||
int retval;
|
||||
|
||||
mutex_init(&sabi_mutex);
|
||||
|
||||
if (!force && !dmi_check_system(samsung_dmi_table))
|
||||
return -ENODEV;
|
||||
|
||||
f0000_segment = ioremap_nocache(0xf0000, 0xffff);
|
||||
if (!f0000_segment) {
|
||||
pr_err("Can't map the segment at 0xf0000\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Try to find one of the signatures in memory to find the header */
|
||||
for (i = 0; sabi_configs[i].test_string != 0; ++i) {
|
||||
sabi_config = &sabi_configs[i];
|
||||
loca = find_signature(f0000_segment, sabi_config->test_string);
|
||||
if (loca != 0xffff)
|
||||
break;
|
||||
}
|
||||
|
||||
if (loca == 0xffff) {
|
||||
pr_err("This computer does not support SABI\n");
|
||||
goto error_no_signature;
|
||||
}
|
||||
|
||||
/* point to the SMI port Number */
|
||||
loca += 1;
|
||||
sabi = (f0000_segment + loca);
|
||||
|
||||
if (debug) {
|
||||
printk(KERN_DEBUG "This computer supports SABI==%x\n",
|
||||
loca + 0xf0000 - 6);
|
||||
printk(KERN_DEBUG "SABI header:\n");
|
||||
printk(KERN_DEBUG " SMI Port Number = 0x%04x\n",
|
||||
readw(sabi + sabi_config->header_offsets.port));
|
||||
printk(KERN_DEBUG " SMI Interface Function = 0x%02x\n",
|
||||
readb(sabi + sabi_config->header_offsets.iface_func));
|
||||
printk(KERN_DEBUG " SMI enable memory buffer = 0x%02x\n",
|
||||
readb(sabi + sabi_config->header_offsets.en_mem));
|
||||
printk(KERN_DEBUG " SMI restore memory buffer = 0x%02x\n",
|
||||
readb(sabi + sabi_config->header_offsets.re_mem));
|
||||
printk(KERN_DEBUG " SABI data offset = 0x%04x\n",
|
||||
readw(sabi + sabi_config->header_offsets.data_offset));
|
||||
printk(KERN_DEBUG " SABI data segment = 0x%04x\n",
|
||||
readw(sabi + sabi_config->header_offsets.data_segment));
|
||||
}
|
||||
|
||||
/* Get a pointer to the SABI Interface */
|
||||
ifaceP = (readw(sabi + sabi_config->header_offsets.data_segment) & 0x0ffff) << 4;
|
||||
ifaceP += readw(sabi + sabi_config->header_offsets.data_offset) & 0x0ffff;
|
||||
sabi_iface = ioremap_nocache(ifaceP, 16);
|
||||
if (!sabi_iface) {
|
||||
pr_err("Can't remap %x\n", ifaceP);
|
||||
goto exit;
|
||||
}
|
||||
if (debug) {
|
||||
printk(KERN_DEBUG "ifaceP = 0x%08x\n", ifaceP);
|
||||
printk(KERN_DEBUG "sabi_iface = %p\n", sabi_iface);
|
||||
|
||||
test_backlight();
|
||||
test_wireless();
|
||||
|
||||
retval = sabi_get_command(sabi_config->commands.get_brightness,
|
||||
&sretval);
|
||||
printk(KERN_DEBUG "brightness = 0x%02x\n", sretval.retval[0]);
|
||||
}
|
||||
|
||||
/* Turn on "Linux" mode in the BIOS */
|
||||
if (sabi_config->commands.set_linux != 0xff) {
|
||||
retval = sabi_set_command(sabi_config->commands.set_linux,
|
||||
0x81);
|
||||
if (retval) {
|
||||
pr_warn("Linux mode was not set!\n");
|
||||
goto error_no_platform;
|
||||
}
|
||||
}
|
||||
|
||||
/* knock up a platform device to hang stuff off of */
|
||||
sdev = platform_device_register_simple("samsung", -1, NULL, 0);
|
||||
if (IS_ERR(sdev))
|
||||
goto error_no_platform;
|
||||
|
||||
/* create a backlight device to talk to this one */
|
||||
memset(&props, 0, sizeof(struct backlight_properties));
|
||||
props.type = BACKLIGHT_PLATFORM;
|
||||
props.max_brightness = sabi_config->max_brightness;
|
||||
backlight_device = backlight_device_register("samsung", &sdev->dev,
|
||||
NULL, &backlight_ops,
|
||||
&props);
|
||||
if (IS_ERR(backlight_device))
|
||||
goto error_no_backlight;
|
||||
|
||||
backlight_device->props.brightness = read_brightness();
|
||||
backlight_device->props.power = FB_BLANK_UNBLANK;
|
||||
backlight_update_status(backlight_device);
|
||||
|
||||
retval = init_wireless(sdev);
|
||||
if (retval)
|
||||
goto error_no_rfk;
|
||||
|
||||
retval = device_create_file(&sdev->dev, &dev_attr_performance_level);
|
||||
if (retval)
|
||||
goto error_file_create;
|
||||
|
||||
exit:
|
||||
return 0;
|
||||
|
||||
error_file_create:
|
||||
destroy_wireless();
|
||||
|
||||
error_no_rfk:
|
||||
backlight_device_unregister(backlight_device);
|
||||
|
||||
error_no_backlight:
|
||||
platform_device_unregister(sdev);
|
||||
|
||||
error_no_platform:
|
||||
iounmap(sabi_iface);
|
||||
|
||||
error_no_signature:
|
||||
iounmap(f0000_segment);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static void __exit samsung_exit(void)
|
||||
{
|
||||
/* Turn off "Linux" mode in the BIOS */
|
||||
if (sabi_config->commands.set_linux != 0xff)
|
||||
sabi_set_command(sabi_config->commands.set_linux, 0x80);
|
||||
|
||||
device_remove_file(&sdev->dev, &dev_attr_performance_level);
|
||||
backlight_device_unregister(backlight_device);
|
||||
destroy_wireless();
|
||||
iounmap(sabi_iface);
|
||||
iounmap(f0000_segment);
|
||||
platform_device_unregister(sdev);
|
||||
}
|
||||
|
||||
module_init(samsung_init);
|
||||
module_exit(samsung_exit);
|
||||
|
||||
MODULE_AUTHOR("Greg Kroah-Hartman <gregkh@suse.de>");
|
||||
MODULE_DESCRIPTION("Samsung Backlight driver");
|
||||
MODULE_LICENSE("GPL");
|
|
@ -912,8 +912,7 @@ int bind_evtchn_to_irqhandler(unsigned int evtchn,
|
|||
unsigned long irqflags,
|
||||
const char *devname, void *dev_id)
|
||||
{
|
||||
unsigned int irq;
|
||||
int retval;
|
||||
int irq, retval;
|
||||
|
||||
irq = bind_evtchn_to_irq(evtchn);
|
||||
if (irq < 0)
|
||||
|
@ -955,8 +954,7 @@ int bind_virq_to_irqhandler(unsigned int virq, unsigned int cpu,
|
|||
irq_handler_t handler,
|
||||
unsigned long irqflags, const char *devname, void *dev_id)
|
||||
{
|
||||
unsigned int irq;
|
||||
int retval;
|
||||
int irq, retval;
|
||||
|
||||
irq = bind_virq_to_irq(virq, cpu);
|
||||
if (irq < 0)
|
||||
|
|
|
@ -61,7 +61,7 @@ static void xen_post_suspend(int cancelled)
|
|||
xen_mm_unpin_all();
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HIBERNATION
|
||||
#ifdef CONFIG_HIBERNATE_CALLBACKS
|
||||
static int xen_suspend(void *data)
|
||||
{
|
||||
struct suspend_info *si = data;
|
||||
|
@ -173,7 +173,7 @@ static void do_suspend(void)
|
|||
#endif
|
||||
shutting_down = SHUTDOWN_INVALID;
|
||||
}
|
||||
#endif /* CONFIG_HIBERNATION */
|
||||
#endif /* CONFIG_HIBERNATE_CALLBACKS */
|
||||
|
||||
struct shutdown_handler {
|
||||
const char *command;
|
||||
|
@ -202,7 +202,7 @@ static void shutdown_handler(struct xenbus_watch *watch,
|
|||
{ "poweroff", do_poweroff },
|
||||
{ "halt", do_poweroff },
|
||||
{ "reboot", do_reboot },
|
||||
#ifdef CONFIG_HIBERNATION
|
||||
#ifdef CONFIG_HIBERNATE_CALLBACKS
|
||||
{ "suspend", do_suspend },
|
||||
#endif
|
||||
{NULL, NULL},
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue