mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-06 05:06:29 +00:00
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Conflicts: drivers/net/team/team.c drivers/net/usb/qmi_wwan.c net/batman-adv/bat_iv_ogm.c net/ipv4/fib_frontend.c net/ipv4/route.c net/l2tp/l2tp_netlink.c The team, fib_frontend, route, and l2tp_netlink conflicts were simply overlapping changes. qmi_wwan and bat_iv_ogm were of the "use HEAD" variety. With help from Antonio Quartulli. Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
6a06e5e1bb
@ -133,7 +133,7 @@ character devices for this group:
|
||||
$ lspci -n -s 0000:06:0d.0
|
||||
06:0d.0 0401: 1102:0002 (rev 08)
|
||||
# echo 0000:06:0d.0 > /sys/bus/pci/devices/0000:06:0d.0/driver/unbind
|
||||
# echo 1102 0002 > /sys/bus/pci/drivers/vfio/new_id
|
||||
# echo 1102 0002 > /sys/bus/pci/drivers/vfio-pci/new_id
|
||||
|
||||
Now we need to look at what other devices are in the group to free
|
||||
it for use by VFIO:
|
||||
|
14
MAINTAINERS
14
MAINTAINERS
@ -3552,11 +3552,12 @@ K: \b(ABS|SYN)_MT_
|
||||
|
||||
INTEL C600 SERIES SAS CONTROLLER DRIVER
|
||||
M: Intel SCU Linux support <intel-linux-scu@intel.com>
|
||||
M: Lukasz Dorau <lukasz.dorau@intel.com>
|
||||
M: Maciej Patelczyk <maciej.patelczyk@intel.com>
|
||||
M: Dave Jiang <dave.jiang@intel.com>
|
||||
M: Ed Nadolski <edmund.nadolski@intel.com>
|
||||
L: linux-scsi@vger.kernel.org
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/djbw/isci.git
|
||||
S: Maintained
|
||||
T: git git://git.code.sf.net/p/intel-sas/isci
|
||||
S: Supported
|
||||
F: drivers/scsi/isci/
|
||||
F: firmware/isci/
|
||||
|
||||
@ -3666,11 +3667,12 @@ F: Documentation/networking/README.ipw2200
|
||||
F: drivers/net/wireless/ipw2x00/
|
||||
|
||||
INTEL(R) TRUSTED EXECUTION TECHNOLOGY (TXT)
|
||||
M: Joseph Cihula <joseph.cihula@intel.com>
|
||||
M: Richard L Maliszewski <richard.l.maliszewski@intel.com>
|
||||
M: Gang Wei <gang.wei@intel.com>
|
||||
M: Shane Wang <shane.wang@intel.com>
|
||||
L: tboot-devel@lists.sourceforge.net
|
||||
W: http://tboot.sourceforge.net
|
||||
T: Mercurial http://www.bughost.org/repos.hg/tboot.hg
|
||||
T: hg http://tboot.hg.sourceforge.net:8000/hgroot/tboot/tboot
|
||||
S: Supported
|
||||
F: Documentation/intel_txt.txt
|
||||
F: include/linux/tboot.h
|
||||
@ -5543,6 +5545,8 @@ F: Documentation/devicetree/bindings/pwm/
|
||||
F: include/linux/pwm.h
|
||||
F: include/linux/of_pwm.h
|
||||
F: drivers/pwm/
|
||||
F: drivers/video/backlight/pwm_bl.c
|
||||
F: include/linux/pwm_backlight.h
|
||||
|
||||
PXA2xx/PXA3xx SUPPORT
|
||||
M: Eric Miao <eric.y.miao@gmail.com>
|
||||
|
4
Makefile
4
Makefile
@ -1,8 +1,8 @@
|
||||
VERSION = 3
|
||||
PATCHLEVEL = 6
|
||||
SUBLEVEL = 0
|
||||
EXTRAVERSION = -rc5
|
||||
NAME = Saber-toothed Squirrel
|
||||
EXTRAVERSION = -rc7
|
||||
NAME = Terrified Chipmunk
|
||||
|
||||
# *DOCUMENTATION*
|
||||
# To see a list of typical targets execute "make help"
|
||||
|
@ -653,6 +653,7 @@ __armv7_mmu_cache_on:
|
||||
mcrne p15, 0, r0, c8, c7, 0 @ flush I,D TLBs
|
||||
#endif
|
||||
mrc p15, 0, r0, c1, c0, 0 @ read control reg
|
||||
bic r0, r0, #1 << 28 @ clear SCTLR.TRE
|
||||
orr r0, r0, #0x5000 @ I-cache enable, RR cache replacement
|
||||
orr r0, r0, #0x003c @ write buffer
|
||||
#ifdef CONFIG_MMU
|
||||
|
@ -104,6 +104,7 @@ pioA: gpio@fffff400 {
|
||||
#gpio-cells = <2>;
|
||||
gpio-controller;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
};
|
||||
|
||||
pioB: gpio@fffff600 {
|
||||
@ -113,6 +114,7 @@ pioB: gpio@fffff600 {
|
||||
#gpio-cells = <2>;
|
||||
gpio-controller;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
};
|
||||
|
||||
pioC: gpio@fffff800 {
|
||||
@ -122,6 +124,7 @@ pioC: gpio@fffff800 {
|
||||
#gpio-cells = <2>;
|
||||
gpio-controller;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
};
|
||||
|
||||
dbgu: serial@fffff200 {
|
||||
|
@ -95,6 +95,7 @@ pioA: gpio@fffff200 {
|
||||
#gpio-cells = <2>;
|
||||
gpio-controller;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
};
|
||||
|
||||
pioB: gpio@fffff400 {
|
||||
@ -104,6 +105,7 @@ pioB: gpio@fffff400 {
|
||||
#gpio-cells = <2>;
|
||||
gpio-controller;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
};
|
||||
|
||||
pioC: gpio@fffff600 {
|
||||
@ -113,6 +115,7 @@ pioC: gpio@fffff600 {
|
||||
#gpio-cells = <2>;
|
||||
gpio-controller;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
};
|
||||
|
||||
pioD: gpio@fffff800 {
|
||||
@ -122,6 +125,7 @@ pioD: gpio@fffff800 {
|
||||
#gpio-cells = <2>;
|
||||
gpio-controller;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
};
|
||||
|
||||
pioE: gpio@fffffa00 {
|
||||
@ -131,6 +135,7 @@ pioE: gpio@fffffa00 {
|
||||
#gpio-cells = <2>;
|
||||
gpio-controller;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
};
|
||||
|
||||
dbgu: serial@ffffee00 {
|
||||
|
@ -113,6 +113,7 @@ pioA: gpio@fffff200 {
|
||||
#gpio-cells = <2>;
|
||||
gpio-controller;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
};
|
||||
|
||||
pioB: gpio@fffff400 {
|
||||
@ -122,6 +123,7 @@ pioB: gpio@fffff400 {
|
||||
#gpio-cells = <2>;
|
||||
gpio-controller;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
};
|
||||
|
||||
pioC: gpio@fffff600 {
|
||||
@ -131,6 +133,7 @@ pioC: gpio@fffff600 {
|
||||
#gpio-cells = <2>;
|
||||
gpio-controller;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
};
|
||||
|
||||
pioD: gpio@fffff800 {
|
||||
@ -140,6 +143,7 @@ pioD: gpio@fffff800 {
|
||||
#gpio-cells = <2>;
|
||||
gpio-controller;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
};
|
||||
|
||||
pioE: gpio@fffffa00 {
|
||||
@ -149,6 +153,7 @@ pioE: gpio@fffffa00 {
|
||||
#gpio-cells = <2>;
|
||||
gpio-controller;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
};
|
||||
|
||||
dbgu: serial@ffffee00 {
|
||||
|
@ -107,6 +107,7 @@ pioA: gpio@fffff400 {
|
||||
#gpio-cells = <2>;
|
||||
gpio-controller;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
};
|
||||
|
||||
pioB: gpio@fffff600 {
|
||||
@ -116,6 +117,7 @@ pioB: gpio@fffff600 {
|
||||
#gpio-cells = <2>;
|
||||
gpio-controller;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
};
|
||||
|
||||
pioC: gpio@fffff800 {
|
||||
@ -125,6 +127,7 @@ pioC: gpio@fffff800 {
|
||||
#gpio-cells = <2>;
|
||||
gpio-controller;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
};
|
||||
|
||||
pioD: gpio@fffffa00 {
|
||||
@ -134,6 +137,7 @@ pioD: gpio@fffffa00 {
|
||||
#gpio-cells = <2>;
|
||||
gpio-controller;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
};
|
||||
|
||||
dbgu: serial@fffff200 {
|
||||
|
@ -115,6 +115,7 @@ pioA: gpio@fffff400 {
|
||||
#gpio-cells = <2>;
|
||||
gpio-controller;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
};
|
||||
|
||||
pioB: gpio@fffff600 {
|
||||
@ -124,6 +125,7 @@ pioB: gpio@fffff600 {
|
||||
#gpio-cells = <2>;
|
||||
gpio-controller;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
};
|
||||
|
||||
pioC: gpio@fffff800 {
|
||||
@ -133,6 +135,7 @@ pioC: gpio@fffff800 {
|
||||
#gpio-cells = <2>;
|
||||
gpio-controller;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
};
|
||||
|
||||
pioD: gpio@fffffa00 {
|
||||
@ -142,6 +145,7 @@ pioD: gpio@fffffa00 {
|
||||
#gpio-cells = <2>;
|
||||
gpio-controller;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
};
|
||||
|
||||
dbgu: serial@fffff200 {
|
||||
|
@ -404,6 +404,7 @@
|
||||
#define __NR_setns (__NR_SYSCALL_BASE+375)
|
||||
#define __NR_process_vm_readv (__NR_SYSCALL_BASE+376)
|
||||
#define __NR_process_vm_writev (__NR_SYSCALL_BASE+377)
|
||||
/* 378 for kcmp */
|
||||
|
||||
/*
|
||||
* The following SWIs are ARM private.
|
||||
@ -483,6 +484,7 @@
|
||||
*/
|
||||
#define __IGNORE_fadvise64_64
|
||||
#define __IGNORE_migrate_pages
|
||||
#define __IGNORE_kcmp
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
#endif /* __ASM_ARM_UNISTD_H */
|
||||
|
@ -387,6 +387,7 @@
|
||||
/* 375 */ CALL(sys_setns)
|
||||
CALL(sys_process_vm_readv)
|
||||
CALL(sys_process_vm_writev)
|
||||
CALL(sys_ni_syscall) /* reserved for sys_kcmp */
|
||||
#ifndef syscalls_counted
|
||||
.equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
|
||||
#define syscalls_counted
|
||||
|
@ -11,7 +11,6 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/cpufreq.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/err.h>
|
||||
@ -96,7 +95,52 @@ static void twd_timer_stop(struct clock_event_device *clk)
|
||||
disable_percpu_irq(clk->irq);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CPU_FREQ
|
||||
#ifdef CONFIG_COMMON_CLK
|
||||
|
||||
/*
|
||||
* Updates clockevent frequency when the cpu frequency changes.
|
||||
* Called on the cpu that is changing frequency with interrupts disabled.
|
||||
*/
|
||||
static void twd_update_frequency(void *new_rate)
|
||||
{
|
||||
twd_timer_rate = *((unsigned long *) new_rate);
|
||||
|
||||
clockevents_update_freq(*__this_cpu_ptr(twd_evt), twd_timer_rate);
|
||||
}
|
||||
|
||||
static int twd_rate_change(struct notifier_block *nb,
|
||||
unsigned long flags, void *data)
|
||||
{
|
||||
struct clk_notifier_data *cnd = data;
|
||||
|
||||
/*
|
||||
* The twd clock events must be reprogrammed to account for the new
|
||||
* frequency. The timer is local to a cpu, so cross-call to the
|
||||
* changing cpu.
|
||||
*/
|
||||
if (flags == POST_RATE_CHANGE)
|
||||
smp_call_function(twd_update_frequency,
|
||||
(void *)&cnd->new_rate, 1);
|
||||
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
static struct notifier_block twd_clk_nb = {
|
||||
.notifier_call = twd_rate_change,
|
||||
};
|
||||
|
||||
static int twd_clk_init(void)
|
||||
{
|
||||
if (twd_evt && *__this_cpu_ptr(twd_evt) && !IS_ERR(twd_clk))
|
||||
return clk_notifier_register(twd_clk, &twd_clk_nb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
core_initcall(twd_clk_init);
|
||||
|
||||
#elif defined (CONFIG_CPU_FREQ)
|
||||
|
||||
#include <linux/cpufreq.h>
|
||||
|
||||
/*
|
||||
* Updates clockevent frequency when the cpu frequency changes.
|
||||
|
@ -241,6 +241,6 @@ int __init mx25_clocks_init(void)
|
||||
clk_register_clkdev(clk[sdma_ahb], "ahb", "imx35-sdma");
|
||||
clk_register_clkdev(clk[iim_ipg], "iim", NULL);
|
||||
|
||||
mxc_timer_init(MX25_IO_ADDRESS(MX25_GPT1_BASE_ADDR), 54);
|
||||
mxc_timer_init(MX25_IO_ADDRESS(MX25_GPT1_BASE_ADDR), MX25_INT_GPT1);
|
||||
return 0;
|
||||
}
|
||||
|
@ -526,7 +526,8 @@ static void __init armadillo5x0_init(void)
|
||||
imx31_add_mxc_nand(&armadillo5x0_nand_board_info);
|
||||
|
||||
/* set NAND page size to 2k if not configured via boot mode pins */
|
||||
__raw_writel(__raw_readl(MXC_CCM_RCSR) | (1 << 30), MXC_CCM_RCSR);
|
||||
__raw_writel(__raw_readl(mx3_ccm_base + MXC_CCM_RCSR) |
|
||||
(1 << 30), mx3_ccm_base + MXC_CCM_RCSR);
|
||||
|
||||
/* RTC */
|
||||
/* Get RTC IRQ and register the chip */
|
||||
|
@ -261,7 +261,7 @@ static void __init apx4devkit_init(void)
|
||||
enable_clk_enet_out();
|
||||
|
||||
if (IS_BUILTIN(CONFIG_PHYLIB))
|
||||
phy_register_fixup_for_uid(PHY_ID_KS8051, MICREL_PHY_ID_MASK,
|
||||
phy_register_fixup_for_uid(PHY_ID_KSZ8051, MICREL_PHY_ID_MASK,
|
||||
apx4devkit_phy_fixup);
|
||||
|
||||
mxsfb_pdata.mode_list = apx4devkit_video_modes;
|
||||
|
@ -204,6 +204,13 @@ void __init orion5x_wdt_init(void)
|
||||
void __init orion5x_init_early(void)
|
||||
{
|
||||
orion_time_set_base(TIMER_VIRT_BASE);
|
||||
|
||||
/*
|
||||
* Some Orion5x devices allocate their coherent buffers from atomic
|
||||
* context. Increase size of atomic coherent pool to make sure such
|
||||
* the allocations won't fail.
|
||||
*/
|
||||
init_dma_coherent_pool_size(SZ_1M);
|
||||
}
|
||||
|
||||
int orion5x_tclk;
|
||||
|
@ -346,11 +346,11 @@ static struct resource sh_mmcif_resources[] = {
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[1] = {
|
||||
.start = gic_spi(141),
|
||||
.start = gic_spi(140),
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
[2] = {
|
||||
.start = gic_spi(140),
|
||||
.start = gic_spi(141),
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
@ -346,6 +346,8 @@ static int __init atomic_pool_init(void)
|
||||
(unsigned)pool->size / 1024);
|
||||
return 0;
|
||||
}
|
||||
|
||||
kfree(pages);
|
||||
no_pages:
|
||||
kfree(bitmap);
|
||||
no_bitmap:
|
||||
|
@ -98,6 +98,7 @@
|
||||
#define MX25_INT_UART1 (NR_IRQS_LEGACY + 45)
|
||||
#define MX25_INT_GPIO2 (NR_IRQS_LEGACY + 51)
|
||||
#define MX25_INT_GPIO1 (NR_IRQS_LEGACY + 52)
|
||||
#define MX25_INT_GPT1 (NR_IRQS_LEGACY + 54)
|
||||
#define MX25_INT_FEC (NR_IRQS_LEGACY + 57)
|
||||
|
||||
#define MX25_DMA_REQ_SSI2_RX1 22
|
||||
|
@ -144,6 +144,7 @@ long clk_round_rate(struct clk *clk, unsigned long rate)
|
||||
|
||||
int clk_set_rate(struct clk *clk, unsigned long rate)
|
||||
{
|
||||
unsigned long flags;
|
||||
int ret;
|
||||
|
||||
if (IS_ERR(clk))
|
||||
@ -159,9 +160,9 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
|
||||
if (clk->ops == NULL || clk->ops->set_rate == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
spin_lock(&clocks_lock);
|
||||
spin_lock_irqsave(&clocks_lock, flags);
|
||||
ret = (clk->ops->set_rate)(clk, rate);
|
||||
spin_unlock(&clocks_lock);
|
||||
spin_unlock_irqrestore(&clocks_lock, flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -173,17 +174,18 @@ struct clk *clk_get_parent(struct clk *clk)
|
||||
|
||||
int clk_set_parent(struct clk *clk, struct clk *parent)
|
||||
{
|
||||
unsigned long flags;
|
||||
int ret = 0;
|
||||
|
||||
if (IS_ERR(clk))
|
||||
return -EINVAL;
|
||||
|
||||
spin_lock(&clocks_lock);
|
||||
spin_lock_irqsave(&clocks_lock, flags);
|
||||
|
||||
if (clk->ops && clk->ops->set_parent)
|
||||
ret = (clk->ops->set_parent)(clk, parent);
|
||||
|
||||
spin_unlock(&clocks_lock);
|
||||
spin_unlock_irqrestore(&clocks_lock, flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ include include/asm-generic/Kbuild.asm
|
||||
|
||||
generic-y += atomic.h
|
||||
generic-y += auxvec.h
|
||||
generic-y += barrier.h
|
||||
generic-y += bitsperlong.h
|
||||
generic-y += bugs.h
|
||||
generic-y += cputime.h
|
||||
|
@ -1,27 +0,0 @@
|
||||
/*
|
||||
* Port on Texas Instruments TMS320C6x architecture
|
||||
*
|
||||
* Copyright (C) 2004, 2009, 2010, 2011 Texas Instruments Incorporated
|
||||
* Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#ifndef _ASM_C6X_BARRIER_H
|
||||
#define _ASM_C6X_BARRIER_H
|
||||
|
||||
#define nop() asm("NOP\n");
|
||||
|
||||
#define mb() barrier()
|
||||
#define rmb() barrier()
|
||||
#define wmb() barrier()
|
||||
#define set_mb(var, value) do { var = value; mb(); } while (0)
|
||||
#define set_wmb(var, value) do { var = value; wmb(); } while (0)
|
||||
|
||||
#define smp_mb() barrier()
|
||||
#define smp_rmb() barrier()
|
||||
#define smp_wmb() barrier()
|
||||
#define smp_read_barrier_depends() do { } while (0)
|
||||
|
||||
#endif /* _ASM_C6X_BARRIER_H */
|
@ -146,9 +146,3 @@ struct clk_ops clk_ops1 = {
|
||||
};
|
||||
#endif /* MCFPM_PPMCR1 */
|
||||
#endif /* MCFPM_PPMCR0 */
|
||||
|
||||
struct clk *devm_clk_get(struct device *dev, const char *id)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(devm_clk_get);
|
||||
|
@ -102,7 +102,7 @@ static void cmp_init_secondary(void)
|
||||
c->vpe_id = (read_c0_tcbind() >> TCBIND_CURVPE_SHIFT) & TCBIND_CURVPE;
|
||||
#endif
|
||||
#ifdef CONFIG_MIPS_MT_SMTC
|
||||
c->tc_id = (read_c0_tcbind() >> TCBIND_CURTC_SHIFT) & TCBIND_CURTC;
|
||||
c->tc_id = (read_c0_tcbind() & TCBIND_CURTC) >> TCBIND_CURTC_SHIFT;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -152,6 +152,8 @@ static int gup_huge_pud(pud_t pud, unsigned long addr, unsigned long end,
|
||||
do {
|
||||
VM_BUG_ON(compound_head(page) != head);
|
||||
pages[*nr] = page;
|
||||
if (PageTail(page))
|
||||
get_huge_page_tail(page);
|
||||
(*nr)++;
|
||||
page++;
|
||||
refs++;
|
||||
|
@ -273,16 +273,19 @@ asmlinkage void plat_irq_dispatch(void)
|
||||
unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
|
||||
int irq;
|
||||
|
||||
if (unlikely(!pending)) {
|
||||
spurious_interrupt();
|
||||
return;
|
||||
}
|
||||
|
||||
irq = irq_ffs(pending);
|
||||
|
||||
if (irq == MIPSCPU_INT_I8259A)
|
||||
malta_hw0_irqdispatch();
|
||||
else if (gic_present && ((1 << irq) & ipi_map[smp_processor_id()]))
|
||||
malta_ipi_irqdispatch();
|
||||
else if (irq >= 0)
|
||||
do_IRQ(MIPS_CPU_IRQ_BASE + irq);
|
||||
else
|
||||
spurious_interrupt();
|
||||
do_IRQ(MIPS_CPU_IRQ_BASE + irq);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MIPS_MT_SMP
|
||||
|
@ -138,11 +138,6 @@ static int __init malta_add_devices(void)
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/*
|
||||
* Set RTC to BCD mode to support current alarm code.
|
||||
*/
|
||||
CMOS_WRITE(CMOS_READ(RTC_CONTROL) & ~RTC_DM_BINARY, RTC_CONTROL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -66,16 +66,6 @@ static inline pte_t huge_ptep_get(pte_t *ptep)
|
||||
return pte;
|
||||
}
|
||||
|
||||
static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
|
||||
unsigned long addr, pte_t *ptep)
|
||||
{
|
||||
pte_t pte = huge_ptep_get(ptep);
|
||||
|
||||
mm->context.flush_mm = 1;
|
||||
pmd_clear((pmd_t *) ptep);
|
||||
return pte;
|
||||
}
|
||||
|
||||
static inline void __pmd_csp(pmd_t *pmdp)
|
||||
{
|
||||
register unsigned long reg2 asm("2") = pmd_val(*pmdp);
|
||||
@ -117,6 +107,15 @@ static inline void huge_ptep_invalidate(struct mm_struct *mm,
|
||||
__pmd_csp(pmdp);
|
||||
}
|
||||
|
||||
static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
|
||||
unsigned long addr, pte_t *ptep)
|
||||
{
|
||||
pte_t pte = huge_ptep_get(ptep);
|
||||
|
||||
huge_ptep_invalidate(mm, addr, ptep);
|
||||
return pte;
|
||||
}
|
||||
|
||||
#define huge_ptep_set_access_flags(__vma, __addr, __ptep, __entry, __dirty) \
|
||||
({ \
|
||||
int __changed = !pte_same(huge_ptep_get(__ptep), __entry); \
|
||||
@ -131,10 +130,7 @@ static inline void huge_ptep_invalidate(struct mm_struct *mm,
|
||||
({ \
|
||||
pte_t __pte = huge_ptep_get(__ptep); \
|
||||
if (pte_write(__pte)) { \
|
||||
(__mm)->context.flush_mm = 1; \
|
||||
if (atomic_read(&(__mm)->context.attach_count) > 1 || \
|
||||
(__mm) != current->active_mm) \
|
||||
huge_ptep_invalidate(__mm, __addr, __ptep); \
|
||||
huge_ptep_invalidate(__mm, __addr, __ptep); \
|
||||
set_huge_pte_at(__mm, __addr, __ptep, \
|
||||
huge_pte_wrprotect(__pte)); \
|
||||
} \
|
||||
|
@ -90,12 +90,10 @@ static inline void __tlb_flush_mm(struct mm_struct * mm)
|
||||
|
||||
static inline void __tlb_flush_mm_cond(struct mm_struct * mm)
|
||||
{
|
||||
spin_lock(&mm->page_table_lock);
|
||||
if (mm->context.flush_mm) {
|
||||
__tlb_flush_mm(mm);
|
||||
mm->context.flush_mm = 0;
|
||||
}
|
||||
spin_unlock(&mm->page_table_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -974,11 +974,13 @@ static void __init setup_hwcaps(void)
|
||||
if (MACHINE_HAS_HPAGE)
|
||||
elf_hwcap |= HWCAP_S390_HPAGE;
|
||||
|
||||
#if defined(CONFIG_64BIT)
|
||||
/*
|
||||
* 64-bit register support for 31-bit processes
|
||||
* HWCAP_S390_HIGH_GPRS is bit 9.
|
||||
*/
|
||||
elf_hwcap |= HWCAP_S390_HIGH_GPRS;
|
||||
#endif
|
||||
|
||||
get_cpu_id(&cpu_id);
|
||||
switch (cpu_id.machine) {
|
||||
|
@ -2,69 +2,82 @@
|
||||
* User access functions based on page table walks for enhanced
|
||||
* system layout without hardware support.
|
||||
*
|
||||
* Copyright IBM Corp. 2006
|
||||
* Copyright IBM Corp. 2006, 2012
|
||||
* Author(s): Gerald Schaefer (gerald.schaefer@de.ibm.com)
|
||||
*/
|
||||
|
||||
#include <linux/errno.h>
|
||||
#include <linux/hardirq.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/hugetlb.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/futex.h>
|
||||
#include "uaccess.h"
|
||||
|
||||
static inline pte_t *follow_table(struct mm_struct *mm, unsigned long addr)
|
||||
|
||||
/*
|
||||
* Returns kernel address for user virtual address. If the returned address is
|
||||
* >= -4095 (IS_ERR_VALUE(x) returns true), a fault has occured and the address
|
||||
* contains the (negative) exception code.
|
||||
*/
|
||||
static __always_inline unsigned long follow_table(struct mm_struct *mm,
|
||||
unsigned long addr, int write)
|
||||
{
|
||||
pgd_t *pgd;
|
||||
pud_t *pud;
|
||||
pmd_t *pmd;
|
||||
pte_t *ptep;
|
||||
|
||||
pgd = pgd_offset(mm, addr);
|
||||
if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd)))
|
||||
return (pte_t *) 0x3a;
|
||||
return -0x3aUL;
|
||||
|
||||
pud = pud_offset(pgd, addr);
|
||||
if (pud_none(*pud) || unlikely(pud_bad(*pud)))
|
||||
return (pte_t *) 0x3b;
|
||||
return -0x3bUL;
|
||||
|
||||
pmd = pmd_offset(pud, addr);
|
||||
if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd)))
|
||||
return (pte_t *) 0x10;
|
||||
if (pmd_none(*pmd))
|
||||
return -0x10UL;
|
||||
if (pmd_huge(*pmd)) {
|
||||
if (write && (pmd_val(*pmd) & _SEGMENT_ENTRY_RO))
|
||||
return -0x04UL;
|
||||
return (pmd_val(*pmd) & HPAGE_MASK) + (addr & ~HPAGE_MASK);
|
||||
}
|
||||
if (unlikely(pmd_bad(*pmd)))
|
||||
return -0x10UL;
|
||||
|
||||
return pte_offset_map(pmd, addr);
|
||||
ptep = pte_offset_map(pmd, addr);
|
||||
if (!pte_present(*ptep))
|
||||
return -0x11UL;
|
||||
if (write && !pte_write(*ptep))
|
||||
return -0x04UL;
|
||||
|
||||
return (pte_val(*ptep) & PAGE_MASK) + (addr & ~PAGE_MASK);
|
||||
}
|
||||
|
||||
static __always_inline size_t __user_copy_pt(unsigned long uaddr, void *kptr,
|
||||
size_t n, int write_user)
|
||||
{
|
||||
struct mm_struct *mm = current->mm;
|
||||
unsigned long offset, pfn, done, size;
|
||||
pte_t *pte;
|
||||
unsigned long offset, done, size, kaddr;
|
||||
void *from, *to;
|
||||
|
||||
done = 0;
|
||||
retry:
|
||||
spin_lock(&mm->page_table_lock);
|
||||
do {
|
||||
pte = follow_table(mm, uaddr);
|
||||
if ((unsigned long) pte < 0x1000)
|
||||
kaddr = follow_table(mm, uaddr, write_user);
|
||||
if (IS_ERR_VALUE(kaddr))
|
||||
goto fault;
|
||||
if (!pte_present(*pte)) {
|
||||
pte = (pte_t *) 0x11;
|
||||
goto fault;
|
||||
} else if (write_user && !pte_write(*pte)) {
|
||||
pte = (pte_t *) 0x04;
|
||||
goto fault;
|
||||
}
|
||||
|
||||
pfn = pte_pfn(*pte);
|
||||
offset = uaddr & (PAGE_SIZE - 1);
|
||||
offset = uaddr & ~PAGE_MASK;
|
||||
size = min(n - done, PAGE_SIZE - offset);
|
||||
if (write_user) {
|
||||
to = (void *)((pfn << PAGE_SHIFT) + offset);
|
||||
to = (void *) kaddr;
|
||||
from = kptr + done;
|
||||
} else {
|
||||
from = (void *)((pfn << PAGE_SHIFT) + offset);
|
||||
from = (void *) kaddr;
|
||||
to = kptr + done;
|
||||
}
|
||||
memcpy(to, from, size);
|
||||
@ -75,7 +88,7 @@ static __always_inline size_t __user_copy_pt(unsigned long uaddr, void *kptr,
|
||||
return n - done;
|
||||
fault:
|
||||
spin_unlock(&mm->page_table_lock);
|
||||
if (__handle_fault(uaddr, (unsigned long) pte, write_user))
|
||||
if (__handle_fault(uaddr, -kaddr, write_user))
|
||||
return n - done;
|
||||
goto retry;
|
||||
}
|
||||
@ -84,27 +97,22 @@ static __always_inline size_t __user_copy_pt(unsigned long uaddr, void *kptr,
|
||||
* Do DAT for user address by page table walk, return kernel address.
|
||||
* This function needs to be called with current->mm->page_table_lock held.
|
||||
*/
|
||||
static __always_inline unsigned long __dat_user_addr(unsigned long uaddr)
|
||||
static __always_inline unsigned long __dat_user_addr(unsigned long uaddr,
|
||||
int write)
|
||||
{
|
||||
struct mm_struct *mm = current->mm;
|
||||
unsigned long pfn;
|
||||
pte_t *pte;
|
||||
unsigned long kaddr;
|
||||
int rc;
|
||||
|
||||
retry:
|
||||
pte = follow_table(mm, uaddr);
|
||||
if ((unsigned long) pte < 0x1000)
|
||||
kaddr = follow_table(mm, uaddr, write);
|
||||
if (IS_ERR_VALUE(kaddr))
|
||||
goto fault;
|
||||
if (!pte_present(*pte)) {
|
||||
pte = (pte_t *) 0x11;
|
||||
goto fault;
|
||||
}
|
||||
|
||||
pfn = pte_pfn(*pte);
|
||||
return (pfn << PAGE_SHIFT) + (uaddr & (PAGE_SIZE - 1));
|
||||
return kaddr;
|
||||
fault:
|
||||
spin_unlock(&mm->page_table_lock);
|
||||
rc = __handle_fault(uaddr, (unsigned long) pte, 0);
|
||||
rc = __handle_fault(uaddr, -kaddr, write);
|
||||
spin_lock(&mm->page_table_lock);
|
||||
if (!rc)
|
||||
goto retry;
|
||||
@ -159,11 +167,9 @@ static size_t clear_user_pt(size_t n, void __user *to)
|
||||
|
||||
static size_t strnlen_user_pt(size_t count, const char __user *src)
|
||||
{
|
||||
char *addr;
|
||||
unsigned long uaddr = (unsigned long) src;
|
||||
struct mm_struct *mm = current->mm;
|
||||
unsigned long offset, pfn, done, len;
|
||||
pte_t *pte;
|
||||
unsigned long offset, done, len, kaddr;
|
||||
size_t len_str;
|
||||
|
||||
if (segment_eq(get_fs(), KERNEL_DS))
|
||||
@ -172,19 +178,13 @@ static size_t strnlen_user_pt(size_t count, const char __user *src)
|
||||
retry:
|
||||
spin_lock(&mm->page_table_lock);
|
||||
do {
|
||||
pte = follow_table(mm, uaddr);
|
||||
if ((unsigned long) pte < 0x1000)
|
||||
kaddr = follow_table(mm, uaddr, 0);
|
||||
if (IS_ERR_VALUE(kaddr))
|
||||
goto fault;
|
||||
if (!pte_present(*pte)) {
|
||||
pte = (pte_t *) 0x11;
|
||||
goto fault;
|
||||
}
|
||||
|
||||
pfn = pte_pfn(*pte);
|
||||
offset = uaddr & (PAGE_SIZE-1);
|
||||
addr = (char *)(pfn << PAGE_SHIFT) + offset;
|
||||
offset = uaddr & ~PAGE_MASK;
|
||||
len = min(count - done, PAGE_SIZE - offset);
|
||||
len_str = strnlen(addr, len);
|
||||
len_str = strnlen((char *) kaddr, len);
|
||||
done += len_str;
|
||||
uaddr += len_str;
|
||||
} while ((len_str == len) && (done < count));
|
||||
@ -192,7 +192,7 @@ static size_t strnlen_user_pt(size_t count, const char __user *src)
|
||||
return done + 1;
|
||||
fault:
|
||||
spin_unlock(&mm->page_table_lock);
|
||||
if (__handle_fault(uaddr, (unsigned long) pte, 0))
|
||||
if (__handle_fault(uaddr, -kaddr, 0))
|
||||
return 0;
|
||||
goto retry;
|
||||
}
|
||||
@ -225,11 +225,10 @@ static size_t copy_in_user_pt(size_t n, void __user *to,
|
||||
const void __user *from)
|
||||
{
|
||||
struct mm_struct *mm = current->mm;
|
||||
unsigned long offset_from, offset_to, offset_max, pfn_from, pfn_to,
|
||||
uaddr, done, size, error_code;
|
||||
unsigned long offset_max, uaddr, done, size, error_code;
|
||||
unsigned long uaddr_from = (unsigned long) from;
|
||||
unsigned long uaddr_to = (unsigned long) to;
|
||||
pte_t *pte_from, *pte_to;
|
||||
unsigned long kaddr_to, kaddr_from;
|
||||
int write_user;
|
||||
|
||||
if (segment_eq(get_fs(), KERNEL_DS)) {
|
||||
@ -242,38 +241,23 @@ static size_t copy_in_user_pt(size_t n, void __user *to,
|
||||
do {
|
||||
write_user = 0;
|
||||
uaddr = uaddr_from;
|
||||
pte_from = follow_table(mm, uaddr_from);
|
||||
error_code = (unsigned long) pte_from;
|
||||
if (error_code < 0x1000)
|
||||
kaddr_from = follow_table(mm, uaddr_from, 0);
|
||||
error_code = kaddr_from;
|
||||
if (IS_ERR_VALUE(error_code))
|
||||
goto fault;
|
||||
if (!pte_present(*pte_from)) {
|
||||
error_code = 0x11;
|
||||
goto fault;
|
||||
}
|
||||
|
||||
write_user = 1;
|
||||
uaddr = uaddr_to;
|
||||
pte_to = follow_table(mm, uaddr_to);
|
||||
error_code = (unsigned long) pte_to;
|
||||
if (error_code < 0x1000)
|
||||
kaddr_to = follow_table(mm, uaddr_to, 1);
|
||||
error_code = (unsigned long) kaddr_to;
|
||||
if (IS_ERR_VALUE(error_code))
|
||||
goto fault;
|
||||
if (!pte_present(*pte_to)) {
|
||||
error_code = 0x11;
|
||||
goto fault;
|
||||
} else if (!pte_write(*pte_to)) {
|
||||
error_code = 0x04;
|
||||
goto fault;
|
||||
}
|
||||
|
||||
pfn_from = pte_pfn(*pte_from);
|
||||
pfn_to = pte_pfn(*pte_to);
|
||||
offset_from = uaddr_from & (PAGE_SIZE-1);
|
||||
offset_to = uaddr_from & (PAGE_SIZE-1);
|
||||
offset_max = max(offset_from, offset_to);
|
||||
offset_max = max(uaddr_from & ~PAGE_MASK,
|
||||
uaddr_to & ~PAGE_MASK);
|
||||
size = min(n - done, PAGE_SIZE - offset_max);
|
||||
|
||||
memcpy((void *)(pfn_to << PAGE_SHIFT) + offset_to,
|
||||
(void *)(pfn_from << PAGE_SHIFT) + offset_from, size);
|
||||
memcpy((void *) kaddr_to, (void *) kaddr_from, size);
|
||||
done += size;
|
||||
uaddr_from += size;
|
||||
uaddr_to += size;
|
||||
@ -282,7 +266,7 @@ static size_t copy_in_user_pt(size_t n, void __user *to,
|
||||
return n - done;
|
||||
fault:
|
||||
spin_unlock(&mm->page_table_lock);
|
||||
if (__handle_fault(uaddr, error_code, write_user))
|
||||
if (__handle_fault(uaddr, -error_code, write_user))
|
||||
return n - done;
|
||||
goto retry;
|
||||
}
|
||||
@ -341,7 +325,7 @@ int futex_atomic_op_pt(int op, u32 __user *uaddr, int oparg, int *old)
|
||||
return __futex_atomic_op_pt(op, uaddr, oparg, old);
|
||||
spin_lock(¤t->mm->page_table_lock);
|
||||
uaddr = (u32 __force __user *)
|
||||
__dat_user_addr((__force unsigned long) uaddr);
|
||||
__dat_user_addr((__force unsigned long) uaddr, 1);
|
||||
if (!uaddr) {
|
||||
spin_unlock(¤t->mm->page_table_lock);
|
||||
return -EFAULT;
|
||||
@ -378,7 +362,7 @@ int futex_atomic_cmpxchg_pt(u32 *uval, u32 __user *uaddr,
|
||||
return __futex_atomic_cmpxchg_pt(uval, uaddr, oldval, newval);
|
||||
spin_lock(¤t->mm->page_table_lock);
|
||||
uaddr = (u32 __force __user *)
|
||||
__dat_user_addr((__force unsigned long) uaddr);
|
||||
__dat_user_addr((__force unsigned long) uaddr, 1);
|
||||
if (!uaddr) {
|
||||
spin_unlock(¤t->mm->page_table_lock);
|
||||
return -EFAULT;
|
||||
|
@ -933,7 +933,7 @@ ret_with_reschedule:
|
||||
|
||||
pta restore_all, tr1
|
||||
|
||||
movi _TIF_SIGPENDING, r8
|
||||
movi (_TIF_SIGPENDING|_TIF_NOTIFY_RESUME), r8
|
||||
and r8, r7, r8
|
||||
pta work_notifysig, tr0
|
||||
bne r8, ZERO, tr0
|
||||
|
@ -139,7 +139,7 @@ work_pending:
|
||||
! r8: current_thread_info
|
||||
! t: result of "tst #_TIF_NEED_RESCHED, r0"
|
||||
bf/s work_resched
|
||||
tst #_TIF_SIGPENDING, r0
|
||||
tst #(_TIF_SIGPENDING | _TIF_NOTIFY_RESUME), r0
|
||||
work_notifysig:
|
||||
bt/s __restore_all
|
||||
mov r15, r4
|
||||
|
@ -48,9 +48,7 @@ void *module_alloc(unsigned long size)
|
||||
return NULL;
|
||||
|
||||
ret = module_map(size);
|
||||
if (!ret)
|
||||
ret = ERR_PTR(-ENOMEM);
|
||||
else
|
||||
if (ret)
|
||||
memset(ret, 0, size);
|
||||
|
||||
return ret;
|
||||
@ -116,6 +114,10 @@ int apply_relocate_add(Elf_Shdr *sechdrs,
|
||||
v = sym->st_value + rel[i].r_addend;
|
||||
|
||||
switch (ELF_R_TYPE(rel[i].r_info) & 0xff) {
|
||||
case R_SPARC_DISP32:
|
||||
v -= (Elf_Addr) location;
|
||||
*loc32 = v;
|
||||
break;
|
||||
#ifdef CONFIG_SPARC64
|
||||
case R_SPARC_64:
|
||||
location[0] = v >> 56;
|
||||
@ -128,11 +130,6 @@ int apply_relocate_add(Elf_Shdr *sechdrs,
|
||||
location[7] = v >> 0;
|
||||
break;
|
||||
|
||||
case R_SPARC_DISP32:
|
||||
v -= (Elf_Addr) location;
|
||||
*loc32 = v;
|
||||
break;
|
||||
|
||||
case R_SPARC_WDISP19:
|
||||
v -= (Elf_Addr) location;
|
||||
*loc32 = (*loc32 & ~0x7ffff) |
|
||||
|
@ -25,21 +25,23 @@
|
||||
#include <linux/module.h>
|
||||
#include <asm/pgtable.h>
|
||||
|
||||
#define GXIO_TRIO_OP_ALLOC_ASIDS IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1400)
|
||||
#define GXIO_TRIO_OP_DEALLOC_ASID IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1400)
|
||||
#define GXIO_TRIO_OP_ALLOC_ASIDS IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1401)
|
||||
|
||||
#define GXIO_TRIO_OP_ALLOC_MEMORY_MAPS IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1402)
|
||||
#define GXIO_TRIO_OP_ALLOC_MEMORY_MAPS IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1404)
|
||||
|
||||
#define GXIO_TRIO_OP_ALLOC_PIO_REGIONS IORPC_OPCODE(IORPC_FORMAT_NONE, 0x140e)
|
||||
#define GXIO_TRIO_OP_INIT_PIO_REGION_AUX IORPC_OPCODE(IORPC_FORMAT_NONE, 0x140f)
|
||||
#define GXIO_TRIO_OP_ALLOC_PIO_REGIONS IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1412)
|
||||
|
||||
#define GXIO_TRIO_OP_INIT_MEMORY_MAP_MMU_AUX IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x1417)
|
||||
#define GXIO_TRIO_OP_GET_PORT_PROPERTY IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x1418)
|
||||
#define GXIO_TRIO_OP_CONFIG_LEGACY_INTR IORPC_OPCODE(IORPC_FORMAT_KERNEL_INTERRUPT, 0x1419)
|
||||
#define GXIO_TRIO_OP_CONFIG_MSI_INTR IORPC_OPCODE(IORPC_FORMAT_KERNEL_INTERRUPT, 0x141a)
|
||||
#define GXIO_TRIO_OP_INIT_PIO_REGION_AUX IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1414)
|
||||
|
||||
#define GXIO_TRIO_OP_SET_MPS_MRS IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x141c)
|
||||
#define GXIO_TRIO_OP_FORCE_RC_LINK_UP IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x141d)
|
||||
#define GXIO_TRIO_OP_FORCE_EP_LINK_UP IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x141e)
|
||||
#define GXIO_TRIO_OP_INIT_MEMORY_MAP_MMU_AUX IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x141e)
|
||||
#define GXIO_TRIO_OP_GET_PORT_PROPERTY IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x141f)
|
||||
#define GXIO_TRIO_OP_CONFIG_LEGACY_INTR IORPC_OPCODE(IORPC_FORMAT_KERNEL_INTERRUPT, 0x1420)
|
||||
#define GXIO_TRIO_OP_CONFIG_MSI_INTR IORPC_OPCODE(IORPC_FORMAT_KERNEL_INTERRUPT, 0x1421)
|
||||
|
||||
#define GXIO_TRIO_OP_SET_MPS_MRS IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x1423)
|
||||
#define GXIO_TRIO_OP_FORCE_RC_LINK_UP IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x1424)
|
||||
#define GXIO_TRIO_OP_FORCE_EP_LINK_UP IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x1425)
|
||||
#define GXIO_TRIO_OP_GET_MMIO_BASE IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x8000)
|
||||
#define GXIO_TRIO_OP_CHECK_MMIO_OFFSET IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x8001)
|
||||
|
||||
|
@ -20,14 +20,6 @@ struct mm_struct;
|
||||
|
||||
struct thread_struct {
|
||||
struct task_struct *saved_task;
|
||||
/*
|
||||
* This flag is set to 1 before calling do_fork (and analyzed in
|
||||
* copy_thread) to mark that we are begin called from userspace (fork /
|
||||
* vfork / clone), and reset to 0 after. It is left to 0 when called
|
||||
* from kernelspace (i.e. kernel_thread() or fork_idle(),
|
||||
* as of 2.6.11).
|
||||
*/
|
||||
int forking;
|
||||
struct pt_regs regs;
|
||||
int singlestep_syscall;
|
||||
void *fault_addr;
|
||||
@ -58,7 +50,6 @@ struct thread_struct {
|
||||
|
||||
#define INIT_THREAD \
|
||||
{ \
|
||||
.forking = 0, \
|
||||
.regs = EMPTY_REGS, \
|
||||
.fault_addr = NULL, \
|
||||
.prev_sched = NULL, \
|
||||
|
@ -7,16 +7,6 @@ DEFINE(UM_KERN_PAGE_MASK, PAGE_MASK);
|
||||
DEFINE(UM_KERN_PAGE_SHIFT, PAGE_SHIFT);
|
||||
DEFINE(UM_NSEC_PER_SEC, NSEC_PER_SEC);
|
||||
|
||||
DEFINE_STR(UM_KERN_EMERG, KERN_EMERG);
|
||||
DEFINE_STR(UM_KERN_ALERT, KERN_ALERT);
|
||||
DEFINE_STR(UM_KERN_CRIT, KERN_CRIT);
|
||||
DEFINE_STR(UM_KERN_ERR, KERN_ERR);
|
||||
DEFINE_STR(UM_KERN_WARNING, KERN_WARNING);
|
||||
DEFINE_STR(UM_KERN_NOTICE, KERN_NOTICE);
|
||||
DEFINE_STR(UM_KERN_INFO, KERN_INFO);
|
||||
DEFINE_STR(UM_KERN_DEBUG, KERN_DEBUG);
|
||||
DEFINE_STR(UM_KERN_CONT, KERN_CONT);
|
||||
|
||||
DEFINE(UM_ELF_CLASS, ELF_CLASS);
|
||||
DEFINE(UM_ELFCLASS32, ELFCLASS32);
|
||||
DEFINE(UM_ELFCLASS64, ELFCLASS64);
|
||||
|
@ -26,6 +26,17 @@
|
||||
extern void panic(const char *fmt, ...)
|
||||
__attribute__ ((format (printf, 1, 2)));
|
||||
|
||||
/* Requires preincluding include/linux/kern_levels.h */
|
||||
#define UM_KERN_EMERG KERN_EMERG
|
||||
#define UM_KERN_ALERT KERN_ALERT
|
||||
#define UM_KERN_CRIT KERN_CRIT
|
||||
#define UM_KERN_ERR KERN_ERR
|
||||
#define UM_KERN_WARNING KERN_WARNING
|
||||
#define UM_KERN_NOTICE KERN_NOTICE
|
||||
#define UM_KERN_INFO KERN_INFO
|
||||
#define UM_KERN_DEBUG KERN_DEBUG
|
||||
#define UM_KERN_CONT KERN_CONT
|
||||
|
||||
#ifdef UML_CONFIG_PRINTK
|
||||
extern int printk(const char *fmt, ...)
|
||||
__attribute__ ((format (printf, 1, 2)));
|
||||
|
@ -39,34 +39,21 @@ void flush_thread(void)
|
||||
|
||||
void start_thread(struct pt_regs *regs, unsigned long eip, unsigned long esp)
|
||||
{
|
||||
get_safe_registers(regs->regs.gp, regs->regs.fp);
|
||||
PT_REGS_IP(regs) = eip;
|
||||
PT_REGS_SP(regs) = esp;
|
||||
current->ptrace &= ~PT_DTRACE;
|
||||
#ifdef SUBARCH_EXECVE1
|
||||
SUBARCH_EXECVE1(regs->regs);
|
||||
#endif
|
||||
}
|
||||
EXPORT_SYMBOL(start_thread);
|
||||
|
||||
static long execve1(const char *file,
|
||||
const char __user *const __user *argv,
|
||||
const char __user *const __user *env)
|
||||
{
|
||||
long error;
|
||||
|
||||
error = do_execve(file, argv, env, ¤t->thread.regs);
|
||||
if (error == 0) {
|
||||
task_lock(current);
|
||||
current->ptrace &= ~PT_DTRACE;
|
||||
#ifdef SUBARCH_EXECVE1
|
||||
SUBARCH_EXECVE1(¤t->thread.regs.regs);
|
||||
#endif
|
||||
task_unlock(current);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
long um_execve(const char *file, const char __user *const __user *argv, const char __user *const __user *env)
|
||||
{
|
||||
long err;
|
||||
|
||||
err = execve1(file, argv, env);
|
||||
err = do_execve(file, argv, env, ¤t->thread.regs);
|
||||
if (!err)
|
||||
UML_LONGJMP(current->thread.exec_buf, 1);
|
||||
return err;
|
||||
@ -81,7 +68,7 @@ long sys_execve(const char __user *file, const char __user *const __user *argv,
|
||||
filename = getname(file);
|
||||
error = PTR_ERR(filename);
|
||||
if (IS_ERR(filename)) goto out;
|
||||
error = execve1(filename, argv, env);
|
||||
error = do_execve(filename, argv, env, ¤t->thread.regs);
|
||||
putname(filename);
|
||||
out:
|
||||
return error;
|
||||
|
@ -181,11 +181,12 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
|
||||
struct pt_regs *regs)
|
||||
{
|
||||
void (*handler)(void);
|
||||
int kthread = current->flags & PF_KTHREAD;
|
||||
int ret = 0;
|
||||
|
||||
p->thread = (struct thread_struct) INIT_THREAD;
|
||||
|
||||
if (current->thread.forking) {
|
||||
if (!kthread) {
|
||||
memcpy(&p->thread.regs.regs, ®s->regs,
|
||||
sizeof(p->thread.regs.regs));
|
||||
PT_REGS_SET_SYSCALL_RETURN(&p->thread.regs, 0);
|
||||
@ -195,8 +196,7 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
|
||||
handler = fork_handler;
|
||||
|
||||
arch_copy_thread(¤t->thread.arch, &p->thread.arch);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
get_safe_registers(p->thread.regs.regs.gp, p->thread.regs.regs.fp);
|
||||
p->thread.request.u.thread = current->thread.request.u.thread;
|
||||
handler = new_thread_handler;
|
||||
@ -204,7 +204,7 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
|
||||
|
||||
new_thread(task_stack_page(p), &p->thread.switch_buf, handler);
|
||||
|
||||
if (current->thread.forking) {
|
||||
if (!kthread) {
|
||||
clear_flushed_tls(p);
|
||||
|
||||
/*
|
||||
|
@ -22,9 +22,13 @@ static void handle_signal(struct pt_regs *regs, unsigned long signr,
|
||||
struct k_sigaction *ka, siginfo_t *info)
|
||||
{
|
||||
sigset_t *oldset = sigmask_to_save();
|
||||
int singlestep = 0;
|
||||
unsigned long sp;
|
||||
int err;
|
||||
|
||||
if ((current->ptrace & PT_DTRACE) && (current->ptrace & PT_PTRACED))
|
||||
singlestep = 1;
|
||||
|
||||
/* Did we come from a system call? */
|
||||
if (PT_REGS_SYSCALL_NR(regs) >= 0) {
|
||||
/* If so, check system call restarting.. */
|
||||
@ -61,7 +65,7 @@ static void handle_signal(struct pt_regs *regs, unsigned long signr,
|
||||
if (err)
|
||||
force_sigsegv(signr, current);
|
||||
else
|
||||
signal_delivered(signr, info, ka, regs, 0);
|
||||
signal_delivered(signr, info, ka, regs, singlestep);
|
||||
}
|
||||
|
||||
static int kern_do_signal(struct pt_regs *regs)
|
||||
|
@ -17,25 +17,25 @@
|
||||
|
||||
long sys_fork(void)
|
||||
{
|
||||
long ret;
|
||||
|
||||
current->thread.forking = 1;
|
||||
ret = do_fork(SIGCHLD, UPT_SP(¤t->thread.regs.regs),
|
||||
return do_fork(SIGCHLD, UPT_SP(¤t->thread.regs.regs),
|
||||
¤t->thread.regs, 0, NULL, NULL);
|
||||
current->thread.forking = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
long sys_vfork(void)
|
||||
{
|
||||
long ret;
|
||||
|
||||
current->thread.forking = 1;
|
||||
ret = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD,
|
||||
return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD,
|
||||
UPT_SP(¤t->thread.regs.regs),
|
||||
¤t->thread.regs, 0, NULL, NULL);
|
||||
current->thread.forking = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
long sys_clone(unsigned long clone_flags, unsigned long newsp,
|
||||
void __user *parent_tid, void __user *child_tid)
|
||||
{
|
||||
if (!newsp)
|
||||
newsp = UPT_SP(¤t->thread.regs.regs);
|
||||
|
||||
return do_fork(clone_flags, newsp, ¤t->thread.regs, 0, parent_tid,
|
||||
child_tid);
|
||||
}
|
||||
|
||||
long old_mmap(unsigned long addr, unsigned long len,
|
||||
|
@ -8,7 +8,7 @@ USER_OBJS += $(filter %_user.o,$(obj-y) $(obj-m) $(USER_SINGLE_OBJS))
|
||||
USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
|
||||
|
||||
$(USER_OBJS:.o=.%): \
|
||||
c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) -include user.h $(CFLAGS_$(basetarget).o)
|
||||
c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) -include $(srctree)/include/linux/kern_levels.h -include user.h $(CFLAGS_$(basetarget).o)
|
||||
|
||||
# These are like USER_OBJS but filter USER_CFLAGS through unprofile instead of
|
||||
# using it directly.
|
||||
|
@ -746,10 +746,10 @@ config SWIOTLB
|
||||
def_bool y if X86_64
|
||||
---help---
|
||||
Support for software bounce buffers used on x86-64 systems
|
||||
which don't have a hardware IOMMU (e.g. the current generation
|
||||
of Intel's x86-64 CPUs). Using this PCI devices which can only
|
||||
access 32-bits of memory can be used on systems with more than
|
||||
3 GB of memory. If unsure, say Y.
|
||||
which don't have a hardware IOMMU. Using this PCI devices
|
||||
which can only access 32-bits of memory can be used on systems
|
||||
with more than 3 GB of memory.
|
||||
If unsure, say Y.
|
||||
|
||||
config IOMMU_HELPER
|
||||
def_bool (CALGARY_IOMMU || GART_IOMMU || SWIOTLB || AMD_IOMMU)
|
||||
|
@ -142,7 +142,7 @@ KBUILD_CFLAGS += $(call cc-option,-mno-avx,)
|
||||
KBUILD_CFLAGS += $(mflags-y)
|
||||
KBUILD_AFLAGS += $(mflags-y)
|
||||
|
||||
archscripts:
|
||||
archscripts: scripts_basic
|
||||
$(Q)$(MAKE) $(build)=arch/x86/tools relocs
|
||||
|
||||
###
|
||||
|
@ -51,7 +51,8 @@ extern unsigned long set_phys_range_identity(unsigned long pfn_s,
|
||||
|
||||
extern int m2p_add_override(unsigned long mfn, struct page *page,
|
||||
struct gnttab_map_grant_ref *kmap_op);
|
||||
extern int m2p_remove_override(struct page *page, bool clear_pte);
|
||||
extern int m2p_remove_override(struct page *page,
|
||||
struct gnttab_map_grant_ref *kmap_op);
|
||||
extern struct page *m2p_find_override(unsigned long mfn);
|
||||
extern unsigned long m2p_find_override_pfn(unsigned long mfn, unsigned long pfn);
|
||||
|
||||
|
@ -586,6 +586,8 @@ extern struct event_constraint intel_westmere_pebs_event_constraints[];
|
||||
|
||||
extern struct event_constraint intel_snb_pebs_event_constraints[];
|
||||
|
||||
extern struct event_constraint intel_ivb_pebs_event_constraints[];
|
||||
|
||||
struct event_constraint *intel_pebs_constraints(struct perf_event *event);
|
||||
|
||||
void intel_pmu_pebs_enable(struct perf_event *event);
|
||||
|
@ -209,6 +209,15 @@ static int perf_ibs_precise_event(struct perf_event *event, u64 *config)
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static const struct perf_event_attr ibs_notsupp = {
|
||||
.exclude_user = 1,
|
||||
.exclude_kernel = 1,
|
||||
.exclude_hv = 1,
|
||||
.exclude_idle = 1,
|
||||
.exclude_host = 1,
|
||||
.exclude_guest = 1,
|
||||
};
|
||||
|
||||
static int perf_ibs_init(struct perf_event *event)
|
||||
{
|
||||
struct hw_perf_event *hwc = &event->hw;
|
||||
@ -229,6 +238,9 @@ static int perf_ibs_init(struct perf_event *event)
|
||||
if (event->pmu != &perf_ibs->pmu)
|
||||
return -ENOENT;
|
||||
|
||||
if (perf_flags(&event->attr) & perf_flags(&ibs_notsupp))
|
||||
return -EINVAL;
|
||||
|
||||
if (config & ~perf_ibs->config_mask)
|
||||
return -EINVAL;
|
||||
|
||||
|
@ -2048,7 +2048,6 @@ __init int intel_pmu_init(void)
|
||||
case 42: /* SandyBridge */
|
||||
case 45: /* SandyBridge, "Romely-EP" */
|
||||
x86_add_quirk(intel_sandybridge_quirk);
|
||||
case 58: /* IvyBridge */
|
||||
memcpy(hw_cache_event_ids, snb_hw_cache_event_ids,
|
||||
sizeof(hw_cache_event_ids));
|
||||
memcpy(hw_cache_extra_regs, snb_hw_cache_extra_regs,
|
||||
@ -2073,6 +2072,29 @@ __init int intel_pmu_init(void)
|
||||
|
||||
pr_cont("SandyBridge events, ");
|
||||
break;
|
||||
case 58: /* IvyBridge */
|
||||
memcpy(hw_cache_event_ids, snb_hw_cache_event_ids,
|
||||
sizeof(hw_cache_event_ids));
|
||||
memcpy(hw_cache_extra_regs, snb_hw_cache_extra_regs,
|
||||
sizeof(hw_cache_extra_regs));
|
||||
|
||||
intel_pmu_lbr_init_snb();
|
||||
|
||||
x86_pmu.event_constraints = intel_snb_event_constraints;
|
||||
x86_pmu.pebs_constraints = intel_ivb_pebs_event_constraints;
|
||||
x86_pmu.pebs_aliases = intel_pebs_aliases_snb;
|
||||
x86_pmu.extra_regs = intel_snb_extra_regs;
|
||||
/* all extra regs are per-cpu when HT is on */
|
||||
x86_pmu.er_flags |= ERF_HAS_RSP_1;
|
||||
x86_pmu.er_flags |= ERF_NO_HT_SHARING;
|
||||
|
||||
/* UOPS_ISSUED.ANY,c=1,i=1 to count stall cycles */
|
||||
intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] =
|
||||
X86_CONFIG(.event=0x0e, .umask=0x01, .inv=1, .cmask=1);
|
||||
|
||||
pr_cont("IvyBridge events, ");
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
switch (x86_pmu.version) {
|
||||
|
@ -407,6 +407,20 @@ struct event_constraint intel_snb_pebs_event_constraints[] = {
|
||||
EVENT_CONSTRAINT_END
|
||||
};
|
||||
|
||||
struct event_constraint intel_ivb_pebs_event_constraints[] = {
|
||||
INTEL_UEVENT_CONSTRAINT(0x01c0, 0x2), /* INST_RETIRED.PRECDIST */
|
||||
INTEL_UEVENT_CONSTRAINT(0x01c2, 0xf), /* UOPS_RETIRED.ALL */
|
||||
INTEL_UEVENT_CONSTRAINT(0x02c2, 0xf), /* UOPS_RETIRED.RETIRE_SLOTS */
|
||||
INTEL_EVENT_CONSTRAINT(0xc4, 0xf), /* BR_INST_RETIRED.* */
|
||||
INTEL_EVENT_CONSTRAINT(0xc5, 0xf), /* BR_MISP_RETIRED.* */
|
||||
INTEL_EVENT_CONSTRAINT(0xcd, 0x8), /* MEM_TRANS_RETIRED.* */
|
||||
INTEL_EVENT_CONSTRAINT(0xd0, 0xf), /* MEM_UOP_RETIRED.* */
|
||||
INTEL_EVENT_CONSTRAINT(0xd1, 0xf), /* MEM_LOAD_UOPS_RETIRED.* */
|
||||
INTEL_EVENT_CONSTRAINT(0xd2, 0xf), /* MEM_LOAD_UOPS_LLC_HIT_RETIRED.* */
|
||||
INTEL_EVENT_CONSTRAINT(0xd3, 0xf), /* MEM_LOAD_UOPS_LLC_MISS_RETIRED.* */
|
||||
EVENT_CONSTRAINT_END
|
||||
};
|
||||
|
||||
struct event_constraint *intel_pebs_constraints(struct perf_event *event)
|
||||
{
|
||||
struct event_constraint *c;
|
||||
|
@ -661,6 +661,11 @@ static void snb_uncore_msr_init_box(struct intel_uncore_box *box)
|
||||
}
|
||||
}
|
||||
|
||||
static struct uncore_event_desc snb_uncore_events[] = {
|
||||
INTEL_UNCORE_EVENT_DESC(clockticks, "event=0xff,umask=0x00"),
|
||||
{ /* end: all zeroes */ },
|
||||
};
|
||||
|
||||
static struct attribute *snb_uncore_formats_attr[] = {
|
||||
&format_attr_event.attr,
|
||||
&format_attr_umask.attr,
|
||||
@ -704,6 +709,7 @@ static struct intel_uncore_type snb_uncore_cbox = {
|
||||
.constraints = snb_uncore_cbox_constraints,
|
||||
.ops = &snb_uncore_msr_ops,
|
||||
.format_group = &snb_uncore_format_group,
|
||||
.event_descs = snb_uncore_events,
|
||||
};
|
||||
|
||||
static struct intel_uncore_type *snb_msr_uncores[] = {
|
||||
|
@ -319,7 +319,7 @@ unsigned long __init_refok init_memory_mapping(unsigned long start,
|
||||
*/
|
||||
int devmem_is_allowed(unsigned long pagenr)
|
||||
{
|
||||
if (pagenr <= 256)
|
||||
if (pagenr < 256)
|
||||
return 1;
|
||||
if (iomem_is_exclusive(pagenr << PAGE_SHIFT))
|
||||
return 0;
|
||||
|
@ -21,6 +21,7 @@ config 64BIT
|
||||
config X86_32
|
||||
def_bool !64BIT
|
||||
select HAVE_AOUT
|
||||
select ARCH_WANT_IPC_PARSE_VERSION
|
||||
|
||||
config X86_64
|
||||
def_bool 64BIT
|
||||
|
@ -7,9 +7,6 @@
|
||||
#define DEFINE(sym, val) \
|
||||
asm volatile("\n->" #sym " %0 " #val : : "i" (val))
|
||||
|
||||
#define STR(x) #x
|
||||
#define DEFINE_STR(sym, val) asm volatile("\n->" #sym " " STR(val) " " #val: : )
|
||||
|
||||
#define BLANK() asm volatile("\n->" : : )
|
||||
|
||||
#define OFFSET(sym, str, mem) \
|
||||
|
@ -1,3 +1,5 @@
|
||||
extern long sys_clone(unsigned long clone_flags, unsigned long newsp,
|
||||
void __user *parent_tid, void __user *child_tid);
|
||||
#ifdef __i386__
|
||||
#include "syscalls_32.h"
|
||||
#else
|
||||
|
@ -416,9 +416,6 @@ int setup_signal_stack_sc(unsigned long stack_top, int sig,
|
||||
PT_REGS_AX(regs) = (unsigned long) sig;
|
||||
PT_REGS_DX(regs) = (unsigned long) 0;
|
||||
PT_REGS_CX(regs) = (unsigned long) 0;
|
||||
|
||||
if ((current->ptrace & PT_DTRACE) && (current->ptrace & PT_PTRACED))
|
||||
ptrace_notify(SIGTRAP);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -466,9 +463,6 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
|
||||
PT_REGS_AX(regs) = (unsigned long) sig;
|
||||
PT_REGS_DX(regs) = (unsigned long) &frame->info;
|
||||
PT_REGS_CX(regs) = (unsigned long) &frame->uc;
|
||||
|
||||
if ((current->ptrace & PT_DTRACE) && (current->ptrace & PT_PTRACED))
|
||||
ptrace_notify(SIGTRAP);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,7 @@
|
||||
#define ptregs_execve sys_execve
|
||||
#define ptregs_iopl sys_iopl
|
||||
#define ptregs_vm86old sys_vm86old
|
||||
#define ptregs_clone sys_clone
|
||||
#define ptregs_clone i386_clone
|
||||
#define ptregs_vm86 sys_vm86
|
||||
#define ptregs_sigaltstack sys_sigaltstack
|
||||
#define ptregs_vfork sys_vfork
|
||||
|
@ -3,37 +3,24 @@
|
||||
* Licensed under the GPL
|
||||
*/
|
||||
|
||||
#include "linux/sched.h"
|
||||
#include "linux/shm.h"
|
||||
#include "linux/ipc.h"
|
||||
#include "linux/syscalls.h"
|
||||
#include "asm/mman.h"
|
||||
#include "asm/uaccess.h"
|
||||
#include "asm/unistd.h"
|
||||
#include <linux/syscalls.h>
|
||||
#include <sysdep/syscalls.h>
|
||||
|
||||
/*
|
||||
* The prototype on i386 is:
|
||||
*
|
||||
* int clone(int flags, void * child_stack, int * parent_tidptr, struct user_desc * newtls, int * child_tidptr)
|
||||
* int clone(int flags, void * child_stack, int * parent_tidptr, struct user_desc * newtls
|
||||
*
|
||||
* and the "newtls" arg. on i386 is read by copy_thread directly from the
|
||||
* register saved on the stack.
|
||||
*/
|
||||
long sys_clone(unsigned long clone_flags, unsigned long newsp,
|
||||
int __user *parent_tid, void *newtls, int __user *child_tid)
|
||||
long i386_clone(unsigned long clone_flags, unsigned long newsp,
|
||||
int __user *parent_tid, void *newtls, int __user *child_tid)
|
||||
{
|
||||
long ret;
|
||||
|
||||
if (!newsp)
|
||||
newsp = UPT_SP(¤t->thread.regs.regs);
|
||||
|
||||
current->thread.forking = 1;
|
||||
ret = do_fork(clone_flags, newsp, ¤t->thread.regs, 0, parent_tid,
|
||||
child_tid);
|
||||
current->thread.forking = 0;
|
||||
return ret;
|
||||
return sys_clone(clone_flags, newsp, parent_tid, child_tid);
|
||||
}
|
||||
|
||||
|
||||
long sys_sigaction(int sig, const struct old_sigaction __user *act,
|
||||
struct old_sigaction __user *oact)
|
||||
{
|
||||
|
@ -5,12 +5,9 @@
|
||||
* Licensed under the GPL
|
||||
*/
|
||||
|
||||
#include "linux/linkage.h"
|
||||
#include "linux/personality.h"
|
||||
#include "linux/utsname.h"
|
||||
#include "asm/prctl.h" /* XXX This should get the constants from libc */
|
||||
#include "asm/uaccess.h"
|
||||
#include "os.h"
|
||||
#include <linux/sched.h>
|
||||
#include <asm/prctl.h> /* XXX This should get the constants from libc */
|
||||
#include <os.h>
|
||||
|
||||
long arch_prctl(struct task_struct *task, int code, unsigned long __user *addr)
|
||||
{
|
||||
@ -79,20 +76,6 @@ long sys_arch_prctl(int code, unsigned long addr)
|
||||
return arch_prctl(current, code, (unsigned long __user *) addr);
|
||||
}
|
||||
|
||||
long sys_clone(unsigned long clone_flags, unsigned long newsp,
|
||||
void __user *parent_tid, void __user *child_tid)
|
||||
{
|
||||
long ret;
|
||||
|
||||
if (!newsp)
|
||||
newsp = UPT_SP(¤t->thread.regs.regs);
|
||||
current->thread.forking = 1;
|
||||
ret = do_fork(clone_flags, newsp, ¤t->thread.regs, 0, parent_tid,
|
||||
child_tid);
|
||||
current->thread.forking = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void arch_switch_to(struct task_struct *to)
|
||||
{
|
||||
if ((to->thread.arch.fs == 0) || (to->mm == NULL))
|
||||
|
@ -1452,6 +1452,10 @@ asmlinkage void __init xen_start_kernel(void)
|
||||
pci_request_acs();
|
||||
|
||||
xen_acpi_sleep_register();
|
||||
|
||||
/* Avoid searching for BIOS MP tables */
|
||||
x86_init.mpparse.find_smp_config = x86_init_noop;
|
||||
x86_init.mpparse.get_smp_config = x86_init_uint_noop;
|
||||
}
|
||||
#ifdef CONFIG_PCI
|
||||
/* PCI BIOS service won't work from a PV guest. */
|
||||
|
@ -828,9 +828,6 @@ int m2p_add_override(unsigned long mfn, struct page *page,
|
||||
|
||||
xen_mc_issue(PARAVIRT_LAZY_MMU);
|
||||
}
|
||||
/* let's use dev_bus_addr to record the old mfn instead */
|
||||
kmap_op->dev_bus_addr = page->index;
|
||||
page->index = (unsigned long) kmap_op;
|
||||
}
|
||||
spin_lock_irqsave(&m2p_override_lock, flags);
|
||||
list_add(&page->lru, &m2p_overrides[mfn_hash(mfn)]);
|
||||
@ -857,7 +854,8 @@ int m2p_add_override(unsigned long mfn, struct page *page,
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(m2p_add_override);
|
||||
int m2p_remove_override(struct page *page, bool clear_pte)
|
||||
int m2p_remove_override(struct page *page,
|
||||
struct gnttab_map_grant_ref *kmap_op)
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned long mfn;
|
||||
@ -887,10 +885,8 @@ int m2p_remove_override(struct page *page, bool clear_pte)
|
||||
WARN_ON(!PagePrivate(page));
|
||||
ClearPagePrivate(page);
|
||||
|
||||
if (clear_pte) {
|
||||
struct gnttab_map_grant_ref *map_op =
|
||||
(struct gnttab_map_grant_ref *) page->index;
|
||||
set_phys_to_machine(pfn, map_op->dev_bus_addr);
|
||||
set_phys_to_machine(pfn, page->index);
|
||||
if (kmap_op != NULL) {
|
||||
if (!PageHighMem(page)) {
|
||||
struct multicall_space mcs;
|
||||
struct gnttab_unmap_grant_ref *unmap_op;
|
||||
@ -902,13 +898,13 @@ int m2p_remove_override(struct page *page, bool clear_pte)
|
||||
* issued. In this case handle is going to -1 because
|
||||
* it hasn't been modified yet.
|
||||
*/
|
||||
if (map_op->handle == -1)
|
||||
if (kmap_op->handle == -1)
|
||||
xen_mc_flush();
|
||||
/*
|
||||
* Now if map_op->handle is negative it means that the
|
||||
* Now if kmap_op->handle is negative it means that the
|
||||
* hypercall actually returned an error.
|
||||
*/
|
||||
if (map_op->handle == GNTST_general_error) {
|
||||
if (kmap_op->handle == GNTST_general_error) {
|
||||
printk(KERN_WARNING "m2p_remove_override: "
|
||||
"pfn %lx mfn %lx, failed to modify kernel mappings",
|
||||
pfn, mfn);
|
||||
@ -918,8 +914,8 @@ int m2p_remove_override(struct page *page, bool clear_pte)
|
||||
mcs = xen_mc_entry(
|
||||
sizeof(struct gnttab_unmap_grant_ref));
|
||||
unmap_op = mcs.args;
|
||||
unmap_op->host_addr = map_op->host_addr;
|
||||
unmap_op->handle = map_op->handle;
|
||||
unmap_op->host_addr = kmap_op->host_addr;
|
||||
unmap_op->handle = kmap_op->handle;
|
||||
unmap_op->dev_bus_addr = 0;
|
||||
|
||||
MULTI_grant_table_op(mcs.mc,
|
||||
@ -930,10 +926,9 @@ int m2p_remove_override(struct page *page, bool clear_pte)
|
||||
set_pte_at(&init_mm, address, ptep,
|
||||
pfn_pte(pfn, PAGE_KERNEL));
|
||||
__flush_tlb_single(address);
|
||||
map_op->host_addr = 0;
|
||||
kmap_op->host_addr = 0;
|
||||
}
|
||||
} else
|
||||
set_phys_to_machine(pfn, page->index);
|
||||
}
|
||||
|
||||
/* p2m(m2p(mfn)) == FOREIGN_FRAME(mfn): the mfn is already present
|
||||
* somewhere in this domain, even before being added to the
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include <asm/e820.h>
|
||||
#include <asm/setup.h>
|
||||
#include <asm/acpi.h>
|
||||
#include <asm/numa.h>
|
||||
#include <asm/xen/hypervisor.h>
|
||||
#include <asm/xen/hypercall.h>
|
||||
|
||||
@ -544,4 +545,7 @@ void __init xen_arch_setup(void)
|
||||
disable_cpufreq();
|
||||
WARN_ON(set_pm_idle_to_default());
|
||||
fiddle_vdso();
|
||||
#ifdef CONFIG_NUMA
|
||||
numa_off = 1;
|
||||
#endif
|
||||
}
|
||||
|
@ -2254,9 +2254,11 @@ bool blk_update_request(struct request *req, int error, unsigned int nr_bytes)
|
||||
error_type = "I/O";
|
||||
break;
|
||||
}
|
||||
printk(KERN_ERR "end_request: %s error, dev %s, sector %llu\n",
|
||||
error_type, req->rq_disk ? req->rq_disk->disk_name : "?",
|
||||
(unsigned long long)blk_rq_pos(req));
|
||||
printk_ratelimited(KERN_ERR "end_request: %s error, dev %s, sector %llu\n",
|
||||
error_type, req->rq_disk ?
|
||||
req->rq_disk->disk_name : "?",
|
||||
(unsigned long long)blk_rq_pos(req));
|
||||
|
||||
}
|
||||
|
||||
blk_account_io_completion(req, nr_bytes);
|
||||
|
@ -41,7 +41,7 @@ static int blkpg_ioctl(struct block_device *bdev, struct blkpg_ioctl_arg __user
|
||||
sizeof(long long) > sizeof(long)) {
|
||||
long pstart = start, plength = length;
|
||||
if (pstart != start || plength != length
|
||||
|| pstart < 0 || plength < 0)
|
||||
|| pstart < 0 || plength < 0 || partno > 65535)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -237,6 +237,16 @@ static int __acpi_bus_get_power(struct acpi_device *device, int *state)
|
||||
} else if (result == ACPI_STATE_D3_HOT) {
|
||||
result = ACPI_STATE_D3;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we were unsure about the device parent's power state up to this
|
||||
* point, the fact that the device is in D0 implies that the parent has
|
||||
* to be in D0 too.
|
||||
*/
|
||||
if (device->parent && device->parent->power.state == ACPI_STATE_UNKNOWN
|
||||
&& result == ACPI_STATE_D0)
|
||||
device->parent->power.state = ACPI_STATE_D0;
|
||||
|
||||
*state = result;
|
||||
|
||||
out:
|
||||
|
@ -107,6 +107,7 @@ struct acpi_power_resource {
|
||||
|
||||
/* List of devices relying on this power resource */
|
||||
struct acpi_power_resource_device *devices;
|
||||
struct mutex devices_lock;
|
||||
};
|
||||
|
||||
static struct list_head acpi_power_resource_list;
|
||||
@ -225,7 +226,6 @@ static void acpi_power_on_device(struct acpi_power_managed_device *device)
|
||||
|
||||
static int __acpi_power_on(struct acpi_power_resource *resource)
|
||||
{
|
||||
struct acpi_power_resource_device *device_list = resource->devices;
|
||||
acpi_status status = AE_OK;
|
||||
|
||||
status = acpi_evaluate_object(resource->device->handle, "_ON", NULL, NULL);
|
||||
@ -238,19 +238,15 @@ static int __acpi_power_on(struct acpi_power_resource *resource)
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Power resource [%s] turned on\n",
|
||||
resource->name));
|
||||
|
||||
while (device_list) {
|
||||
acpi_power_on_device(device_list->device);
|
||||
|
||||
device_list = device_list->next;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acpi_power_on(acpi_handle handle)
|
||||
{
|
||||
int result = 0;
|
||||
bool resume_device = false;
|
||||
struct acpi_power_resource *resource = NULL;
|
||||
struct acpi_power_resource_device *device_list;
|
||||
|
||||
result = acpi_power_get_context(handle, &resource);
|
||||
if (result)
|
||||
@ -266,10 +262,25 @@ static int acpi_power_on(acpi_handle handle)
|
||||
result = __acpi_power_on(resource);
|
||||
if (result)
|
||||
resource->ref_count--;
|
||||
else
|
||||
resume_device = true;
|
||||
}
|
||||
|
||||
mutex_unlock(&resource->resource_lock);
|
||||
|
||||
if (!resume_device)
|
||||
return result;
|
||||
|
||||
mutex_lock(&resource->devices_lock);
|
||||
|
||||
device_list = resource->devices;
|
||||
while (device_list) {
|
||||
acpi_power_on_device(device_list->device);
|
||||
device_list = device_list->next;
|
||||
}
|
||||
|
||||
mutex_unlock(&resource->devices_lock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -355,7 +366,7 @@ static void __acpi_power_resource_unregister_device(struct device *dev,
|
||||
if (acpi_power_get_context(res_handle, &resource))
|
||||
return;
|
||||
|
||||
mutex_lock(&resource->resource_lock);
|
||||
mutex_lock(&resource->devices_lock);
|
||||
prev = NULL;
|
||||
curr = resource->devices;
|
||||
while (curr) {
|
||||
@ -372,7 +383,7 @@ static void __acpi_power_resource_unregister_device(struct device *dev,
|
||||
prev = curr;
|
||||
curr = curr->next;
|
||||
}
|
||||
mutex_unlock(&resource->resource_lock);
|
||||
mutex_unlock(&resource->devices_lock);
|
||||
}
|
||||
|
||||
/* Unlink dev from all power resources in _PR0 */
|
||||
@ -414,10 +425,10 @@ static int __acpi_power_resource_register_device(
|
||||
|
||||
power_resource_device->device = powered_device;
|
||||
|
||||
mutex_lock(&resource->resource_lock);
|
||||
mutex_lock(&resource->devices_lock);
|
||||
power_resource_device->next = resource->devices;
|
||||
resource->devices = power_resource_device;
|
||||
mutex_unlock(&resource->resource_lock);
|
||||
mutex_unlock(&resource->devices_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -462,7 +473,7 @@ int acpi_power_resource_register_device(struct device *dev, acpi_handle handle)
|
||||
return ret;
|
||||
|
||||
no_power_resource:
|
||||
printk(KERN_WARNING PREFIX "Invalid Power Resource to register!");
|
||||
printk(KERN_DEBUG PREFIX "Invalid Power Resource to register!");
|
||||
return -ENODEV;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_power_resource_register_device);
|
||||
@ -721,6 +732,7 @@ static int acpi_power_add(struct acpi_device *device)
|
||||
|
||||
resource->device = device;
|
||||
mutex_init(&resource->resource_lock);
|
||||
mutex_init(&resource->devices_lock);
|
||||
strcpy(resource->name, device->pnp.bus_id);
|
||||
strcpy(acpi_device_name(device), ACPI_POWER_DEVICE_NAME);
|
||||
strcpy(acpi_device_class(device), ACPI_POWER_CLASS);
|
||||
|
@ -35,6 +35,7 @@ new_skb(ulong len)
|
||||
skb_reset_mac_header(skb);
|
||||
skb_reset_network_header(skb);
|
||||
skb->protocol = __constant_htons(ETH_P_AOE);
|
||||
skb_checksum_none_assert(skb);
|
||||
}
|
||||
return skb;
|
||||
}
|
||||
|
@ -795,6 +795,7 @@ static void complete_scsi_command(CommandList_struct *c, int timeout,
|
||||
}
|
||||
break;
|
||||
case CMD_PROTOCOL_ERR:
|
||||
cmd->result = DID_ERROR << 16;
|
||||
dev_warn(&h->pdev->dev,
|
||||
"%p has protocol error\n", c);
|
||||
break;
|
||||
|
@ -1148,11 +1148,15 @@ static bool mtip_pause_ncq(struct mtip_port *port,
|
||||
reply = port->rxfis + RX_FIS_D2H_REG;
|
||||
task_file_data = readl(port->mmio+PORT_TFDATA);
|
||||
|
||||
if ((task_file_data & 1) || (fis->command == ATA_CMD_SEC_ERASE_UNIT))
|
||||
if (fis->command == ATA_CMD_SEC_ERASE_UNIT)
|
||||
clear_bit(MTIP_DDF_SEC_LOCK_BIT, &port->dd->dd_flag);
|
||||
|
||||
if ((task_file_data & 1))
|
||||
return false;
|
||||
|
||||
if (fis->command == ATA_CMD_SEC_ERASE_PREP) {
|
||||
set_bit(MTIP_PF_SE_ACTIVE_BIT, &port->flags);
|
||||
set_bit(MTIP_DDF_SEC_LOCK_BIT, &port->dd->dd_flag);
|
||||
port->ic_pause_timer = jiffies;
|
||||
return true;
|
||||
} else if ((fis->command == ATA_CMD_DOWNLOAD_MICRO) &&
|
||||
@ -1900,7 +1904,7 @@ static int exec_drive_command(struct mtip_port *port, u8 *command,
|
||||
int rv = 0, xfer_sz = command[3];
|
||||
|
||||
if (xfer_sz) {
|
||||
if (user_buffer)
|
||||
if (!user_buffer)
|
||||
return -EFAULT;
|
||||
|
||||
buf = dmam_alloc_coherent(&port->dd->pdev->dev,
|
||||
@ -2043,7 +2047,7 @@ static void mtip_set_timeout(struct host_to_dev_fis *fis, unsigned int *timeout)
|
||||
*timeout = 240000; /* 4 minutes */
|
||||
break;
|
||||
case ATA_CMD_STANDBYNOW1:
|
||||
*timeout = 10000; /* 10 seconds */
|
||||
*timeout = 120000; /* 2 minutes */
|
||||
break;
|
||||
case 0xF7:
|
||||
case 0xFA:
|
||||
@ -2588,9 +2592,6 @@ static ssize_t mtip_hw_read_registers(struct file *f, char __user *ubuf,
|
||||
if (!len || size)
|
||||
return 0;
|
||||
|
||||
if (size < 0)
|
||||
return -EINVAL;
|
||||
|
||||
size += sprintf(&buf[size], "H/ S ACTive : [ 0x");
|
||||
|
||||
for (n = dd->slot_groups-1; n >= 0; n--)
|
||||
@ -2660,9 +2661,6 @@ static ssize_t mtip_hw_read_flags(struct file *f, char __user *ubuf,
|
||||
if (!len || size)
|
||||
return 0;
|
||||
|
||||
if (size < 0)
|
||||
return -EINVAL;
|
||||
|
||||
size += sprintf(&buf[size], "Flag-port : [ %08lX ]\n",
|
||||
dd->port->flags);
|
||||
size += sprintf(&buf[size], "Flag-dd : [ %08lX ]\n",
|
||||
@ -3214,8 +3212,8 @@ static int mtip_hw_init(struct driver_data *dd)
|
||||
"Unable to check write protect progress\n");
|
||||
else
|
||||
dev_info(&dd->pdev->dev,
|
||||
"Write protect progress: %d%% (%d blocks)\n",
|
||||
attr242.cur, attr242.data);
|
||||
"Write protect progress: %u%% (%u blocks)\n",
|
||||
attr242.cur, le32_to_cpu(attr242.data));
|
||||
return rv;
|
||||
|
||||
out3:
|
||||
@ -3619,6 +3617,10 @@ static void mtip_make_request(struct request_queue *queue, struct bio *bio)
|
||||
bio_endio(bio, -ENODATA);
|
||||
return;
|
||||
}
|
||||
if (unlikely(test_bit(MTIP_DDF_SEC_LOCK_BIT, &dd->dd_flag))) {
|
||||
bio_endio(bio, -ENODATA);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (unlikely(!bio_has_data(bio))) {
|
||||
@ -4168,7 +4170,13 @@ static void mtip_pci_shutdown(struct pci_dev *pdev)
|
||||
|
||||
/* Table of device ids supported by this driver. */
|
||||
static DEFINE_PCI_DEVICE_TABLE(mtip_pci_tbl) = {
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_MICRON, P320_DEVICE_ID) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_MICRON, P320H_DEVICE_ID) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_MICRON, P320M_DEVICE_ID) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_MICRON, P320S_DEVICE_ID) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_MICRON, P325M_DEVICE_ID) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_MICRON, P420H_DEVICE_ID) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_MICRON, P420M_DEVICE_ID) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_MICRON, P425M_DEVICE_ID) },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
@ -4199,12 +4207,12 @@ static int __init mtip_init(void)
|
||||
{
|
||||
int error;
|
||||
|
||||
printk(KERN_INFO MTIP_DRV_NAME " Version " MTIP_DRV_VERSION "\n");
|
||||
pr_info(MTIP_DRV_NAME " Version " MTIP_DRV_VERSION "\n");
|
||||
|
||||
/* Allocate a major block device number to use with this driver. */
|
||||
error = register_blkdev(0, MTIP_DRV_NAME);
|
||||
if (error <= 0) {
|
||||
printk(KERN_ERR "Unable to register block device (%d)\n",
|
||||
pr_err("Unable to register block device (%d)\n",
|
||||
error);
|
||||
return -EBUSY;
|
||||
}
|
||||
@ -4213,7 +4221,7 @@ static int __init mtip_init(void)
|
||||
if (!dfs_parent) {
|
||||
dfs_parent = debugfs_create_dir("rssd", NULL);
|
||||
if (IS_ERR_OR_NULL(dfs_parent)) {
|
||||
printk(KERN_WARNING "Error creating debugfs parent\n");
|
||||
pr_warn("Error creating debugfs parent\n");
|
||||
dfs_parent = NULL;
|
||||
}
|
||||
}
|
||||
|
@ -76,7 +76,13 @@
|
||||
|
||||
/* Micron Vendor ID & P320x SSD Device ID */
|
||||
#define PCI_VENDOR_ID_MICRON 0x1344
|
||||
#define P320_DEVICE_ID 0x5150
|
||||
#define P320H_DEVICE_ID 0x5150
|
||||
#define P320M_DEVICE_ID 0x5151
|
||||
#define P320S_DEVICE_ID 0x5152
|
||||
#define P325M_DEVICE_ID 0x5153
|
||||
#define P420H_DEVICE_ID 0x5160
|
||||
#define P420M_DEVICE_ID 0x5161
|
||||
#define P425M_DEVICE_ID 0x5163
|
||||
|
||||
/* Driver name and version strings */
|
||||
#define MTIP_DRV_NAME "mtip32xx"
|
||||
@ -131,10 +137,12 @@ enum {
|
||||
MTIP_PF_SVC_THD_STOP_BIT = 8,
|
||||
|
||||
/* below are bit numbers in 'dd_flag' defined in driver_data */
|
||||
MTIP_DDF_SEC_LOCK_BIT = 0,
|
||||
MTIP_DDF_REMOVE_PENDING_BIT = 1,
|
||||
MTIP_DDF_OVER_TEMP_BIT = 2,
|
||||
MTIP_DDF_WRITE_PROTECT_BIT = 3,
|
||||
MTIP_DDF_STOP_IO = ((1 << MTIP_DDF_REMOVE_PENDING_BIT) | \
|
||||
(1 << MTIP_DDF_SEC_LOCK_BIT) | \
|
||||
(1 << MTIP_DDF_OVER_TEMP_BIT) | \
|
||||
(1 << MTIP_DDF_WRITE_PROTECT_BIT)),
|
||||
|
||||
|
@ -449,6 +449,14 @@ static void nbd_clear_que(struct nbd_device *nbd)
|
||||
req->errors++;
|
||||
nbd_end_request(req);
|
||||
}
|
||||
|
||||
while (!list_empty(&nbd->waiting_queue)) {
|
||||
req = list_entry(nbd->waiting_queue.next, struct request,
|
||||
queuelist);
|
||||
list_del_init(&req->queuelist);
|
||||
req->errors++;
|
||||
nbd_end_request(req);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -598,6 +606,7 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd,
|
||||
nbd->file = NULL;
|
||||
nbd_clear_que(nbd);
|
||||
BUG_ON(!list_empty(&nbd->queue_head));
|
||||
BUG_ON(!list_empty(&nbd->waiting_queue));
|
||||
if (file)
|
||||
fput(file);
|
||||
return 0;
|
||||
|
@ -246,13 +246,12 @@ static int rbd_open(struct block_device *bdev, fmode_t mode)
|
||||
{
|
||||
struct rbd_device *rbd_dev = bdev->bd_disk->private_data;
|
||||
|
||||
rbd_get_dev(rbd_dev);
|
||||
|
||||
set_device_ro(bdev, rbd_dev->read_only);
|
||||
|
||||
if ((mode & FMODE_WRITE) && rbd_dev->read_only)
|
||||
return -EROFS;
|
||||
|
||||
rbd_get_dev(rbd_dev);
|
||||
set_device_ro(bdev, rbd_dev->read_only);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -337,7 +337,7 @@ static void xen_blkbk_unmap(struct pending_req *req)
|
||||
invcount++;
|
||||
}
|
||||
|
||||
ret = gnttab_unmap_refs(unmap, pages, invcount, false);
|
||||
ret = gnttab_unmap_refs(unmap, NULL, pages, invcount);
|
||||
BUG_ON(ret);
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
# common clock types
|
||||
obj-$(CONFIG_HAVE_CLK) += clk-devres.o
|
||||
obj-$(CONFIG_CLKDEV_LOOKUP) += clkdev.o
|
||||
obj-$(CONFIG_COMMON_CLK) += clk.o clk-fixed-rate.o clk-gate.o \
|
||||
clk-mux.o clk-divider.o clk-fixed-factor.o
|
||||
|
55
drivers/clk/clk-devres.c
Normal file
55
drivers/clk/clk-devres.c
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/gfp.h>
|
||||
|
||||
static void devm_clk_release(struct device *dev, void *res)
|
||||
{
|
||||
clk_put(*(struct clk **)res);
|
||||
}
|
||||
|
||||
struct clk *devm_clk_get(struct device *dev, const char *id)
|
||||
{
|
||||
struct clk **ptr, *clk;
|
||||
|
||||
ptr = devres_alloc(devm_clk_release, sizeof(*ptr), GFP_KERNEL);
|
||||
if (!ptr)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
clk = clk_get(dev, id);
|
||||
if (!IS_ERR(clk)) {
|
||||
*ptr = clk;
|
||||
devres_add(dev, ptr);
|
||||
} else {
|
||||
devres_free(ptr);
|
||||
}
|
||||
|
||||
return clk;
|
||||
}
|
||||
EXPORT_SYMBOL(devm_clk_get);
|
||||
|
||||
static int devm_clk_match(struct device *dev, void *res, void *data)
|
||||
{
|
||||
struct clk **c = res;
|
||||
if (!c || !*c) {
|
||||
WARN_ON(!c || !*c);
|
||||
return 0;
|
||||
}
|
||||
return *c == data;
|
||||
}
|
||||
|
||||
void devm_clk_put(struct device *dev, struct clk *clk)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = devres_release(dev, devm_clk_release, devm_clk_match, clk);
|
||||
|
||||
WARN_ON(ret);
|
||||
}
|
||||
EXPORT_SYMBOL(devm_clk_put);
|
@ -171,51 +171,6 @@ void clk_put(struct clk *clk)
|
||||
}
|
||||
EXPORT_SYMBOL(clk_put);
|
||||
|
||||
static void devm_clk_release(struct device *dev, void *res)
|
||||
{
|
||||
clk_put(*(struct clk **)res);
|
||||
}
|
||||
|
||||
struct clk *devm_clk_get(struct device *dev, const char *id)
|
||||
{
|
||||
struct clk **ptr, *clk;
|
||||
|
||||
ptr = devres_alloc(devm_clk_release, sizeof(*ptr), GFP_KERNEL);
|
||||
if (!ptr)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
clk = clk_get(dev, id);
|
||||
if (!IS_ERR(clk)) {
|
||||
*ptr = clk;
|
||||
devres_add(dev, ptr);
|
||||
} else {
|
||||
devres_free(ptr);
|
||||
}
|
||||
|
||||
return clk;
|
||||
}
|
||||
EXPORT_SYMBOL(devm_clk_get);
|
||||
|
||||
static int devm_clk_match(struct device *dev, void *res, void *data)
|
||||
{
|
||||
struct clk **c = res;
|
||||
if (!c || !*c) {
|
||||
WARN_ON(!c || !*c);
|
||||
return 0;
|
||||
}
|
||||
return *c == data;
|
||||
}
|
||||
|
||||
void devm_clk_put(struct device *dev, struct clk *clk)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = devres_destroy(dev, devm_clk_release, devm_clk_match, clk);
|
||||
|
||||
WARN_ON(ret);
|
||||
}
|
||||
EXPORT_SYMBOL(devm_clk_put);
|
||||
|
||||
void clkdev_add(struct clk_lookup *cl)
|
||||
{
|
||||
mutex_lock(&clocks_mutex);
|
||||
|
@ -35,7 +35,6 @@
|
||||
#include <linux/slab.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/cpumask.h>
|
||||
#include <linux/sched.h> /* for current / set_cpus_allowed() */
|
||||
#include <linux/io.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
@ -1139,16 +1138,23 @@ static int transition_frequency_pstate(struct powernow_k8_data *data,
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Driver entry point to switch to the target frequency */
|
||||
static int powernowk8_target(struct cpufreq_policy *pol,
|
||||
unsigned targfreq, unsigned relation)
|
||||
struct powernowk8_target_arg {
|
||||
struct cpufreq_policy *pol;
|
||||
unsigned targfreq;
|
||||
unsigned relation;
|
||||
};
|
||||
|
||||
static long powernowk8_target_fn(void *arg)
|
||||
{
|
||||
cpumask_var_t oldmask;
|
||||
struct powernowk8_target_arg *pta = arg;
|
||||
struct cpufreq_policy *pol = pta->pol;
|
||||
unsigned targfreq = pta->targfreq;
|
||||
unsigned relation = pta->relation;
|
||||
struct powernow_k8_data *data = per_cpu(powernow_data, pol->cpu);
|
||||
u32 checkfid;
|
||||
u32 checkvid;
|
||||
unsigned int newstate;
|
||||
int ret = -EIO;
|
||||
int ret;
|
||||
|
||||
if (!data)
|
||||
return -EINVAL;
|
||||
@ -1156,29 +1162,16 @@ static int powernowk8_target(struct cpufreq_policy *pol,
|
||||
checkfid = data->currfid;
|
||||
checkvid = data->currvid;
|
||||
|
||||
/* only run on specific CPU from here on. */
|
||||
/* This is poor form: use a workqueue or smp_call_function_single */
|
||||
if (!alloc_cpumask_var(&oldmask, GFP_KERNEL))
|
||||
return -ENOMEM;
|
||||
|
||||
cpumask_copy(oldmask, tsk_cpus_allowed(current));
|
||||
set_cpus_allowed_ptr(current, cpumask_of(pol->cpu));
|
||||
|
||||
if (smp_processor_id() != pol->cpu) {
|
||||
printk(KERN_ERR PFX "limiting to cpu %u failed\n", pol->cpu);
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
if (pending_bit_stuck()) {
|
||||
printk(KERN_ERR PFX "failing targ, change pending bit set\n");
|
||||
goto err_out;
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
pr_debug("targ: cpu %d, %d kHz, min %d, max %d, relation %d\n",
|
||||
pol->cpu, targfreq, pol->min, pol->max, relation);
|
||||
|
||||
if (query_current_values_with_pending_wait(data))
|
||||
goto err_out;
|
||||
return -EIO;
|
||||
|
||||
if (cpu_family != CPU_HW_PSTATE) {
|
||||
pr_debug("targ: curr fid 0x%x, vid 0x%x\n",
|
||||
@ -1196,7 +1189,7 @@ static int powernowk8_target(struct cpufreq_policy *pol,
|
||||
|
||||
if (cpufreq_frequency_table_target(pol, data->powernow_table,
|
||||
targfreq, relation, &newstate))
|
||||
goto err_out;
|
||||
return -EIO;
|
||||
|
||||
mutex_lock(&fidvid_mutex);
|
||||
|
||||
@ -1209,9 +1202,8 @@ static int powernowk8_target(struct cpufreq_policy *pol,
|
||||
ret = transition_frequency_fidvid(data, newstate);
|
||||
if (ret) {
|
||||
printk(KERN_ERR PFX "transition frequency failed\n");
|
||||
ret = 1;
|
||||
mutex_unlock(&fidvid_mutex);
|
||||
goto err_out;
|
||||
return 1;
|
||||
}
|
||||
mutex_unlock(&fidvid_mutex);
|
||||
|
||||
@ -1220,12 +1212,25 @@ static int powernowk8_target(struct cpufreq_policy *pol,
|
||||
data->powernow_table[newstate].index);
|
||||
else
|
||||
pol->cur = find_khz_freq_from_fid(data->currfid);
|
||||
ret = 0;
|
||||
|
||||
err_out:
|
||||
set_cpus_allowed_ptr(current, oldmask);
|
||||
free_cpumask_var(oldmask);
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Driver entry point to switch to the target frequency */
|
||||
static int powernowk8_target(struct cpufreq_policy *pol,
|
||||
unsigned targfreq, unsigned relation)
|
||||
{
|
||||
struct powernowk8_target_arg pta = { .pol = pol, .targfreq = targfreq,
|
||||
.relation = relation };
|
||||
|
||||
/*
|
||||
* Must run on @pol->cpu. cpufreq core is responsible for ensuring
|
||||
* that we're bound to the current CPU and pol->cpu stays online.
|
||||
*/
|
||||
if (smp_processor_id() == pol->cpu)
|
||||
return powernowk8_target_fn(&pta);
|
||||
else
|
||||
return work_on_cpu(pol->cpu, powernowk8_target_fn, &pta);
|
||||
}
|
||||
|
||||
/* Driver entry point to verify the policy and range of frequencies */
|
||||
|
@ -661,7 +661,7 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
|
||||
flags);
|
||||
|
||||
if (unlikely(!atslave || !sg_len)) {
|
||||
dev_dbg(chan2dev(chan), "prep_dma_memcpy: length is zero!\n");
|
||||
dev_dbg(chan2dev(chan), "prep_slave_sg: sg length is zero!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -689,6 +689,11 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
|
||||
|
||||
mem = sg_dma_address(sg);
|
||||
len = sg_dma_len(sg);
|
||||
if (unlikely(!len)) {
|
||||
dev_dbg(chan2dev(chan),
|
||||
"prep_slave_sg: sg(%d) data length is zero\n", i);
|
||||
goto err;
|
||||
}
|
||||
mem_width = 2;
|
||||
if (unlikely(mem & 3 || len & 3))
|
||||
mem_width = 0;
|
||||
@ -724,6 +729,11 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
|
||||
|
||||
mem = sg_dma_address(sg);
|
||||
len = sg_dma_len(sg);
|
||||
if (unlikely(!len)) {
|
||||
dev_dbg(chan2dev(chan),
|
||||
"prep_slave_sg: sg(%d) data length is zero\n", i);
|
||||
goto err;
|
||||
}
|
||||
mem_width = 2;
|
||||
if (unlikely(mem & 3 || len & 3))
|
||||
mem_width = 0;
|
||||
@ -757,6 +767,7 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
|
||||
|
||||
err_desc_get:
|
||||
dev_err(chan2dev(chan), "not enough descriptors available\n");
|
||||
err:
|
||||
atc_desc_put(atchan, first);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1567,17 +1567,19 @@ static int pl330_submit_req(void *ch_id, struct pl330_req *r)
|
||||
goto xfer_exit;
|
||||
}
|
||||
|
||||
/* Prefer Secure Channel */
|
||||
if (!_manager_ns(thrd))
|
||||
r->cfg->nonsecure = 0;
|
||||
else
|
||||
r->cfg->nonsecure = 1;
|
||||
|
||||
/* Use last settings, if not provided */
|
||||
if (r->cfg)
|
||||
if (r->cfg) {
|
||||
/* Prefer Secure Channel */
|
||||
if (!_manager_ns(thrd))
|
||||
r->cfg->nonsecure = 0;
|
||||
else
|
||||
r->cfg->nonsecure = 1;
|
||||
|
||||
ccr = _prepare_ccr(r->cfg);
|
||||
else
|
||||
} else {
|
||||
ccr = readl(regs + CC(thrd->id));
|
||||
}
|
||||
|
||||
/* If this req doesn't have valid xfer settings */
|
||||
if (!_is_valid(ccr)) {
|
||||
@ -2928,6 +2930,11 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
|
||||
num_chan = max_t(int, pi->pcfg.num_peri, pi->pcfg.num_chan);
|
||||
|
||||
pdmac->peripherals = kzalloc(num_chan * sizeof(*pch), GFP_KERNEL);
|
||||
if (!pdmac->peripherals) {
|
||||
ret = -ENOMEM;
|
||||
dev_err(&adev->dev, "unable to allocate pdmac->peripherals\n");
|
||||
goto probe_err5;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_chan; i++) {
|
||||
pch = &pdmac->peripherals[i];
|
||||
|
@ -199,6 +199,36 @@ void *edac_align_ptr(void **p, unsigned size, int n_elems)
|
||||
return (void *)(((unsigned long)ptr) + align - r);
|
||||
}
|
||||
|
||||
static void _edac_mc_free(struct mem_ctl_info *mci)
|
||||
{
|
||||
int i, chn, row;
|
||||
struct csrow_info *csr;
|
||||
const unsigned int tot_dimms = mci->tot_dimms;
|
||||
const unsigned int tot_channels = mci->num_cschannel;
|
||||
const unsigned int tot_csrows = mci->nr_csrows;
|
||||
|
||||
if (mci->dimms) {
|
||||
for (i = 0; i < tot_dimms; i++)
|
||||
kfree(mci->dimms[i]);
|
||||
kfree(mci->dimms);
|
||||
}
|
||||
if (mci->csrows) {
|
||||
for (row = 0; row < tot_csrows; row++) {
|
||||
csr = mci->csrows[row];
|
||||
if (csr) {
|
||||
if (csr->channels) {
|
||||
for (chn = 0; chn < tot_channels; chn++)
|
||||
kfree(csr->channels[chn]);
|
||||
kfree(csr->channels);
|
||||
}
|
||||
kfree(csr);
|
||||
}
|
||||
}
|
||||
kfree(mci->csrows);
|
||||
}
|
||||
kfree(mci);
|
||||
}
|
||||
|
||||
/**
|
||||
* edac_mc_alloc: Allocate and partially fill a struct mem_ctl_info structure
|
||||
* @mc_num: Memory controller number
|
||||
@ -413,24 +443,7 @@ struct mem_ctl_info *edac_mc_alloc(unsigned mc_num,
|
||||
return mci;
|
||||
|
||||
error:
|
||||
if (mci->dimms) {
|
||||
for (i = 0; i < tot_dimms; i++)
|
||||
kfree(mci->dimms[i]);
|
||||
kfree(mci->dimms);
|
||||
}
|
||||
if (mci->csrows) {
|
||||
for (chn = 0; chn < tot_channels; chn++) {
|
||||
csr = mci->csrows[chn];
|
||||
if (csr) {
|
||||
for (chn = 0; chn < tot_channels; chn++)
|
||||
kfree(csr->channels[chn]);
|
||||
kfree(csr);
|
||||
}
|
||||
kfree(mci->csrows[i]);
|
||||
}
|
||||
kfree(mci->csrows);
|
||||
}
|
||||
kfree(mci);
|
||||
_edac_mc_free(mci);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@ -445,6 +458,14 @@ void edac_mc_free(struct mem_ctl_info *mci)
|
||||
{
|
||||
edac_dbg(1, "\n");
|
||||
|
||||
/* If we're not yet registered with sysfs free only what was allocated
|
||||
* in edac_mc_alloc().
|
||||
*/
|
||||
if (!device_is_registered(&mci->dev)) {
|
||||
_edac_mc_free(mci);
|
||||
return;
|
||||
}
|
||||
|
||||
/* the mci instance is freed here, when the sysfs object is dropped */
|
||||
edac_unregister_sysfs(mci);
|
||||
}
|
||||
|
@ -391,7 +391,7 @@ static int i3200_probe1(struct pci_dev *pdev, int dev_idx)
|
||||
for (j = 0; j < nr_channels; j++) {
|
||||
struct dimm_info *dimm = csrow->channels[j]->dimm;
|
||||
|
||||
dimm->nr_pages = nr_pages / nr_channels;
|
||||
dimm->nr_pages = nr_pages;
|
||||
dimm->grain = nr_pages << PAGE_SHIFT;
|
||||
dimm->mtype = MEM_DDR2;
|
||||
dimm->dtype = DEV_UNKNOWN;
|
||||
|
@ -1012,6 +1012,10 @@ static void handle_channel(struct i5000_pvt *pvt, int slot, int channel,
|
||||
/* add the number of COLUMN bits */
|
||||
addrBits += MTR_DIMM_COLS_ADDR_BITS(mtr);
|
||||
|
||||
/* Dual-rank memories have twice the size */
|
||||
if (dinfo->dual_rank)
|
||||
addrBits++;
|
||||
|
||||
addrBits += 6; /* add 64 bits per DIMM */
|
||||
addrBits -= 20; /* divide by 2^^20 */
|
||||
addrBits -= 3; /* 8 bits per bytes */
|
||||
|
@ -513,7 +513,8 @@ static int get_dimm_config(struct mem_ctl_info *mci)
|
||||
{
|
||||
struct sbridge_pvt *pvt = mci->pvt_info;
|
||||
struct dimm_info *dimm;
|
||||
int i, j, banks, ranks, rows, cols, size, npages;
|
||||
unsigned i, j, banks, ranks, rows, cols, npages;
|
||||
u64 size;
|
||||
u32 reg;
|
||||
enum edac_type mode;
|
||||
enum mem_type mtype;
|
||||
@ -585,10 +586,10 @@ static int get_dimm_config(struct mem_ctl_info *mci)
|
||||
cols = numcol(mtr);
|
||||
|
||||
/* DDR3 has 8 I/O banks */
|
||||
size = (rows * cols * banks * ranks) >> (20 - 3);
|
||||
size = ((u64)rows * cols * banks * ranks) >> (20 - 3);
|
||||
npages = MiB_TO_PAGES(size);
|
||||
|
||||
edac_dbg(0, "mc#%d: channel %d, dimm %d, %d Mb (%d pages) bank: %d, rank: %d, row: %#x, col: %#x\n",
|
||||
edac_dbg(0, "mc#%d: channel %d, dimm %d, %Ld Mb (%d pages) bank: %d, rank: %d, row: %#x, col: %#x\n",
|
||||
pvt->sbridge_dev->mc, i, j,
|
||||
size, npages,
|
||||
banks, ranks, rows, cols);
|
||||
|
@ -669,13 +669,18 @@ static int __devinit max77693_muic_probe(struct platform_device *pdev)
|
||||
}
|
||||
info->dev = &pdev->dev;
|
||||
info->max77693 = max77693;
|
||||
info->max77693->regmap_muic = regmap_init_i2c(info->max77693->muic,
|
||||
&max77693_muic_regmap_config);
|
||||
if (IS_ERR(info->max77693->regmap_muic)) {
|
||||
ret = PTR_ERR(info->max77693->regmap_muic);
|
||||
dev_err(max77693->dev,
|
||||
"failed to allocate register map: %d\n", ret);
|
||||
goto err_regmap;
|
||||
if (info->max77693->regmap_muic)
|
||||
dev_dbg(&pdev->dev, "allocate register map\n");
|
||||
else {
|
||||
info->max77693->regmap_muic = devm_regmap_init_i2c(
|
||||
info->max77693->muic,
|
||||
&max77693_muic_regmap_config);
|
||||
if (IS_ERR(info->max77693->regmap_muic)) {
|
||||
ret = PTR_ERR(info->max77693->regmap_muic);
|
||||
dev_err(max77693->dev,
|
||||
"failed to allocate register map: %d\n", ret);
|
||||
goto err_regmap;
|
||||
}
|
||||
}
|
||||
platform_set_drvdata(pdev, info);
|
||||
mutex_init(&info->mutex);
|
||||
|
@ -308,6 +308,7 @@ static int lpc32xx_gpio_dir_output_p012(struct gpio_chip *chip, unsigned pin,
|
||||
{
|
||||
struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip);
|
||||
|
||||
__set_gpio_level_p012(group, pin, value);
|
||||
__set_gpio_dir_p012(group, pin, 0);
|
||||
|
||||
return 0;
|
||||
@ -318,6 +319,7 @@ static int lpc32xx_gpio_dir_output_p3(struct gpio_chip *chip, unsigned pin,
|
||||
{
|
||||
struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip);
|
||||
|
||||
__set_gpio_level_p3(group, pin, value);
|
||||
__set_gpio_dir_p3(group, pin, 0);
|
||||
|
||||
return 0;
|
||||
@ -326,6 +328,9 @@ static int lpc32xx_gpio_dir_output_p3(struct gpio_chip *chip, unsigned pin,
|
||||
static int lpc32xx_gpio_dir_out_always(struct gpio_chip *chip, unsigned pin,
|
||||
int value)
|
||||
{
|
||||
struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip);
|
||||
|
||||
__set_gpo_level_p3(group, pin, value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -3242,7 +3242,8 @@ i915_gem_object_pin(struct drm_i915_gem_object *obj,
|
||||
{
|
||||
int ret;
|
||||
|
||||
BUG_ON(obj->pin_count == DRM_I915_GEM_OBJECT_MAX_PIN_COUNT);
|
||||
if (WARN_ON(obj->pin_count == DRM_I915_GEM_OBJECT_MAX_PIN_COUNT))
|
||||
return -EBUSY;
|
||||
|
||||
if (obj->gtt_space != NULL) {
|
||||
if ((alignment && obj->gtt_offset & (alignment - 1)) ||
|
||||
|
@ -4191,12 +4191,6 @@ static void i8xx_update_pll(struct drm_crtc *crtc,
|
||||
POSTING_READ(DPLL(pipe));
|
||||
udelay(150);
|
||||
|
||||
I915_WRITE(DPLL(pipe), dpll);
|
||||
|
||||
/* Wait for the clocks to stabilize. */
|
||||
POSTING_READ(DPLL(pipe));
|
||||
udelay(150);
|
||||
|
||||
/* The LVDS pin pair needs to be on before the DPLLs are enabled.
|
||||
* This is an exception to the general rule that mode_set doesn't turn
|
||||
* things on.
|
||||
@ -4204,6 +4198,12 @@ static void i8xx_update_pll(struct drm_crtc *crtc,
|
||||
if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS))
|
||||
intel_update_lvds(crtc, clock, adjusted_mode);
|
||||
|
||||
I915_WRITE(DPLL(pipe), dpll);
|
||||
|
||||
/* Wait for the clocks to stabilize. */
|
||||
POSTING_READ(DPLL(pipe));
|
||||
udelay(150);
|
||||
|
||||
/* The pixel multiplier can only be updated once the
|
||||
* DPLL is enabled and the clocks are stable.
|
||||
*
|
||||
|
@ -609,7 +609,7 @@ static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode)
|
||||
u32 temp;
|
||||
u32 enable_bits = SDVO_ENABLE;
|
||||
|
||||
if (intel_hdmi->has_audio)
|
||||
if (intel_hdmi->has_audio || mode != DRM_MODE_DPMS_ON)
|
||||
enable_bits |= SDVO_AUDIO_ENABLE;
|
||||
|
||||
temp = I915_READ(intel_hdmi->sdvox_reg);
|
||||
|
@ -179,7 +179,7 @@ nouveau_abi16_ioctl_grobj_alloc(ABI16_IOCTL_ARGS)
|
||||
return 0;
|
||||
} else
|
||||
if (init->class == 0x906e) {
|
||||
NV_ERROR(dev, "906e not supported yet\n");
|
||||
NV_DEBUG(dev, "906e not supported yet\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,7 @@
|
||||
* Authors: Ben Skeggs
|
||||
*/
|
||||
|
||||
#include <linux/dmi.h>
|
||||
#include "drmP.h"
|
||||
#include "nouveau_drv.h"
|
||||
#include "nouveau_hw.h"
|
||||
@ -110,13 +111,25 @@ nv50_gpio_isr(struct drm_device *dev)
|
||||
nv_wr32(dev, 0xe074, intr1);
|
||||
}
|
||||
|
||||
static struct dmi_system_id gpio_reset_ids[] = {
|
||||
{
|
||||
.ident = "Apple Macbook 10,1",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro10,1"),
|
||||
}
|
||||
},
|
||||
{ }
|
||||
};
|
||||
|
||||
int
|
||||
nv50_gpio_init(struct drm_device *dev)
|
||||
{
|
||||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||
|
||||
/* initialise gpios and routing to vbios defaults */
|
||||
nouveau_gpio_reset(dev);
|
||||
if (dmi_check_system(gpio_reset_ids))
|
||||
nouveau_gpio_reset(dev);
|
||||
|
||||
/* disable, and ack any pending gpio interrupts */
|
||||
nv_wr32(dev, 0xe050, 0x00000000);
|
||||
|
@ -124,6 +124,7 @@ nvc0_fb_init(struct drm_device *dev)
|
||||
priv = dev_priv->engine.fb.priv;
|
||||
|
||||
nv_wr32(dev, 0x100c10, priv->r100c10 >> 8);
|
||||
nv_mask(dev, 0x17e820, 0x00100000, 0x00000000); /* NV_PLTCG_INTR_EN */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -373,7 +373,8 @@ nvc0_fifo_isr_subfifo_intr(struct drm_device *dev, int unit)
|
||||
static void
|
||||
nvc0_fifo_isr(struct drm_device *dev)
|
||||
{
|
||||
u32 stat = nv_rd32(dev, 0x002100);
|
||||
u32 mask = nv_rd32(dev, 0x002140);
|
||||
u32 stat = nv_rd32(dev, 0x002100) & mask;
|
||||
|
||||
if (stat & 0x00000100) {
|
||||
NV_INFO(dev, "PFIFO: unknown status 0x00000100\n");
|
||||
|
@ -345,7 +345,8 @@ nve0_fifo_isr_subfifo_intr(struct drm_device *dev, int unit)
|
||||
static void
|
||||
nve0_fifo_isr(struct drm_device *dev)
|
||||
{
|
||||
u32 stat = nv_rd32(dev, 0x002100);
|
||||
u32 mask = nv_rd32(dev, 0x002140);
|
||||
u32 stat = nv_rd32(dev, 0x002100) & mask;
|
||||
|
||||
if (stat & 0x00000100) {
|
||||
NV_INFO(dev, "PFIFO: unknown status 0x00000100\n");
|
||||
|
@ -1479,98 +1479,14 @@ static void radeon_legacy_atom_fixup(struct drm_crtc *crtc)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* radeon_get_pll_use_mask - look up a mask of which pplls are in use
|
||||
*
|
||||
* @crtc: drm crtc
|
||||
*
|
||||
* Returns the mask of which PPLLs (Pixel PLLs) are in use.
|
||||
*/
|
||||
static u32 radeon_get_pll_use_mask(struct drm_crtc *crtc)
|
||||
{
|
||||
struct drm_device *dev = crtc->dev;
|
||||
struct drm_crtc *test_crtc;
|
||||
struct radeon_crtc *radeon_test_crtc;
|
||||
u32 pll_in_use = 0;
|
||||
|
||||
list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) {
|
||||
if (crtc == test_crtc)
|
||||
continue;
|
||||
|
||||
radeon_test_crtc = to_radeon_crtc(test_crtc);
|
||||
if (radeon_test_crtc->pll_id != ATOM_PPLL_INVALID)
|
||||
pll_in_use |= (1 << radeon_test_crtc->pll_id);
|
||||
}
|
||||
return pll_in_use;
|
||||
}
|
||||
|
||||
/**
|
||||
* radeon_get_shared_dp_ppll - return the PPLL used by another crtc for DP
|
||||
*
|
||||
* @crtc: drm crtc
|
||||
*
|
||||
* Returns the PPLL (Pixel PLL) used by another crtc/encoder which is
|
||||
* also in DP mode. For DP, a single PPLL can be used for all DP
|
||||
* crtcs/encoders.
|
||||
*/
|
||||
static int radeon_get_shared_dp_ppll(struct drm_crtc *crtc)
|
||||
{
|
||||
struct drm_device *dev = crtc->dev;
|
||||
struct drm_encoder *test_encoder;
|
||||
struct radeon_crtc *radeon_test_crtc;
|
||||
|
||||
list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) {
|
||||
if (test_encoder->crtc && (test_encoder->crtc != crtc)) {
|
||||
if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_encoder))) {
|
||||
/* for DP use the same PLL for all */
|
||||
radeon_test_crtc = to_radeon_crtc(test_encoder->crtc);
|
||||
if (radeon_test_crtc->pll_id != ATOM_PPLL_INVALID)
|
||||
return radeon_test_crtc->pll_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ATOM_PPLL_INVALID;
|
||||
}
|
||||
|
||||
/**
|
||||
* radeon_atom_pick_pll - Allocate a PPLL for use by the crtc.
|
||||
*
|
||||
* @crtc: drm crtc
|
||||
*
|
||||
* Returns the PPLL (Pixel PLL) to be used by the crtc. For DP monitors
|
||||
* a single PPLL can be used for all DP crtcs/encoders. For non-DP
|
||||
* monitors a dedicated PPLL must be used. If a particular board has
|
||||
* an external DP PLL, return ATOM_PPLL_INVALID to skip PLL programming
|
||||
* as there is no need to program the PLL itself. If we are not able to
|
||||
* allocate a PLL, return ATOM_PPLL_INVALID to skip PLL programming to
|
||||
* avoid messing up an existing monitor.
|
||||
*
|
||||
* Asic specific PLL information
|
||||
*
|
||||
* DCE 6.1
|
||||
* - PPLL2 is only available to UNIPHYA (both DP and non-DP)
|
||||
* - PPLL0, PPLL1 are available for UNIPHYB/C/D/E/F (both DP and non-DP)
|
||||
*
|
||||
* DCE 6.0
|
||||
* - PPLL0 is available to all UNIPHY (DP only)
|
||||
* - PPLL1, PPLL2 are available for all UNIPHY (both DP and non-DP) and DAC
|
||||
*
|
||||
* DCE 5.0
|
||||
* - DCPLL is available to all UNIPHY (DP only)
|
||||
* - PPLL1, PPLL2 are available for all UNIPHY (both DP and non-DP) and DAC
|
||||
*
|
||||
* DCE 3.0/4.0/4.1
|
||||
* - PPLL1, PPLL2 are available for all UNIPHY (both DP and non-DP) and DAC
|
||||
*
|
||||
*/
|
||||
static int radeon_atom_pick_pll(struct drm_crtc *crtc)
|
||||
{
|
||||
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
|
||||
struct drm_device *dev = crtc->dev;
|
||||
struct radeon_device *rdev = dev->dev_private;
|
||||
struct drm_encoder *test_encoder;
|
||||
u32 pll_in_use;
|
||||
int pll;
|
||||
struct drm_crtc *test_crtc;
|
||||
uint32_t pll_in_use = 0;
|
||||
|
||||
if (ASIC_IS_DCE61(rdev)) {
|
||||
list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) {
|
||||
@ -1582,40 +1498,32 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc)
|
||||
|
||||
if ((test_radeon_encoder->encoder_id ==
|
||||
ENCODER_OBJECT_ID_INTERNAL_UNIPHY) &&
|
||||
(dig->linkb == false))
|
||||
/* UNIPHY A uses PPLL2 */
|
||||
(dig->linkb == false)) /* UNIPHY A uses PPLL2 */
|
||||
return ATOM_PPLL2;
|
||||
else if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_encoder))) {
|
||||
/* UNIPHY B/C/D/E/F */
|
||||
if (rdev->clock.dp_extclk)
|
||||
/* skip PPLL programming if using ext clock */
|
||||
return ATOM_PPLL_INVALID;
|
||||
else {
|
||||
/* use the same PPLL for all DP monitors */
|
||||
pll = radeon_get_shared_dp_ppll(crtc);
|
||||
if (pll != ATOM_PPLL_INVALID)
|
||||
return pll;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* UNIPHY B/C/D/E/F */
|
||||
pll_in_use = radeon_get_pll_use_mask(crtc);
|
||||
if (!(pll_in_use & (1 << ATOM_PPLL0)))
|
||||
list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) {
|
||||
struct radeon_crtc *radeon_test_crtc;
|
||||
|
||||
if (crtc == test_crtc)
|
||||
continue;
|
||||
|
||||
radeon_test_crtc = to_radeon_crtc(test_crtc);
|
||||
if ((radeon_test_crtc->pll_id == ATOM_PPLL0) ||
|
||||
(radeon_test_crtc->pll_id == ATOM_PPLL1))
|
||||
pll_in_use |= (1 << radeon_test_crtc->pll_id);
|
||||
}
|
||||
if (!(pll_in_use & 4))
|
||||
return ATOM_PPLL0;
|
||||
if (!(pll_in_use & (1 << ATOM_PPLL1)))
|
||||
return ATOM_PPLL1;
|
||||
DRM_ERROR("unable to allocate a PPLL\n");
|
||||
return ATOM_PPLL_INVALID;
|
||||
return ATOM_PPLL1;
|
||||
} else if (ASIC_IS_DCE4(rdev)) {
|
||||
list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) {
|
||||
if (test_encoder->crtc && (test_encoder->crtc == crtc)) {
|
||||
/* in DP mode, the DP ref clock can come from PPLL, DCPLL, or ext clock,
|
||||
* depending on the asic:
|
||||
* DCE4: PPLL or ext clock
|
||||
* DCE5: PPLL, DCPLL, or ext clock
|
||||
* DCE6: PPLL, PPLL0, or ext clock
|
||||
* DCE5: DCPLL or ext clock
|
||||
*
|
||||
* Setting ATOM_PPLL_INVALID will cause SetPixelClock to skip
|
||||
* PPLL/DCPLL programming and only program the DP DTO for the
|
||||
@ -1623,34 +1531,31 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc)
|
||||
*/
|
||||
if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_encoder))) {
|
||||
if (rdev->clock.dp_extclk)
|
||||
/* skip PPLL programming if using ext clock */
|
||||
return ATOM_PPLL_INVALID;
|
||||
else if (ASIC_IS_DCE6(rdev))
|
||||
/* use PPLL0 for all DP */
|
||||
return ATOM_PPLL0;
|
||||
else if (ASIC_IS_DCE5(rdev))
|
||||
/* use DCPLL for all DP */
|
||||
return ATOM_DCPLL;
|
||||
else {
|
||||
/* use the same PPLL for all DP monitors */
|
||||
pll = radeon_get_shared_dp_ppll(crtc);
|
||||
if (pll != ATOM_PPLL_INVALID)
|
||||
return pll;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* all other cases */
|
||||
pll_in_use = radeon_get_pll_use_mask(crtc);
|
||||
if (!(pll_in_use & (1 << ATOM_PPLL2)))
|
||||
return ATOM_PPLL2;
|
||||
if (!(pll_in_use & (1 << ATOM_PPLL1)))
|
||||
|
||||
/* otherwise, pick one of the plls */
|
||||
list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) {
|
||||
struct radeon_crtc *radeon_test_crtc;
|
||||
|
||||
if (crtc == test_crtc)
|
||||
continue;
|
||||
|
||||
radeon_test_crtc = to_radeon_crtc(test_crtc);
|
||||
if ((radeon_test_crtc->pll_id >= ATOM_PPLL1) &&
|
||||
(radeon_test_crtc->pll_id <= ATOM_PPLL2))
|
||||
pll_in_use |= (1 << radeon_test_crtc->pll_id);
|
||||
}
|
||||
if (!(pll_in_use & 1))
|
||||
return ATOM_PPLL1;
|
||||
DRM_ERROR("unable to allocate a PPLL\n");
|
||||
return ATOM_PPLL_INVALID;
|
||||
return ATOM_PPLL2;
|
||||
} else
|
||||
/* use PPLL1 or PPLL2 */
|
||||
return radeon_crtc->crtc_id;
|
||||
|
||||
}
|
||||
@ -1792,7 +1697,7 @@ static void atombios_crtc_disable(struct drm_crtc *crtc)
|
||||
break;
|
||||
}
|
||||
done:
|
||||
radeon_crtc->pll_id = ATOM_PPLL_INVALID;
|
||||
radeon_crtc->pll_id = -1;
|
||||
}
|
||||
|
||||
static const struct drm_crtc_helper_funcs atombios_helper_funcs = {
|
||||
@ -1841,6 +1746,6 @@ void radeon_atombios_init_crtc(struct drm_device *dev,
|
||||
else
|
||||
radeon_crtc->crtc_offset = 0;
|
||||
}
|
||||
radeon_crtc->pll_id = ATOM_PPLL_INVALID;
|
||||
radeon_crtc->pll_id = -1;
|
||||
drm_crtc_helper_add(&radeon_crtc->base, &atombios_helper_funcs);
|
||||
}
|
||||
|
@ -1182,7 +1182,8 @@ int r100_cp_init(struct radeon_device *rdev, unsigned ring_size)
|
||||
ring->ready = true;
|
||||
radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size);
|
||||
|
||||
if (radeon_ring_supports_scratch_reg(rdev, ring)) {
|
||||
if (!ring->rptr_save_reg /* not resuming from suspend */
|
||||
&& radeon_ring_supports_scratch_reg(rdev, ring)) {
|
||||
r = radeon_scratch_get(rdev, &ring->rptr_save_reg);
|
||||
if (r) {
|
||||
DRM_ERROR("failed to get scratch reg for rptr save (%d).\n", r);
|
||||
|
@ -69,6 +69,13 @@ static int udl_get_modes(struct drm_connector *connector)
|
||||
static int udl_mode_valid(struct drm_connector *connector,
|
||||
struct drm_display_mode *mode)
|
||||
{
|
||||
struct udl_device *udl = connector->dev->dev_private;
|
||||
if (!udl->sku_pixel_limit)
|
||||
return 0;
|
||||
|
||||
if (mode->vdisplay * mode->hdisplay > udl->sku_pixel_limit)
|
||||
return MODE_VIRTUAL_Y;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1018,7 +1018,7 @@ int vmw_event_fence_action_create(struct drm_file *file_priv,
|
||||
}
|
||||
|
||||
|
||||
event = kzalloc(sizeof(event->event), GFP_KERNEL);
|
||||
event = kzalloc(sizeof(*event), GFP_KERNEL);
|
||||
if (unlikely(event == NULL)) {
|
||||
DRM_ERROR("Failed to allocate an event.\n");
|
||||
ret = -ENOMEM;
|
||||
|
@ -519,6 +519,8 @@ static void tpkbd_remove_tp(struct hid_device *hdev)
|
||||
led_classdev_unregister(&data_pointer->led_mute);
|
||||
|
||||
hid_set_drvdata(hdev, NULL);
|
||||
kfree(data_pointer->led_micmute.name);
|
||||
kfree(data_pointer->led_mute.name);
|
||||
kfree(data_pointer);
|
||||
}
|
||||
|
||||
|
@ -193,6 +193,7 @@ static struct hid_ll_driver logi_dj_ll_driver;
|
||||
static int logi_dj_output_hidraw_report(struct hid_device *hid, u8 * buf,
|
||||
size_t count,
|
||||
unsigned char report_type);
|
||||
static int logi_dj_recv_query_paired_devices(struct dj_receiver_dev *djrcv_dev);
|
||||
|
||||
static void logi_dj_recv_destroy_djhid_device(struct dj_receiver_dev *djrcv_dev,
|
||||
struct dj_report *dj_report)
|
||||
@ -233,6 +234,7 @@ static void logi_dj_recv_add_djhid_device(struct dj_receiver_dev *djrcv_dev,
|
||||
if (dj_report->report_params[DEVICE_PAIRED_PARAM_SPFUNCTION] &
|
||||
SPFUNCTION_DEVICE_LIST_EMPTY) {
|
||||
dbg_hid("%s: device list is empty\n", __func__);
|
||||
djrcv_dev->querying_devices = false;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -243,6 +245,12 @@ static void logi_dj_recv_add_djhid_device(struct dj_receiver_dev *djrcv_dev,
|
||||
return;
|
||||
}
|
||||
|
||||
if (djrcv_dev->paired_dj_devices[dj_report->device_index]) {
|
||||
/* The device is already known. No need to reallocate it. */
|
||||
dbg_hid("%s: device is already known\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
dj_hiddev = hid_allocate_device();
|
||||
if (IS_ERR(dj_hiddev)) {
|
||||
dev_err(&djrcv_hdev->dev, "%s: hid_allocate_device failed\n",
|
||||
@ -306,6 +314,7 @@ static void delayedwork_callback(struct work_struct *work)
|
||||
struct dj_report dj_report;
|
||||
unsigned long flags;
|
||||
int count;
|
||||
int retval;
|
||||
|
||||
dbg_hid("%s\n", __func__);
|
||||
|
||||
@ -338,6 +347,25 @@ static void delayedwork_callback(struct work_struct *work)
|
||||
logi_dj_recv_destroy_djhid_device(djrcv_dev, &dj_report);
|
||||
break;
|
||||
default:
|
||||
/* A normal report (i. e. not belonging to a pair/unpair notification)
|
||||
* arriving here, means that the report arrived but we did not have a
|
||||
* paired dj_device associated to the report's device_index, this
|
||||
* means that the original "device paired" notification corresponding
|
||||
* to this dj_device never arrived to this driver. The reason is that
|
||||
* hid-core discards all packets coming from a device while probe() is
|
||||
* executing. */
|
||||
if (!djrcv_dev->paired_dj_devices[dj_report.device_index]) {
|
||||
/* ok, we don't know the device, just re-ask the
|
||||
* receiver for the list of connected devices. */
|
||||
retval = logi_dj_recv_query_paired_devices(djrcv_dev);
|
||||
if (!retval) {
|
||||
/* everything went fine, so just leave */
|
||||
break;
|
||||
}
|
||||
dev_err(&djrcv_dev->hdev->dev,
|
||||
"%s:logi_dj_recv_query_paired_devices "
|
||||
"error:%d\n", __func__, retval);
|
||||
}
|
||||
dbg_hid("%s: unexpected report type\n", __func__);
|
||||
}
|
||||
}
|
||||
@ -368,6 +396,12 @@ static void logi_dj_recv_forward_null_report(struct dj_receiver_dev *djrcv_dev,
|
||||
if (!djdev) {
|
||||
dbg_hid("djrcv_dev->paired_dj_devices[dj_report->device_index]"
|
||||
" is NULL, index %d\n", dj_report->device_index);
|
||||
kfifo_in(&djrcv_dev->notif_fifo, dj_report, sizeof(struct dj_report));
|
||||
|
||||
if (schedule_work(&djrcv_dev->work) == 0) {
|
||||
dbg_hid("%s: did not schedule the work item, was already "
|
||||
"queued\n", __func__);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -398,6 +432,12 @@ static void logi_dj_recv_forward_report(struct dj_receiver_dev *djrcv_dev,
|
||||
if (dj_device == NULL) {
|
||||
dbg_hid("djrcv_dev->paired_dj_devices[dj_report->device_index]"
|
||||
" is NULL, index %d\n", dj_report->device_index);
|
||||
kfifo_in(&djrcv_dev->notif_fifo, dj_report, sizeof(struct dj_report));
|
||||
|
||||
if (schedule_work(&djrcv_dev->work) == 0) {
|
||||
dbg_hid("%s: did not schedule the work item, was already "
|
||||
"queued\n", __func__);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -439,6 +479,10 @@ static int logi_dj_recv_query_paired_devices(struct dj_receiver_dev *djrcv_dev)
|
||||
struct dj_report *dj_report;
|
||||
int retval;
|
||||
|
||||
/* no need to protect djrcv_dev->querying_devices */
|
||||
if (djrcv_dev->querying_devices)
|
||||
return 0;
|
||||
|
||||
dj_report = kzalloc(sizeof(struct dj_report), GFP_KERNEL);
|
||||
if (!dj_report)
|
||||
return -ENOMEM;
|
||||
@ -450,6 +494,7 @@ static int logi_dj_recv_query_paired_devices(struct dj_receiver_dev *djrcv_dev)
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
static int logi_dj_recv_switch_to_dj_mode(struct dj_receiver_dev *djrcv_dev,
|
||||
unsigned timeout)
|
||||
{
|
||||
|
@ -101,6 +101,7 @@ struct dj_receiver_dev {
|
||||
struct work_struct work;
|
||||
struct kfifo notif_fifo;
|
||||
spinlock_t lock;
|
||||
bool querying_devices;
|
||||
};
|
||||
|
||||
struct dj_device {
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user