Merge commit 'v3.4-rc6' into android-3.4

Conflicts:
	arch/arm/mm/cache-l2x0.c
	arch/arm/mm/mmu.c

Change-Id: If4f371a21c052fa597d107c44b128a093e4a8b91
This commit is contained in:
Colin Cross 2012-05-07 18:20:34 -07:00
commit f02fac6330
225 changed files with 2292 additions and 1274 deletions

View file

@ -1,10 +1,10 @@
* Calxeda SATA Controller * AHCI SATA Controller
SATA nodes are defined to describe on-chip Serial ATA controllers. SATA nodes are defined to describe on-chip Serial ATA controllers.
Each SATA controller should have its own node. Each SATA controller should have its own node.
Required properties: Required properties:
- compatible : compatible list, contains "calxeda,hb-ahci" - compatible : compatible list, contains "calxeda,hb-ahci" or "snps,spear-ahci"
- interrupts : <interrupt mapping for SATA IRQ> - interrupts : <interrupt mapping for SATA IRQ>
- reg : <registers mapping> - reg : <registers mapping>
@ -14,4 +14,3 @@ Example:
reg = <0xffe08000 0x1000>; reg = <0xffe08000 0x1000>;
interrupts = <115>; interrupts = <115>;
}; };

View file

@ -3,6 +3,8 @@
Required properties: Required properties:
- compatible : "fsl,sgtl5000". - compatible : "fsl,sgtl5000".
- reg : the I2C address of the device
Example: Example:
codec: sgtl5000@0a { codec: sgtl5000@0a {

View file

@ -147,7 +147,7 @@ tcp_adv_win_scale - INTEGER
(if tcp_adv_win_scale > 0) or bytes-bytes/2^(-tcp_adv_win_scale), (if tcp_adv_win_scale > 0) or bytes-bytes/2^(-tcp_adv_win_scale),
if it is <= 0. if it is <= 0.
Possible values are [-31, 31], inclusive. Possible values are [-31, 31], inclusive.
Default: 2 Default: 1
tcp_allowed_congestion_control - STRING tcp_allowed_congestion_control - STRING
Show/set the congestion control choices available to non-privileged Show/set the congestion control choices available to non-privileged
@ -410,7 +410,7 @@ tcp_rmem - vector of 3 INTEGERs: min, default, max
net.core.rmem_max. Calling setsockopt() with SO_RCVBUF disables net.core.rmem_max. Calling setsockopt() with SO_RCVBUF disables
automatic tuning of that socket's receive buffer size, in which automatic tuning of that socket's receive buffer size, in which
case this value is ignored. case this value is ignored.
Default: between 87380B and 4MB, depending on RAM size. Default: between 87380B and 6MB, depending on RAM size.
tcp_sack - BOOLEAN tcp_sack - BOOLEAN
Enable select acknowledgments (SACKS). Enable select acknowledgments (SACKS).

View file

@ -1968,10 +1968,7 @@ S: Maintained
F: drivers/net/ethernet/ti/cpmac.c F: drivers/net/ethernet/ti/cpmac.c
CPU FREQUENCY DRIVERS CPU FREQUENCY DRIVERS
M: Dave Jones <davej@redhat.com>
L: cpufreq@vger.kernel.org L: cpufreq@vger.kernel.org
W: http://www.codemonkey.org.uk/projects/cpufreq/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/davej/cpufreq.git
S: Maintained S: Maintained
F: drivers/cpufreq/ F: drivers/cpufreq/
F: include/linux/cpufreq.h F: include/linux/cpufreq.h
@ -5892,11 +5889,11 @@ F: Documentation/scsi/st.txt
F: drivers/scsi/st* F: drivers/scsi/st*
SCTP PROTOCOL SCTP PROTOCOL
M: Vlad Yasevich <vladislav.yasevich@hp.com> M: Vlad Yasevich <vyasevich@gmail.com>
M: Sridhar Samudrala <sri@us.ibm.com> M: Sridhar Samudrala <sri@us.ibm.com>
L: linux-sctp@vger.kernel.org L: linux-sctp@vger.kernel.org
W: http://lksctp.sourceforge.net W: http://lksctp.sourceforge.net
S: Supported S: Maintained
F: Documentation/networking/sctp.txt F: Documentation/networking/sctp.txt
F: include/linux/sctp.h F: include/linux/sctp.h
F: include/net/sctp/ F: include/net/sctp/

View file

@ -1,7 +1,7 @@
VERSION = 3 VERSION = 3
PATCHLEVEL = 4 PATCHLEVEL = 4
SUBLEVEL = 0 SUBLEVEL = 0
EXTRAVERSION = -rc5 EXTRAVERSION = -rc6
NAME = Saber-toothed Squirrel NAME = Saber-toothed Squirrel
# *DOCUMENTATION* # *DOCUMENTATION*

View file

@ -477,7 +477,7 @@ config ALPHA_BROKEN_IRQ_MASK
config VGA_HOSE config VGA_HOSE
bool bool
depends on ALPHA_GENERIC || ALPHA_TITAN || ALPHA_MARVEL || ALPHA_TSUNAMI depends on VGA_CONSOLE && (ALPHA_GENERIC || ALPHA_TITAN || ALPHA_MARVEL || ALPHA_TSUNAMI)
default y default y
help help
Support VGA on an arbitrary hose; needed for several platforms Support VGA on an arbitrary hose; needed for several platforms

View file

@ -1,14 +1,10 @@
#ifndef _ALPHA_RTC_H #ifndef _ALPHA_RTC_H
#define _ALPHA_RTC_H #define _ALPHA_RTC_H
#if defined(CONFIG_ALPHA_GENERIC) #if defined(CONFIG_ALPHA_MARVEL) && defined(CONFIG_SMP) \
|| defined(CONFIG_ALPHA_GENERIC)
# define get_rtc_time alpha_mv.rtc_get_time # define get_rtc_time alpha_mv.rtc_get_time
# define set_rtc_time alpha_mv.rtc_set_time # define set_rtc_time alpha_mv.rtc_set_time
#else
# if defined(CONFIG_ALPHA_MARVEL) && defined(CONFIG_SMP)
# define get_rtc_time marvel_get_rtc_time
# define set_rtc_time marvel_set_rtc_time
# endif
#endif #endif
#include <asm-generic/rtc.h> #include <asm-generic/rtc.h>

View file

@ -11,6 +11,7 @@
#include <asm/core_tsunami.h> #include <asm/core_tsunami.h>
#undef __EXTERN_INLINE #undef __EXTERN_INLINE
#include <linux/module.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/sched.h> #include <linux/sched.h>

View file

@ -317,7 +317,7 @@ marvel_init_irq(void)
} }
static int static int
marvel_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) marvel_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{ {
struct pci_controller *hose = dev->sysdata; struct pci_controller *hose = dev->sysdata;
struct io7_port *io7_port = hose->sysdata; struct io7_port *io7_port = hose->sysdata;

View file

@ -1186,6 +1186,15 @@ if !MMU
source "arch/arm/Kconfig-nommu" source "arch/arm/Kconfig-nommu"
endif endif
config ARM_ERRATA_326103
bool "ARM errata: FSR write bit incorrect on a SWP to read-only memory"
depends on CPU_V6
help
Executing a SWP instruction to read-only memory does not set bit 11
of the FSR on the ARM 1136 prior to r1p0. This causes the kernel to
treat the access as a read, preventing a COW from occurring and
causing the faulting task to livelock.
config ARM_ERRATA_411920 config ARM_ERRATA_411920
bool "ARM errata: Invalidation of the Instruction Cache operation can fail" bool "ARM errata: Invalidation of the Instruction Cache operation can fail"
depends on CPU_V6 || CPU_V6K depends on CPU_V6 || CPU_V6K

View file

@ -173,7 +173,7 @@
mmc@5000 { mmc@5000 {
compatible = "arm,primecell"; compatible = "arm,primecell";
reg = < 0x5000 0x1000>; reg = < 0x5000 0x1000>;
interrupts = <22>; interrupts = <22 34>;
}; };
kmi@6000 { kmi@6000 {
compatible = "arm,pl050", "arm,primecell"; compatible = "arm,pl050", "arm,primecell";

View file

@ -41,7 +41,7 @@
mmc@b000 { mmc@b000 {
compatible = "arm,primecell"; compatible = "arm,primecell";
reg = <0xb000 0x1000>; reg = <0xb000 0x1000>;
interrupts = <23>; interrupts = <23 34>;
}; };
}; };
}; };

View file

@ -118,6 +118,13 @@ extern void iwmmxt_task_switch(struct thread_info *);
extern void vfp_sync_hwstate(struct thread_info *); extern void vfp_sync_hwstate(struct thread_info *);
extern void vfp_flush_hwstate(struct thread_info *); extern void vfp_flush_hwstate(struct thread_info *);
struct user_vfp;
struct user_vfp_exc;
extern int vfp_preserve_user_clear_hwstate(struct user_vfp __user *,
struct user_vfp_exc __user *);
extern int vfp_restore_user_hwstate(struct user_vfp __user *,
struct user_vfp_exc __user *);
#endif #endif
/* /*

View file

@ -7,6 +7,8 @@
.macro set_tls_v6k, tp, tmp1, tmp2 .macro set_tls_v6k, tp, tmp1, tmp2
mcr p15, 0, \tp, c13, c0, 3 @ set TLS register mcr p15, 0, \tp, c13, c0, 3 @ set TLS register
mov \tmp1, #0
mcr p15, 0, \tmp1, c13, c0, 2 @ clear user r/w TLS register
.endm .endm
.macro set_tls_v6, tp, tmp1, tmp2 .macro set_tls_v6, tp, tmp1, tmp2
@ -15,6 +17,8 @@
mov \tmp2, #0xffff0fff mov \tmp2, #0xffff0fff
tst \tmp1, #HWCAP_TLS @ hardware TLS available? tst \tmp1, #HWCAP_TLS @ hardware TLS available?
mcrne p15, 0, \tp, c13, c0, 3 @ yes, set TLS register mcrne p15, 0, \tp, c13, c0, 3 @ yes, set TLS register
movne \tmp1, #0
mcrne p15, 0, \tmp1, c13, c0, 2 @ clear user r/w TLS register
streq \tp, [\tmp2, #-15] @ set TLS value at 0xffff0ff0 streq \tp, [\tmp2, #-15] @ set TLS value at 0xffff0ff0
.endm .endm

View file

@ -155,10 +155,10 @@ static bool migrate_one_irq(struct irq_desc *desc)
} }
c = irq_data_get_irq_chip(d); c = irq_data_get_irq_chip(d);
if (c->irq_set_affinity) if (!c->irq_set_affinity)
c->irq_set_affinity(d, affinity, true);
else
pr_debug("IRQ%u: unable to set affinity\n", d->irq); pr_debug("IRQ%u: unable to set affinity\n", d->irq);
else if (c->irq_set_affinity(d, affinity, true) == IRQ_SET_MASK_OK && ret)
cpumask_copy(d->affinity, affinity);
return ret; return ret;
} }

View file

@ -180,44 +180,23 @@ static int restore_iwmmxt_context(struct iwmmxt_sigframe *frame)
static int preserve_vfp_context(struct vfp_sigframe __user *frame) static int preserve_vfp_context(struct vfp_sigframe __user *frame)
{ {
struct thread_info *thread = current_thread_info();
struct vfp_hard_struct *h = &thread->vfpstate.hard;
const unsigned long magic = VFP_MAGIC; const unsigned long magic = VFP_MAGIC;
const unsigned long size = VFP_STORAGE_SIZE; const unsigned long size = VFP_STORAGE_SIZE;
int err = 0; int err = 0;
vfp_sync_hwstate(thread);
__put_user_error(magic, &frame->magic, err); __put_user_error(magic, &frame->magic, err);
__put_user_error(size, &frame->size, err); __put_user_error(size, &frame->size, err);
/* if (err)
* Copy the floating point registers. There can be unused return -EFAULT;
* registers see asm/hwcap.h for details.
*/
err |= __copy_to_user(&frame->ufp.fpregs, &h->fpregs,
sizeof(h->fpregs));
/*
* Copy the status and control register.
*/
__put_user_error(h->fpscr, &frame->ufp.fpscr, err);
/* return vfp_preserve_user_clear_hwstate(&frame->ufp, &frame->ufp_exc);
* Copy the exception registers.
*/
__put_user_error(h->fpexc, &frame->ufp_exc.fpexc, err);
__put_user_error(h->fpinst, &frame->ufp_exc.fpinst, err);
__put_user_error(h->fpinst2, &frame->ufp_exc.fpinst2, err);
return err ? -EFAULT : 0;
} }
static int restore_vfp_context(struct vfp_sigframe __user *frame) static int restore_vfp_context(struct vfp_sigframe __user *frame)
{ {
struct thread_info *thread = current_thread_info();
struct vfp_hard_struct *h = &thread->vfpstate.hard;
unsigned long magic; unsigned long magic;
unsigned long size; unsigned long size;
unsigned long fpexc;
int err = 0; int err = 0;
__get_user_error(magic, &frame->magic, err); __get_user_error(magic, &frame->magic, err);
@ -228,33 +207,7 @@ static int restore_vfp_context(struct vfp_sigframe __user *frame)
if (magic != VFP_MAGIC || size != VFP_STORAGE_SIZE) if (magic != VFP_MAGIC || size != VFP_STORAGE_SIZE)
return -EINVAL; return -EINVAL;
vfp_flush_hwstate(thread); return vfp_restore_user_hwstate(&frame->ufp, &frame->ufp_exc);
/*
* Copy the floating point registers. There can be unused
* registers see asm/hwcap.h for details.
*/
err |= __copy_from_user(&h->fpregs, &frame->ufp.fpregs,
sizeof(h->fpregs));
/*
* Copy the status and control register.
*/
__get_user_error(h->fpscr, &frame->ufp.fpscr, err);
/*
* Sanitise and restore the exception registers.
*/
__get_user_error(fpexc, &frame->ufp_exc.fpexc, err);
/* Ensure the VFP is enabled. */
fpexc |= FPEXC_EN;
/* Ensure FPINST2 is invalid and the exception flag is cleared. */
fpexc &= ~(FPEXC_EX | FPEXC_FP2V);
h->fpexc = fpexc;
__get_user_error(h->fpinst, &frame->ufp_exc.fpinst, err);
__get_user_error(h->fpinst2, &frame->ufp_exc.fpinst2, err);
return err ? -EFAULT : 0;
} }
#endif #endif

View file

@ -512,10 +512,6 @@ static void ipi_cpu_stop(unsigned int cpu)
local_fiq_disable(); local_fiq_disable();
local_irq_disable(); local_irq_disable();
#ifdef CONFIG_HOTPLUG_CPU
platform_cpu_kill(cpu);
#endif
while (1) while (1)
cpu_relax(); cpu_relax();
} }
@ -634,17 +630,25 @@ void smp_send_reschedule(int cpu)
smp_cross_call(cpumask_of(cpu), IPI_RESCHEDULE); smp_cross_call(cpumask_of(cpu), IPI_RESCHEDULE);
} }
#ifdef CONFIG_HOTPLUG_CPU
static void smp_kill_cpus(cpumask_t *mask)
{
unsigned int cpu;
for_each_cpu(cpu, mask)
platform_cpu_kill(cpu);
}
#else
static void smp_kill_cpus(cpumask_t *mask) { }
#endif
void smp_send_stop(void) void smp_send_stop(void)
{ {
unsigned long timeout; unsigned long timeout;
if (num_online_cpus() > 1) {
struct cpumask mask; struct cpumask mask;
cpumask_copy(&mask, cpu_online_mask); cpumask_copy(&mask, cpu_online_mask);
cpumask_clear_cpu(smp_processor_id(), &mask); cpumask_clear_cpu(smp_processor_id(), &mask);
smp_cross_call(&mask, IPI_CPU_STOP); smp_cross_call(&mask, IPI_CPU_STOP);
}
/* Wait up to one second for other CPUs to stop */ /* Wait up to one second for other CPUs to stop */
timeout = USEC_PER_SEC; timeout = USEC_PER_SEC;
@ -653,6 +657,8 @@ void smp_send_stop(void)
if (num_online_cpus() > 1) if (num_online_cpus() > 1)
pr_warning("SMP: failed to stop secondary CPUs\n"); pr_warning("SMP: failed to stop secondary CPUs\n");
smp_kill_cpus(&mask);
} }
/* /*

View file

@ -26,18 +26,23 @@ ENTRY(v6_early_abort)
mrc p15, 0, r1, c5, c0, 0 @ get FSR mrc p15, 0, r1, c5, c0, 0 @ get FSR
mrc p15, 0, r0, c6, c0, 0 @ get FAR mrc p15, 0, r0, c6, c0, 0 @ get FAR
/* /*
* Faulty SWP instruction on 1136 doesn't set bit 11 in DFSR (erratum 326103). * Faulty SWP instruction on 1136 doesn't set bit 11 in DFSR.
* The test below covers all the write situations, including Java bytecodes
*/ */
bic r1, r1, #1 << 11 @ clear bit 11 of FSR #ifdef CONFIG_ARM_ERRATA_326103
tst r5, #PSR_J_BIT @ Java? ldr ip, =0x4107b36
mrc p15, 0, r3, c0, c0, 0 @ get processor id
teq ip, r3, lsr #4 @ r0 ARM1136?
bne do_DataAbort bne do_DataAbort
do_thumb_abort fsr=r1, pc=r4, psr=r5, tmp=r3 tst r5, #PSR_J_BIT @ Java?
ldreq r3, [r4] @ read aborted ARM instruction tsteq r5, #PSR_T_BIT @ Thumb?
bne do_DataAbort
bic r1, r1, #1 << 11 @ clear bit 11 of FSR
ldr r3, [r4] @ read aborted ARM instruction
#ifdef CONFIG_CPU_ENDIAN_BE8 #ifdef CONFIG_CPU_ENDIAN_BE8
reveq r3, r3 rev r3, r3
#endif #endif
do_ldrd_abort tmp=ip, insn=r3 do_ldrd_abort tmp=ip, insn=r3
tst r3, #1 << 20 @ L = 0 -> write tst r3, #1 << 20 @ L = 0 -> write
orreq r1, r1, #1 << 11 @ yes. orreq r1, r1, #1 << 11 @ yes.
#endif
b do_DataAbort b do_DataAbort

View file

@ -35,6 +35,7 @@ static u32 l2x0_size;
static u32 l2x0_cache_id; static u32 l2x0_cache_id;
static unsigned int l2x0_sets; static unsigned int l2x0_sets;
static unsigned int l2x0_ways; static unsigned int l2x0_ways;
static unsigned long sync_reg_offset = L2X0_CACHE_SYNC;
static inline bool is_pl310_rev(int rev) static inline bool is_pl310_rev(int rev)
{ {
@ -71,12 +72,7 @@ static inline void cache_sync(void)
{ {
void __iomem *base = l2x0_base; void __iomem *base = l2x0_base;
#ifdef CONFIG_PL310_ERRATA_753970 writel_relaxed(0, base + sync_reg_offset);
/* write to an unmmapped register */
writel_relaxed(0, base + L2X0_DUMMY_REG);
#else
writel_relaxed(0, base + L2X0_CACHE_SYNC);
#endif
cache_wait(base + L2X0_CACHE_SYNC, 1); cache_wait(base + L2X0_CACHE_SYNC, 1);
} }
@ -95,10 +91,13 @@ static inline void l2x0_inv_line(unsigned long addr)
} }
#if defined(CONFIG_PL310_ERRATA_588369) || defined(CONFIG_PL310_ERRATA_727915) #if defined(CONFIG_PL310_ERRATA_588369) || defined(CONFIG_PL310_ERRATA_727915)
static inline void debug_writel(unsigned long val)
{
if (outer_cache.set_debug)
outer_cache.set_debug(val);
}
#define debug_writel(val) outer_cache.set_debug(val) static void pl310_set_debug(unsigned long val)
static void l2x0_set_debug(unsigned long val)
{ {
writel_relaxed(val, l2x0_base + L2X0_DEBUG_CTRL); writel_relaxed(val, l2x0_base + L2X0_DEBUG_CTRL);
} }
@ -108,7 +107,7 @@ static inline void debug_writel(unsigned long val)
{ {
} }
#define l2x0_set_debug NULL #define pl310_set_debug NULL
#endif #endif
#ifdef CONFIG_PL310_ERRATA_588369 #ifdef CONFIG_PL310_ERRATA_588369
@ -372,6 +371,11 @@ void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask)
else else
l2x0_ways = 8; l2x0_ways = 8;
type = "L310"; type = "L310";
#ifdef CONFIG_PL310_ERRATA_753970
/* Unmapped register. */
sync_reg_offset = L2X0_DUMMY_REG;
#endif
outer_cache.set_debug = pl310_set_debug;
break; break;
case L2X0_CACHE_ID_PART_L210: case L2X0_CACHE_ID_PART_L210:
l2x0_ways = (aux >> 13) & 0xf; l2x0_ways = (aux >> 13) & 0xf;
@ -421,7 +425,6 @@ void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask)
outer_cache.flush_all = l2x0_flush_all; outer_cache.flush_all = l2x0_flush_all;
outer_cache.inv_all = l2x0_inv_all; outer_cache.inv_all = l2x0_inv_all;
outer_cache.disable = l2x0_disable; outer_cache.disable = l2x0_disable;
outer_cache.set_debug = l2x0_set_debug;
printk(KERN_INFO "%s cache controller enabled\n", type); printk(KERN_INFO "%s cache controller enabled\n", type);
printk(KERN_INFO "l2x0: %d ways, CACHE_ID 0x%08x, AUX_CTRL 0x%08x, Cache size: %d B\n", printk(KERN_INFO "l2x0: %d ways, CACHE_ID 0x%08x, AUX_CTRL 0x%08x, Cache size: %d B\n",

View file

@ -293,11 +293,11 @@ EXPORT_SYMBOL(pfn_valid);
#endif #endif
#ifndef CONFIG_SPARSEMEM #ifndef CONFIG_SPARSEMEM
static void arm_memory_present(void) static void __init arm_memory_present(void)
{ {
} }
#else #else
static void arm_memory_present(void) static void __init arm_memory_present(void)
{ {
struct memblock_region *reg; struct memblock_region *reg;

View file

@ -639,8 +639,9 @@ static void __init alloc_init_section(pud_t *pud, unsigned long addr,
} }
} }
static void alloc_init_pud(pgd_t *pgd, unsigned long addr, unsigned long end, static void __init alloc_init_pud(pgd_t *pgd, unsigned long addr,
unsigned long phys, const struct mem_type *type, bool force_pages) unsigned long end, unsigned long phys, const struct mem_type *type,
bool force_pages)
{ {
pud_t *pud = pud_offset(pgd, addr); pud_t *pud = pud_offset(pgd, addr);
unsigned long next; unsigned long next;

View file

@ -916,6 +916,13 @@ void omap_start_dma(int lch)
l |= OMAP_DMA_CCR_BUFFERING_DISABLE; l |= OMAP_DMA_CCR_BUFFERING_DISABLE;
l |= OMAP_DMA_CCR_EN; l |= OMAP_DMA_CCR_EN;
/*
* As dma_write() uses IO accessors which are weakly ordered, there
* is no guarantee that data in coherent DMA memory will be visible
* to the DMA device. Add a memory barrier here to ensure that any
* such data is visible prior to enabling DMA.
*/
mb();
p->dma_write(l, CCR, lch); p->dma_write(l, CCR, lch);
dma_chan[lch].flags |= OMAP_DMA_ACTIVE; dma_chan[lch].flags |= OMAP_DMA_ACTIVE;
@ -965,6 +972,13 @@ void omap_stop_dma(int lch)
p->dma_write(l, CCR, lch); p->dma_write(l, CCR, lch);
} }
/*
* Ensure that data transferred by DMA is visible to any access
* after DMA has been disabled. This is important for coherent
* DMA regions.
*/
mb();
if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) { if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) {
int next_lch, cur_lch = lch; int next_lch, cur_lch = lch;
char dma_chan_link_map[dma_lch_count]; char dma_chan_link_map[dma_lch_count];

View file

@ -17,6 +17,8 @@
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/smp.h> #include <linux/smp.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/uaccess.h>
#include <linux/user.h>
#include <asm/cp15.h> #include <asm/cp15.h>
#include <asm/cputype.h> #include <asm/cputype.h>
@ -534,6 +536,103 @@ void vfp_flush_hwstate(struct thread_info *thread)
put_cpu(); put_cpu();
} }
/*
* Save the current VFP state into the provided structures and prepare
* for entry into a new function (signal handler).
*/
int vfp_preserve_user_clear_hwstate(struct user_vfp __user *ufp,
struct user_vfp_exc __user *ufp_exc)
{
struct thread_info *thread = current_thread_info();
struct vfp_hard_struct *hwstate = &thread->vfpstate.hard;
int err = 0;
/* Ensure that the saved hwstate is up-to-date. */
vfp_sync_hwstate(thread);
/*
* Copy the floating point registers. There can be unused
* registers see asm/hwcap.h for details.
*/
err |= __copy_to_user(&ufp->fpregs, &hwstate->fpregs,
sizeof(hwstate->fpregs));
/*
* Copy the status and control register.
*/
__put_user_error(hwstate->fpscr, &ufp->fpscr, err);
/*
* Copy the exception registers.
*/
__put_user_error(hwstate->fpexc, &ufp_exc->fpexc, err);
__put_user_error(hwstate->fpinst, &ufp_exc->fpinst, err);
__put_user_error(hwstate->fpinst2, &ufp_exc->fpinst2, err);
if (err)
return -EFAULT;
/* Ensure that VFP is disabled. */
vfp_flush_hwstate(thread);
/*
* As per the PCS, clear the length and stride bits for function
* entry.
*/
hwstate->fpscr &= ~(FPSCR_LENGTH_MASK | FPSCR_STRIDE_MASK);
/*
* Disable VFP in the hwstate so that we can detect if it gets
* used.
*/
hwstate->fpexc &= ~FPEXC_EN;
return 0;
}
/* Sanitise and restore the current VFP state from the provided structures. */
int vfp_restore_user_hwstate(struct user_vfp __user *ufp,
struct user_vfp_exc __user *ufp_exc)
{
struct thread_info *thread = current_thread_info();
struct vfp_hard_struct *hwstate = &thread->vfpstate.hard;
unsigned long fpexc;
int err = 0;
/*
* If VFP has been used, then disable it to avoid corrupting
* the new thread state.
*/
if (hwstate->fpexc & FPEXC_EN)
vfp_flush_hwstate(thread);
/*
* Copy the floating point registers. There can be unused
* registers see asm/hwcap.h for details.
*/
err |= __copy_from_user(&hwstate->fpregs, &ufp->fpregs,
sizeof(hwstate->fpregs));
/*
* Copy the status and control register.
*/
__get_user_error(hwstate->fpscr, &ufp->fpscr, err);
/*
* Sanitise and restore the exception registers.
*/
__get_user_error(fpexc, &ufp_exc->fpexc, err);
/* Ensure the VFP is enabled. */
fpexc |= FPEXC_EN;
/* Ensure FPINST2 is invalid and the exception flag is cleared. */
fpexc &= ~(FPEXC_EX | FPEXC_FP2V);
hwstate->fpexc = fpexc;
__get_user_error(hwstate->fpinst, &ufp_exc->fpinst, err);
__get_user_error(hwstate->fpinst2, &ufp_exc->fpinst2, err);
return err ? -EFAULT : 0;
}
/* /*
* VFP hardware can lose all context when a CPU goes offline. * VFP hardware can lose all context when a CPU goes offline.
* As we will be running in SMP mode with CPU hotplug, we will save the * As we will be running in SMP mode with CPU hotplug, we will save the

View file

@ -58,8 +58,8 @@ static void __init ar913x_wmac_setup(void)
static int ar933x_wmac_reset(void) static int ar933x_wmac_reset(void)
{ {
ath79_device_reset_clear(AR933X_RESET_WMAC);
ath79_device_reset_set(AR933X_RESET_WMAC); ath79_device_reset_set(AR933X_RESET_WMAC);
ath79_device_reset_clear(AR933X_RESET_WMAC);
return 0; return 0;
} }

View file

@ -45,7 +45,7 @@
#define JZ4740_IRQ_LCD JZ4740_IRQ(30) #define JZ4740_IRQ_LCD JZ4740_IRQ(30)
/* 2nd-level interrupts */ /* 2nd-level interrupts */
#define JZ4740_IRQ_DMA(x) (JZ4740_IRQ(32) + (X)) #define JZ4740_IRQ_DMA(x) (JZ4740_IRQ(32) + (x))
#define JZ4740_IRQ_INTC_GPIO(x) (JZ4740_IRQ_GPIO0 - (x)) #define JZ4740_IRQ_INTC_GPIO(x) (JZ4740_IRQ_GPIO0 - (x))
#define JZ4740_IRQ_GPIO(x) (JZ4740_IRQ(48) + (x)) #define JZ4740_IRQ_GPIO(x) (JZ4740_IRQ(48) + (x))

View file

@ -37,12 +37,6 @@ extern void tlbmiss_handler_setup_pgd(unsigned long pgd);
write_c0_xcontext((unsigned long) smp_processor_id() << 51); \ write_c0_xcontext((unsigned long) smp_processor_id() << 51); \
} while (0) } while (0)
static inline unsigned long get_current_pgd(void)
{
return PHYS_TO_XKSEG_CACHED((read_c0_context() >> 11) & ~0xfffUL);
}
#else /* CONFIG_MIPS_PGD_C0_CONTEXT: using pgd_current*/ #else /* CONFIG_MIPS_PGD_C0_CONTEXT: using pgd_current*/
/* /*

View file

@ -257,11 +257,8 @@ asmlinkage int sys_sigsuspend(nabi_no_regargs struct pt_regs regs)
return -EFAULT; return -EFAULT;
sigdelsetmask(&newset, ~_BLOCKABLE); sigdelsetmask(&newset, ~_BLOCKABLE);
spin_lock_irq(&current->sighand->siglock);
current->saved_sigmask = current->blocked; current->saved_sigmask = current->blocked;
current->blocked = newset; set_current_blocked(&newset);
recalc_sigpending();
spin_unlock_irq(&current->sighand->siglock);
current->state = TASK_INTERRUPTIBLE; current->state = TASK_INTERRUPTIBLE;
schedule(); schedule();
@ -286,11 +283,8 @@ asmlinkage int sys_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
return -EFAULT; return -EFAULT;
sigdelsetmask(&newset, ~_BLOCKABLE); sigdelsetmask(&newset, ~_BLOCKABLE);
spin_lock_irq(&current->sighand->siglock);
current->saved_sigmask = current->blocked; current->saved_sigmask = current->blocked;
current->blocked = newset; set_current_blocked(&newset);
recalc_sigpending();
spin_unlock_irq(&current->sighand->siglock);
current->state = TASK_INTERRUPTIBLE; current->state = TASK_INTERRUPTIBLE;
schedule(); schedule();
@ -362,10 +356,7 @@ asmlinkage void sys_sigreturn(nabi_no_regargs struct pt_regs regs)
goto badframe; goto badframe;
sigdelsetmask(&blocked, ~_BLOCKABLE); sigdelsetmask(&blocked, ~_BLOCKABLE);
spin_lock_irq(&current->sighand->siglock); set_current_blocked(&blocked);
current->blocked = blocked;
recalc_sigpending();
spin_unlock_irq(&current->sighand->siglock);
sig = restore_sigcontext(&regs, &frame->sf_sc); sig = restore_sigcontext(&regs, &frame->sf_sc);
if (sig < 0) if (sig < 0)
@ -401,10 +392,7 @@ asmlinkage void sys_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
goto badframe; goto badframe;
sigdelsetmask(&set, ~_BLOCKABLE); sigdelsetmask(&set, ~_BLOCKABLE);
spin_lock_irq(&current->sighand->siglock); set_current_blocked(&set);
current->blocked = set;
recalc_sigpending();
spin_unlock_irq(&current->sighand->siglock);
sig = restore_sigcontext(&regs, &frame->rs_uc.uc_mcontext); sig = restore_sigcontext(&regs, &frame->rs_uc.uc_mcontext);
if (sig < 0) if (sig < 0)
@ -580,12 +568,7 @@ static int handle_signal(unsigned long sig, siginfo_t *info,
if (ret) if (ret)
return ret; return ret;
spin_lock_irq(&current->sighand->siglock); block_sigmask(ka, sig);
sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask);
if (!(ka->sa.sa_flags & SA_NODEFER))
sigaddset(&current->blocked, sig);
recalc_sigpending();
spin_unlock_irq(&current->sighand->siglock);
return ret; return ret;
} }

View file

@ -290,11 +290,8 @@ asmlinkage int sys32_sigsuspend(nabi_no_regargs struct pt_regs regs)
return -EFAULT; return -EFAULT;
sigdelsetmask(&newset, ~_BLOCKABLE); sigdelsetmask(&newset, ~_BLOCKABLE);
spin_lock_irq(&current->sighand->siglock);
current->saved_sigmask = current->blocked; current->saved_sigmask = current->blocked;
current->blocked = newset; set_current_blocked(&newset);
recalc_sigpending();
spin_unlock_irq(&current->sighand->siglock);
current->state = TASK_INTERRUPTIBLE; current->state = TASK_INTERRUPTIBLE;
schedule(); schedule();
@ -318,11 +315,8 @@ asmlinkage int sys32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
return -EFAULT; return -EFAULT;
sigdelsetmask(&newset, ~_BLOCKABLE); sigdelsetmask(&newset, ~_BLOCKABLE);
spin_lock_irq(&current->sighand->siglock);
current->saved_sigmask = current->blocked; current->saved_sigmask = current->blocked;
current->blocked = newset; set_current_blocked(&newset);
recalc_sigpending();
spin_unlock_irq(&current->sighand->siglock);
current->state = TASK_INTERRUPTIBLE; current->state = TASK_INTERRUPTIBLE;
schedule(); schedule();
@ -488,10 +482,7 @@ asmlinkage void sys32_sigreturn(nabi_no_regargs struct pt_regs regs)
goto badframe; goto badframe;
sigdelsetmask(&blocked, ~_BLOCKABLE); sigdelsetmask(&blocked, ~_BLOCKABLE);
spin_lock_irq(&current->sighand->siglock); set_current_blocked(&blocked);
current->blocked = blocked;
recalc_sigpending();
spin_unlock_irq(&current->sighand->siglock);
sig = restore_sigcontext32(&regs, &frame->sf_sc); sig = restore_sigcontext32(&regs, &frame->sf_sc);
if (sig < 0) if (sig < 0)
@ -529,10 +520,7 @@ asmlinkage void sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
goto badframe; goto badframe;
sigdelsetmask(&set, ~_BLOCKABLE); sigdelsetmask(&set, ~_BLOCKABLE);
spin_lock_irq(&current->sighand->siglock); set_current_blocked(&set);
current->blocked = set;
recalc_sigpending();
spin_unlock_irq(&current->sighand->siglock);
sig = restore_sigcontext32(&regs, &frame->rs_uc.uc_mcontext); sig = restore_sigcontext32(&regs, &frame->rs_uc.uc_mcontext);
if (sig < 0) if (sig < 0)

View file

@ -93,11 +93,8 @@ asmlinkage int sysn32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
sigset_from_compat(&newset, &uset); sigset_from_compat(&newset, &uset);
sigdelsetmask(&newset, ~_BLOCKABLE); sigdelsetmask(&newset, ~_BLOCKABLE);
spin_lock_irq(&current->sighand->siglock);
current->saved_sigmask = current->blocked; current->saved_sigmask = current->blocked;
current->blocked = newset; set_current_blocked(&newset);
recalc_sigpending();
spin_unlock_irq(&current->sighand->siglock);
current->state = TASK_INTERRUPTIBLE; current->state = TASK_INTERRUPTIBLE;
schedule(); schedule();
@ -121,10 +118,7 @@ asmlinkage void sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
goto badframe; goto badframe;
sigdelsetmask(&set, ~_BLOCKABLE); sigdelsetmask(&set, ~_BLOCKABLE);
spin_lock_irq(&current->sighand->siglock); set_current_blocked(&set);
current->blocked = set;
recalc_sigpending();
spin_unlock_irq(&current->sighand->siglock);
sig = restore_sigcontext(&regs, &frame->rs_uc.uc_mcontext); sig = restore_sigcontext(&regs, &frame->rs_uc.uc_mcontext);
if (sig < 0) if (sig < 0)

View file

@ -104,7 +104,7 @@ static int pdc_console_tty_open(struct tty_struct *tty, struct file *filp)
static void pdc_console_tty_close(struct tty_struct *tty, struct file *filp) static void pdc_console_tty_close(struct tty_struct *tty, struct file *filp)
{ {
if (!tty->count) { if (tty->count == 1) {
del_timer_sync(&pdc_console_timer); del_timer_sync(&pdc_console_timer);
tty_port_tty_set(&tty_port, NULL); tty_port_tty_set(&tty_port, NULL);
} }

View file

@ -18,10 +18,6 @@
#include <linux/atomic.h> #include <linux/atomic.h>
/* Define a way to iterate across irqs. */
#define for_each_irq(i) \
for ((i) = 0; (i) < NR_IRQS; ++(i))
extern atomic_t ppc_n_lost_interrupts; extern atomic_t ppc_n_lost_interrupts;
/* This number is used when no interrupt has been assigned */ /* This number is used when no interrupt has been assigned */

View file

@ -330,14 +330,10 @@ void migrate_irqs(void)
alloc_cpumask_var(&mask, GFP_KERNEL); alloc_cpumask_var(&mask, GFP_KERNEL);
for_each_irq(irq) { for_each_irq_desc(irq, desc) {
struct irq_data *data; struct irq_data *data;
struct irq_chip *chip; struct irq_chip *chip;
desc = irq_to_desc(irq);
if (!desc)
continue;
data = irq_desc_get_irq_data(desc); data = irq_desc_get_irq_data(desc);
if (irqd_is_per_cpu(data)) if (irqd_is_per_cpu(data))
continue; continue;

View file

@ -23,14 +23,11 @@
void machine_kexec_mask_interrupts(void) { void machine_kexec_mask_interrupts(void) {
unsigned int i; unsigned int i;
struct irq_desc *desc;
for_each_irq(i) { for_each_irq_desc(i, desc) {
struct irq_desc *desc = irq_to_desc(i);
struct irq_chip *chip; struct irq_chip *chip;
if (!desc)
continue;
chip = irq_desc_get_chip(desc); chip = irq_desc_get_chip(desc);
if (!chip) if (!chip)
continue; continue;

View file

@ -48,7 +48,13 @@
/* /*
* Assembly helpers from arch/powerpc/net/bpf_jit.S: * Assembly helpers from arch/powerpc/net/bpf_jit.S:
*/ */
extern u8 sk_load_word[], sk_load_half[], sk_load_byte[], sk_load_byte_msh[]; #define DECLARE_LOAD_FUNC(func) \
extern u8 func[], func##_negative_offset[], func##_positive_offset[]
DECLARE_LOAD_FUNC(sk_load_word);
DECLARE_LOAD_FUNC(sk_load_half);
DECLARE_LOAD_FUNC(sk_load_byte);
DECLARE_LOAD_FUNC(sk_load_byte_msh);
#define FUNCTION_DESCR_SIZE 24 #define FUNCTION_DESCR_SIZE 24

View file

@ -31,14 +31,13 @@
* then branch directly to slow_path_XXX if required. (In fact, could * then branch directly to slow_path_XXX if required. (In fact, could
* load a spare GPR with the address of slow_path_generic and pass size * load a spare GPR with the address of slow_path_generic and pass size
* as an argument, making the call site a mtlr, li and bllr.) * as an argument, making the call site a mtlr, li and bllr.)
*
* Technically, the "is addr < 0" check is unnecessary & slowing down
* the ABS path, as it's statically checked on generation.
*/ */
.globl sk_load_word .globl sk_load_word
sk_load_word: sk_load_word:
cmpdi r_addr, 0 cmpdi r_addr, 0
blt bpf_error blt bpf_slow_path_word_neg
.globl sk_load_word_positive_offset
sk_load_word_positive_offset:
/* Are we accessing past headlen? */ /* Are we accessing past headlen? */
subi r_scratch1, r_HL, 4 subi r_scratch1, r_HL, 4
cmpd r_scratch1, r_addr cmpd r_scratch1, r_addr
@ -51,7 +50,9 @@ sk_load_word:
.globl sk_load_half .globl sk_load_half
sk_load_half: sk_load_half:
cmpdi r_addr, 0 cmpdi r_addr, 0
blt bpf_error blt bpf_slow_path_half_neg
.globl sk_load_half_positive_offset
sk_load_half_positive_offset:
subi r_scratch1, r_HL, 2 subi r_scratch1, r_HL, 2
cmpd r_scratch1, r_addr cmpd r_scratch1, r_addr
blt bpf_slow_path_half blt bpf_slow_path_half
@ -61,7 +62,9 @@ sk_load_half:
.globl sk_load_byte .globl sk_load_byte
sk_load_byte: sk_load_byte:
cmpdi r_addr, 0 cmpdi r_addr, 0
blt bpf_error blt bpf_slow_path_byte_neg
.globl sk_load_byte_positive_offset
sk_load_byte_positive_offset:
cmpd r_HL, r_addr cmpd r_HL, r_addr
ble bpf_slow_path_byte ble bpf_slow_path_byte
lbzx r_A, r_D, r_addr lbzx r_A, r_D, r_addr
@ -69,22 +72,20 @@ sk_load_byte:
/* /*
* BPF_S_LDX_B_MSH: ldxb 4*([offset]&0xf) * BPF_S_LDX_B_MSH: ldxb 4*([offset]&0xf)
* r_addr is the offset value, already known positive * r_addr is the offset value
*/ */
.globl sk_load_byte_msh .globl sk_load_byte_msh
sk_load_byte_msh: sk_load_byte_msh:
cmpdi r_addr, 0
blt bpf_slow_path_byte_msh_neg
.globl sk_load_byte_msh_positive_offset
sk_load_byte_msh_positive_offset:
cmpd r_HL, r_addr cmpd r_HL, r_addr
ble bpf_slow_path_byte_msh ble bpf_slow_path_byte_msh
lbzx r_X, r_D, r_addr lbzx r_X, r_D, r_addr
rlwinm r_X, r_X, 2, 32-4-2, 31-2 rlwinm r_X, r_X, 2, 32-4-2, 31-2
blr blr
bpf_error:
/* Entered with cr0 = lt */
li r3, 0
/* Generated code will 'blt epilogue', returning 0. */
blr
/* Call out to skb_copy_bits: /* Call out to skb_copy_bits:
* We'll need to back up our volatile regs first; we have * We'll need to back up our volatile regs first; we have
* local variable space at r1+(BPF_PPC_STACK_BASIC). * local variable space at r1+(BPF_PPC_STACK_BASIC).
@ -136,3 +137,84 @@ bpf_slow_path_byte_msh:
lbz r_X, BPF_PPC_STACK_BASIC+(2*8)(r1) lbz r_X, BPF_PPC_STACK_BASIC+(2*8)(r1)
rlwinm r_X, r_X, 2, 32-4-2, 31-2 rlwinm r_X, r_X, 2, 32-4-2, 31-2
blr blr
/* Call out to bpf_internal_load_pointer_neg_helper:
* We'll need to back up our volatile regs first; we have
* local variable space at r1+(BPF_PPC_STACK_BASIC).
* Allocate a new stack frame here to remain ABI-compliant in
* stashing LR.
*/
#define sk_negative_common(SIZE) \
mflr r0; \
std r0, 16(r1); \
/* R3 goes in parameter space of caller's frame */ \
std r_skb, (BPF_PPC_STACKFRAME+48)(r1); \
std r_A, (BPF_PPC_STACK_BASIC+(0*8))(r1); \
std r_X, (BPF_PPC_STACK_BASIC+(1*8))(r1); \
stdu r1, -BPF_PPC_SLOWPATH_FRAME(r1); \
/* R3 = r_skb, as passed */ \
mr r4, r_addr; \
li r5, SIZE; \
bl bpf_internal_load_pointer_neg_helper; \
/* R3 != 0 on success */ \
addi r1, r1, BPF_PPC_SLOWPATH_FRAME; \
ld r0, 16(r1); \
ld r_A, (BPF_PPC_STACK_BASIC+(0*8))(r1); \
ld r_X, (BPF_PPC_STACK_BASIC+(1*8))(r1); \
mtlr r0; \
cmpldi r3, 0; \
beq bpf_error_slow; /* cr0 = EQ */ \
mr r_addr, r3; \
ld r_skb, (BPF_PPC_STACKFRAME+48)(r1); \
/* Great success! */
bpf_slow_path_word_neg:
lis r_scratch1,-32 /* SKF_LL_OFF */
cmpd r_addr, r_scratch1 /* addr < SKF_* */
blt bpf_error /* cr0 = LT */
.globl sk_load_word_negative_offset
sk_load_word_negative_offset:
sk_negative_common(4)
lwz r_A, 0(r_addr)
blr
bpf_slow_path_half_neg:
lis r_scratch1,-32 /* SKF_LL_OFF */
cmpd r_addr, r_scratch1 /* addr < SKF_* */
blt bpf_error /* cr0 = LT */
.globl sk_load_half_negative_offset
sk_load_half_negative_offset:
sk_negative_common(2)
lhz r_A, 0(r_addr)
blr
bpf_slow_path_byte_neg:
lis r_scratch1,-32 /* SKF_LL_OFF */
cmpd r_addr, r_scratch1 /* addr < SKF_* */
blt bpf_error /* cr0 = LT */
.globl sk_load_byte_negative_offset
sk_load_byte_negative_offset:
sk_negative_common(1)
lbz r_A, 0(r_addr)
blr
bpf_slow_path_byte_msh_neg:
lis r_scratch1,-32 /* SKF_LL_OFF */
cmpd r_addr, r_scratch1 /* addr < SKF_* */
blt bpf_error /* cr0 = LT */
.globl sk_load_byte_msh_negative_offset
sk_load_byte_msh_negative_offset:
sk_negative_common(1)
lbz r_X, 0(r_addr)
rlwinm r_X, r_X, 2, 32-4-2, 31-2
blr
bpf_error_slow:
/* fabricate a cr0 = lt */
li r_scratch1, -1
cmpdi r_scratch1, 0
bpf_error:
/* Entered with cr0 = lt */
li r3, 0
/* Generated code will 'blt epilogue', returning 0. */
blr

View file

@ -127,6 +127,9 @@ static void bpf_jit_build_epilogue(u32 *image, struct codegen_context *ctx)
PPC_BLR(); PPC_BLR();
} }
#define CHOOSE_LOAD_FUNC(K, func) \
((int)K < 0 ? ((int)K >= SKF_LL_OFF ? func##_negative_offset : func) : func##_positive_offset)
/* Assemble the body code between the prologue & epilogue. */ /* Assemble the body code between the prologue & epilogue. */
static int bpf_jit_build_body(struct sk_filter *fp, u32 *image, static int bpf_jit_build_body(struct sk_filter *fp, u32 *image,
struct codegen_context *ctx, struct codegen_context *ctx,
@ -391,21 +394,16 @@ static int bpf_jit_build_body(struct sk_filter *fp, u32 *image,
/*** Absolute loads from packet header/data ***/ /*** Absolute loads from packet header/data ***/
case BPF_S_LD_W_ABS: case BPF_S_LD_W_ABS:
func = sk_load_word; func = CHOOSE_LOAD_FUNC(K, sk_load_word);
goto common_load; goto common_load;
case BPF_S_LD_H_ABS: case BPF_S_LD_H_ABS:
func = sk_load_half; func = CHOOSE_LOAD_FUNC(K, sk_load_half);
goto common_load; goto common_load;
case BPF_S_LD_B_ABS: case BPF_S_LD_B_ABS:
func = sk_load_byte; func = CHOOSE_LOAD_FUNC(K, sk_load_byte);
common_load: common_load:
/* /* Load from [K]. */
* Load from [K]. Reference with the (negative)
* SKF_NET_OFF/SKF_LL_OFF offsets is unsupported.
*/
ctx->seen |= SEEN_DATAREF; ctx->seen |= SEEN_DATAREF;
if ((int)K < 0)
return -ENOTSUPP;
PPC_LI64(r_scratch1, func); PPC_LI64(r_scratch1, func);
PPC_MTLR(r_scratch1); PPC_MTLR(r_scratch1);
PPC_LI32(r_addr, K); PPC_LI32(r_addr, K);
@ -429,7 +427,7 @@ static int bpf_jit_build_body(struct sk_filter *fp, u32 *image,
common_load_ind: common_load_ind:
/* /*
* Load from [X + K]. Negative offsets are tested for * Load from [X + K]. Negative offsets are tested for
* in the helper functions, and result in a 'ret 0'. * in the helper functions.
*/ */
ctx->seen |= SEEN_DATAREF | SEEN_XREG; ctx->seen |= SEEN_DATAREF | SEEN_XREG;
PPC_LI64(r_scratch1, func); PPC_LI64(r_scratch1, func);
@ -443,13 +441,7 @@ static int bpf_jit_build_body(struct sk_filter *fp, u32 *image,
break; break;
case BPF_S_LDX_B_MSH: case BPF_S_LDX_B_MSH:
/* func = CHOOSE_LOAD_FUNC(K, sk_load_byte_msh);
* x86 version drops packet (RET 0) when K<0, whereas
* interpreter does allow K<0 (__load_pointer, special
* ancillary data). common_load returns ENOTSUPP if K<0,
* so we fall back to interpreter & filter works.
*/
func = sk_load_byte_msh;
goto common_load; goto common_load;
break; break;

View file

@ -114,7 +114,7 @@ static void axon_msi_cascade(unsigned int irq, struct irq_desc *desc)
pr_devel("axon_msi: woff %x roff %x msi %x\n", pr_devel("axon_msi: woff %x roff %x msi %x\n",
write_offset, msic->read_offset, msi); write_offset, msic->read_offset, msi);
if (msi < NR_IRQS && irq_get_chip_data(msi) == msic) { if (msi < nr_irqs && irq_get_chip_data(msi) == msic) {
generic_handle_irq(msi); generic_handle_irq(msi);
msic->fifo_virt[idx] = cpu_to_le32(0xffffffff); msic->fifo_virt[idx] = cpu_to_le32(0xffffffff);
} else { } else {
@ -276,9 +276,6 @@ static int axon_msi_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
if (rc) if (rc)
return rc; return rc;
/* We rely on being able to stash a virq in a u16 */
BUILD_BUG_ON(NR_IRQS > 65536);
list_for_each_entry(entry, &dev->msi_list, list) { list_for_each_entry(entry, &dev->msi_list, list) {
virq = irq_create_direct_mapping(msic->irq_domain); virq = irq_create_direct_mapping(msic->irq_domain);
if (virq == NO_IRQ) { if (virq == NO_IRQ) {
@ -392,7 +389,8 @@ static int axon_msi_probe(struct platform_device *device)
} }
memset(msic->fifo_virt, 0xff, MSIC_FIFO_SIZE_BYTES); memset(msic->fifo_virt, 0xff, MSIC_FIFO_SIZE_BYTES);
msic->irq_domain = irq_domain_add_nomap(dn, 0, &msic_host_ops, msic); /* We rely on being able to stash a virq in a u16, so limit irqs to < 65536 */
msic->irq_domain = irq_domain_add_nomap(dn, 65536, &msic_host_ops, msic);
if (!msic->irq_domain) { if (!msic->irq_domain) {
printk(KERN_ERR "axon_msi: couldn't allocate irq_domain for %s\n", printk(KERN_ERR "axon_msi: couldn't allocate irq_domain for %s\n",
dn->full_name); dn->full_name);

View file

@ -248,6 +248,6 @@ void beatic_deinit_IRQ(void)
{ {
int i; int i;
for (i = 1; i < NR_IRQS; i++) for (i = 1; i < nr_irqs; i++)
beat_destruct_irq_plug(i); beat_destruct_irq_plug(i);
} }

View file

@ -57,9 +57,9 @@ static int max_real_irqs;
static DEFINE_RAW_SPINLOCK(pmac_pic_lock); static DEFINE_RAW_SPINLOCK(pmac_pic_lock);
#define NR_MASK_WORDS ((NR_IRQS + 31) / 32) /* The max irq number this driver deals with is 128; see max_irqs */
static unsigned long ppc_lost_interrupts[NR_MASK_WORDS]; static DECLARE_BITMAP(ppc_lost_interrupts, 128);
static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS]; static DECLARE_BITMAP(ppc_cached_irq_mask, 128);
static int pmac_irq_cascade = -1; static int pmac_irq_cascade = -1;
static struct irq_domain *pmac_pic_host; static struct irq_domain *pmac_pic_host;

View file

@ -30,9 +30,9 @@ config PPC_SPLPAR
two or more partitions. two or more partitions.
config EEH config EEH
bool "PCI Extended Error Handling (EEH)" if EXPERT bool
depends on PPC_PSERIES && PCI depends on PPC_PSERIES && PCI
default y if !EXPERT default y
config PSERIES_MSI config PSERIES_MSI
bool bool

View file

@ -51,8 +51,7 @@
static intctl_cpm2_t __iomem *cpm2_intctl; static intctl_cpm2_t __iomem *cpm2_intctl;
static struct irq_domain *cpm2_pic_host; static struct irq_domain *cpm2_pic_host;
#define NR_MASK_WORDS ((NR_IRQS + 31) / 32) static unsigned long ppc_cached_irq_mask[2]; /* 2 32-bit registers */
static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS];
static const u_char irq_to_siureg[] = { static const u_char irq_to_siureg[] = {
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,

View file

@ -18,70 +18,46 @@
extern int cpm_get_irq(struct pt_regs *regs); extern int cpm_get_irq(struct pt_regs *regs);
static struct irq_domain *mpc8xx_pic_host; static struct irq_domain *mpc8xx_pic_host;
#define NR_MASK_WORDS ((NR_IRQS + 31) / 32) static unsigned long mpc8xx_cached_irq_mask;
static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS];
static sysconf8xx_t __iomem *siu_reg; static sysconf8xx_t __iomem *siu_reg;
int cpm_get_irq(struct pt_regs *regs); static inline unsigned long mpc8xx_irqd_to_bit(struct irq_data *d)
{
return 0x80000000 >> irqd_to_hwirq(d);
}
static void mpc8xx_unmask_irq(struct irq_data *d) static void mpc8xx_unmask_irq(struct irq_data *d)
{ {
int bit, word; mpc8xx_cached_irq_mask |= mpc8xx_irqd_to_bit(d);
unsigned int irq_nr = (unsigned int)irqd_to_hwirq(d); out_be32(&siu_reg->sc_simask, mpc8xx_cached_irq_mask);
bit = irq_nr & 0x1f;
word = irq_nr >> 5;
ppc_cached_irq_mask[word] |= (1 << (31-bit));
out_be32(&siu_reg->sc_simask, ppc_cached_irq_mask[word]);
} }
static void mpc8xx_mask_irq(struct irq_data *d) static void mpc8xx_mask_irq(struct irq_data *d)
{ {
int bit, word; mpc8xx_cached_irq_mask &= ~mpc8xx_irqd_to_bit(d);
unsigned int irq_nr = (unsigned int)irqd_to_hwirq(d); out_be32(&siu_reg->sc_simask, mpc8xx_cached_irq_mask);
bit = irq_nr & 0x1f;
word = irq_nr >> 5;
ppc_cached_irq_mask[word] &= ~(1 << (31-bit));
out_be32(&siu_reg->sc_simask, ppc_cached_irq_mask[word]);
} }
static void mpc8xx_ack(struct irq_data *d) static void mpc8xx_ack(struct irq_data *d)
{ {
int bit; out_be32(&siu_reg->sc_sipend, mpc8xx_irqd_to_bit(d));
unsigned int irq_nr = (unsigned int)irqd_to_hwirq(d);
bit = irq_nr & 0x1f;
out_be32(&siu_reg->sc_sipend, 1 << (31-bit));
} }
static void mpc8xx_end_irq(struct irq_data *d) static void mpc8xx_end_irq(struct irq_data *d)
{ {
int bit, word; mpc8xx_cached_irq_mask |= mpc8xx_irqd_to_bit(d);
unsigned int irq_nr = (unsigned int)irqd_to_hwirq(d); out_be32(&siu_reg->sc_simask, mpc8xx_cached_irq_mask);
bit = irq_nr & 0x1f;
word = irq_nr >> 5;
ppc_cached_irq_mask[word] |= (1 << (31-bit));
out_be32(&siu_reg->sc_simask, ppc_cached_irq_mask[word]);
} }
static int mpc8xx_set_irq_type(struct irq_data *d, unsigned int flow_type) static int mpc8xx_set_irq_type(struct irq_data *d, unsigned int flow_type)
{ {
if (flow_type & IRQ_TYPE_EDGE_FALLING) {
irq_hw_number_t hw = (unsigned int)irqd_to_hwirq(d);
unsigned int siel = in_be32(&siu_reg->sc_siel);
/* only external IRQ senses are programmable */ /* only external IRQ senses are programmable */
if ((hw & 1) == 0) { if ((flow_type & IRQ_TYPE_EDGE_FALLING) && !(irqd_to_hwirq(d) & 1)) {
siel |= (0x80000000 >> hw); unsigned int siel = in_be32(&siu_reg->sc_siel);
siel |= mpc8xx_irqd_to_bit(d);
out_be32(&siu_reg->sc_siel, siel); out_be32(&siu_reg->sc_siel, siel);
__irq_set_handler_locked(d->irq, handle_edge_irq); __irq_set_handler_locked(d->irq, handle_edge_irq);
} }
}
return 0; return 0;
} }
@ -132,6 +108,9 @@ static int mpc8xx_pic_host_xlate(struct irq_domain *h, struct device_node *ct,
IRQ_TYPE_EDGE_FALLING, IRQ_TYPE_EDGE_FALLING,
}; };
if (intspec[0] > 0x1f)
return 0;
*out_hwirq = intspec[0]; *out_hwirq = intspec[0];
if (intsize > 1 && intspec[1] < 4) if (intsize > 1 && intspec[1] < 4)
*out_flags = map_pic_senses[intspec[1]]; *out_flags = map_pic_senses[intspec[1]];

View file

@ -188,6 +188,7 @@ void xics_migrate_irqs_away(void)
{ {
int cpu = smp_processor_id(), hw_cpu = hard_smp_processor_id(); int cpu = smp_processor_id(), hw_cpu = hard_smp_processor_id();
unsigned int irq, virq; unsigned int irq, virq;
struct irq_desc *desc;
/* If we used to be the default server, move to the new "boot_cpuid" */ /* If we used to be the default server, move to the new "boot_cpuid" */
if (hw_cpu == xics_default_server) if (hw_cpu == xics_default_server)
@ -202,8 +203,7 @@ void xics_migrate_irqs_away(void)
/* Allow IPIs again... */ /* Allow IPIs again... */
icp_ops->set_priority(DEFAULT_PRIORITY); icp_ops->set_priority(DEFAULT_PRIORITY);
for_each_irq(virq) { for_each_irq_desc(virq, desc) {
struct irq_desc *desc;
struct irq_chip *chip; struct irq_chip *chip;
long server; long server;
unsigned long flags; unsigned long flags;
@ -212,9 +212,8 @@ void xics_migrate_irqs_away(void)
/* We can't set affinity on ISA interrupts */ /* We can't set affinity on ISA interrupts */
if (virq < NUM_ISA_INTERRUPTS) if (virq < NUM_ISA_INTERRUPTS)
continue; continue;
desc = irq_to_desc(virq);
/* We only need to migrate enabled IRQS */ /* We only need to migrate enabled IRQS */
if (!desc || !desc->action) if (!desc->action)
continue; continue;
if (desc->irq_data.domain != xics_host) if (desc->irq_data.domain != xics_host)
continue; continue;

View file

@ -81,7 +81,7 @@ config X86
select CLKEVT_I8253 select CLKEVT_I8253
select ARCH_HAVE_NMI_SAFE_CMPXCHG select ARCH_HAVE_NMI_SAFE_CMPXCHG
select GENERIC_IOMAP select GENERIC_IOMAP
select DCACHE_WORD_ACCESS if !DEBUG_PAGEALLOC select DCACHE_WORD_ACCESS
config INSTRUCTION_DECODER config INSTRUCTION_DECODER
def_bool (KPROBES || PERF_EVENTS) def_bool (KPROBES || PERF_EVENTS)

View file

@ -403,13 +403,11 @@ static void print_absolute_symbols(void)
for (i = 0; i < ehdr.e_shnum; i++) { for (i = 0; i < ehdr.e_shnum; i++) {
struct section *sec = &secs[i]; struct section *sec = &secs[i];
char *sym_strtab; char *sym_strtab;
Elf32_Sym *sh_symtab;
int j; int j;
if (sec->shdr.sh_type != SHT_SYMTAB) { if (sec->shdr.sh_type != SHT_SYMTAB) {
continue; continue;
} }
sh_symtab = sec->symtab;
sym_strtab = sec->link->strtab; sym_strtab = sec->link->strtab;
for (j = 0; j < sec->shdr.sh_size/sizeof(Elf32_Sym); j++) { for (j = 0; j < sec->shdr.sh_size/sizeof(Elf32_Sym); j++) {
Elf32_Sym *sym; Elf32_Sym *sym;

View file

@ -294,8 +294,7 @@ static int load_aout_binary(struct linux_binprm *bprm, struct pt_regs *regs)
/* OK, This is the point of no return */ /* OK, This is the point of no return */
set_personality(PER_LINUX); set_personality(PER_LINUX);
set_thread_flag(TIF_IA32); set_personality_ia32(false);
current->mm->context.ia32_compat = 1;
setup_new_exec(bprm); setup_new_exec(bprm);

View file

@ -43,4 +43,37 @@ static inline unsigned long has_zero(unsigned long a)
return ((a - REPEAT_BYTE(0x01)) & ~a) & REPEAT_BYTE(0x80); return ((a - REPEAT_BYTE(0x01)) & ~a) & REPEAT_BYTE(0x80);
} }
/*
* Load an unaligned word from kernel space.
*
* In the (very unlikely) case of the word being a page-crosser
* and the next page not being mapped, take the exception and
* return zeroes in the non-existing part.
*/
static inline unsigned long load_unaligned_zeropad(const void *addr)
{
unsigned long ret, dummy;
asm(
"1:\tmov %2,%0\n"
"2:\n"
".section .fixup,\"ax\"\n"
"3:\t"
"lea %2,%1\n\t"
"and %3,%1\n\t"
"mov (%1),%0\n\t"
"leal %2,%%ecx\n\t"
"andl %4,%%ecx\n\t"
"shll $3,%%ecx\n\t"
"shr %%cl,%0\n\t"
"jmp 2b\n"
".previous\n"
_ASM_EXTABLE(1b, 3b)
:"=&r" (ret),"=&c" (dummy)
:"m" (*(unsigned long *)addr),
"i" (-sizeof(unsigned long)),
"i" (sizeof(unsigned long)-1));
return ret;
}
#endif /* _ASM_WORD_AT_A_TIME_H */ #endif /* _ASM_WORD_AT_A_TIME_H */

View file

@ -580,6 +580,24 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c)
} }
} }
/* re-enable TopologyExtensions if switched off by BIOS */
if ((c->x86 == 0x15) &&
(c->x86_model >= 0x10) && (c->x86_model <= 0x1f) &&
!cpu_has(c, X86_FEATURE_TOPOEXT)) {
u64 val;
if (!rdmsrl_amd_safe(0xc0011005, &val)) {
val |= 1ULL << 54;
wrmsrl_amd_safe(0xc0011005, val);
rdmsrl(0xc0011005, val);
if (val & (1ULL << 54)) {
set_cpu_cap(c, X86_FEATURE_TOPOEXT);
printk(KERN_INFO FW_INFO "CPU: Re-enabling "
"disabled Topology Extensions Support\n");
}
}
}
cpu_detect_cache_sizes(c); cpu_detect_cache_sizes(c);
/* Multi core CPU? */ /* Multi core CPU? */

View file

@ -63,7 +63,7 @@ static struct gpio_led net5501_leds[] = {
.name = "net5501:1", .name = "net5501:1",
.gpio = 6, .gpio = 6,
.default_trigger = "default-on", .default_trigger = "default-on",
.active_low = 1, .active_low = 0,
}, },
}; };

View file

@ -631,7 +631,7 @@ int acpi_power_get_inferred_state(struct acpi_device *device, int *state)
* We know a device's inferred power state when all the resources * We know a device's inferred power state when all the resources
* required for a given D-state are 'on'. * required for a given D-state are 'on'.
*/ */
for (i = ACPI_STATE_D0; i < ACPI_STATE_D3; i++) { for (i = ACPI_STATE_D0; i < ACPI_STATE_D3_HOT; i++) {
list = &device->power.states[i].resources; list = &device->power.states[i].resources;
if (list->count < 1) if (list->count < 1)
continue; continue;

View file

@ -869,7 +869,7 @@ static int acpi_bus_get_power_flags(struct acpi_device *device)
/* /*
* Enumerate supported power management states * Enumerate supported power management states
*/ */
for (i = ACPI_STATE_D0; i <= ACPI_STATE_D3; i++) { for (i = ACPI_STATE_D0; i <= ACPI_STATE_D3_HOT; i++) {
struct acpi_device_power_state *ps = &device->power.states[i]; struct acpi_device_power_state *ps = &device->power.states[i];
char object_name[5] = { '_', 'P', 'R', '0' + i, '\0' }; char object_name[5] = { '_', 'P', 'R', '0' + i, '\0' };
@ -884,21 +884,18 @@ static int acpi_bus_get_power_flags(struct acpi_device *device)
acpi_bus_add_power_resource(ps->resources.handles[j]); acpi_bus_add_power_resource(ps->resources.handles[j]);
} }
/* The exist of _PR3 indicates D3Cold support */
if (i == ACPI_STATE_D3) {
status = acpi_get_handle(device->handle, object_name, &handle);
if (ACPI_SUCCESS(status))
device->power.states[ACPI_STATE_D3_COLD].flags.valid = 1;
}
/* Evaluate "_PSx" to see if we can do explicit sets */ /* Evaluate "_PSx" to see if we can do explicit sets */
object_name[2] = 'S'; object_name[2] = 'S';
status = acpi_get_handle(device->handle, object_name, &handle); status = acpi_get_handle(device->handle, object_name, &handle);
if (ACPI_SUCCESS(status)) if (ACPI_SUCCESS(status))
ps->flags.explicit_set = 1; ps->flags.explicit_set = 1;
/* State is valid if we have some power control */ /*
if (ps->resources.count || ps->flags.explicit_set) * State is valid if there are means to put the device into it.
* D3hot is only valid if _PR3 present.
*/
if (ps->resources.count ||
(ps->flags.explicit_set && i < ACPI_STATE_D3_HOT))
ps->flags.valid = 1; ps->flags.valid = 1;
ps->power = -1; /* Unknown - driver assigned */ ps->power = -1; /* Unknown - driver assigned */

View file

@ -394,6 +394,8 @@ static const struct pci_device_id ahci_pci_tbl[] = {
.driver_data = board_ahci_yes_fbs }, /* 88se9128 */ .driver_data = board_ahci_yes_fbs }, /* 88se9128 */
{ PCI_DEVICE(0x1b4b, 0x9125), { PCI_DEVICE(0x1b4b, 0x9125),
.driver_data = board_ahci_yes_fbs }, /* 88se9125 */ .driver_data = board_ahci_yes_fbs }, /* 88se9125 */
{ PCI_DEVICE(0x1b4b, 0x917a),
.driver_data = board_ahci_yes_fbs }, /* 88se9172 */
{ PCI_DEVICE(0x1b4b, 0x91a3), { PCI_DEVICE(0x1b4b, 0x91a3),
.driver_data = board_ahci_yes_fbs }, .driver_data = board_ahci_yes_fbs },

View file

@ -280,6 +280,7 @@ static struct dev_pm_ops ahci_pm_ops = {
static const struct of_device_id ahci_of_match[] = { static const struct of_device_id ahci_of_match[] = {
{ .compatible = "calxeda,hb-ahci", }, { .compatible = "calxeda,hb-ahci", },
{ .compatible = "snps,spear-ahci", },
{}, {},
}; };
MODULE_DEVICE_TABLE(of, ahci_of_match); MODULE_DEVICE_TABLE(of, ahci_of_match);

View file

@ -95,7 +95,7 @@ static unsigned int ata_dev_set_xfermode(struct ata_device *dev);
static void ata_dev_xfermask(struct ata_device *dev); static void ata_dev_xfermask(struct ata_device *dev);
static unsigned long ata_dev_blacklisted(const struct ata_device *dev); static unsigned long ata_dev_blacklisted(const struct ata_device *dev);
atomic_t ata_print_id = ATOMIC_INIT(1); atomic_t ata_print_id = ATOMIC_INIT(0);
struct ata_force_param { struct ata_force_param {
const char *name; const char *name;

View file

@ -3501,7 +3501,8 @@ static int ata_count_probe_trials_cb(struct ata_ering_entry *ent, void *void_arg
u64 now = get_jiffies_64(); u64 now = get_jiffies_64();
int *trials = void_arg; int *trials = void_arg;
if (ent->timestamp < now - min(now, interval)) if ((ent->eflags & ATA_EFLAG_OLD_ER) ||
(ent->timestamp < now - min(now, interval)))
return -1; return -1;
(*trials)++; (*trials)++;

View file

@ -3399,7 +3399,8 @@ int ata_scsi_add_hosts(struct ata_host *host, struct scsi_host_template *sht)
*/ */
shost->max_host_blocked = 1; shost->max_host_blocked = 1;
rc = scsi_add_host(ap->scsi_host, &ap->tdev); rc = scsi_add_host_with_dma(ap->scsi_host,
&ap->tdev, ap->host->dev);
if (rc) if (rc)
goto err_add; goto err_add;
} }
@ -3838,18 +3839,25 @@ void ata_sas_port_stop(struct ata_port *ap)
} }
EXPORT_SYMBOL_GPL(ata_sas_port_stop); EXPORT_SYMBOL_GPL(ata_sas_port_stop);
int ata_sas_async_port_init(struct ata_port *ap) /**
* ata_sas_async_probe - simply schedule probing and return
* @ap: Port to probe
*
* For batch scheduling of probe for sas attached ata devices, assumes
* the port has already been through ata_sas_port_init()
*/
void ata_sas_async_probe(struct ata_port *ap)
{ {
int rc = ap->ops->port_start(ap);
if (!rc) {
ap->print_id = atomic_inc_return(&ata_print_id);
__ata_port_probe(ap); __ata_port_probe(ap);
} }
EXPORT_SYMBOL_GPL(ata_sas_async_probe);
return rc; int ata_sas_sync_probe(struct ata_port *ap)
{
return ata_port_probe(ap);
} }
EXPORT_SYMBOL_GPL(ata_sas_async_port_init); EXPORT_SYMBOL_GPL(ata_sas_sync_probe);
/** /**
* ata_sas_port_init - Initialize a SATA device * ata_sas_port_init - Initialize a SATA device
@ -3866,12 +3874,10 @@ int ata_sas_port_init(struct ata_port *ap)
{ {
int rc = ap->ops->port_start(ap); int rc = ap->ops->port_start(ap);
if (!rc) { if (rc)
ap->print_id = atomic_inc_return(&ata_print_id);
rc = ata_port_probe(ap);
}
return rc; return rc;
ap->print_id = atomic_inc_return(&ata_print_id);
return 0;
} }
EXPORT_SYMBOL_GPL(ata_sas_port_init); EXPORT_SYMBOL_GPL(ata_sas_port_init);

View file

@ -943,9 +943,9 @@ static int arasan_cf_resume(struct device *dev)
return 0; return 0;
} }
#endif
static SIMPLE_DEV_PM_OPS(arasan_cf_pm_ops, arasan_cf_suspend, arasan_cf_resume); static SIMPLE_DEV_PM_OPS(arasan_cf_pm_ops, arasan_cf_suspend, arasan_cf_resume);
#endif
static struct platform_driver arasan_cf_driver = { static struct platform_driver arasan_cf_driver = {
.probe = arasan_cf_probe, .probe = arasan_cf_probe,
@ -953,9 +953,7 @@ static struct platform_driver arasan_cf_driver = {
.driver = { .driver = {
.name = DRIVER_NAME, .name = DRIVER_NAME,
.owner = THIS_MODULE, .owner = THIS_MODULE,
#ifdef CONFIG_PM
.pm = &arasan_cf_pm_ops, .pm = &arasan_cf_pm_ops,
#endif
}, },
}; };

View file

@ -75,6 +75,8 @@ static struct usb_device_id ath3k_table[] = {
{ USB_DEVICE(0x0CF3, 0x311D) }, { USB_DEVICE(0x0CF3, 0x311D) },
{ USB_DEVICE(0x13d3, 0x3375) }, { USB_DEVICE(0x13d3, 0x3375) },
{ USB_DEVICE(0x04CA, 0x3005) }, { USB_DEVICE(0x04CA, 0x3005) },
{ USB_DEVICE(0x13d3, 0x3362) },
{ USB_DEVICE(0x0CF3, 0xE004) },
/* Atheros AR5BBU12 with sflash firmware */ /* Atheros AR5BBU12 with sflash firmware */
{ USB_DEVICE(0x0489, 0xE02C) }, { USB_DEVICE(0x0489, 0xE02C) },
@ -94,6 +96,8 @@ static struct usb_device_id ath3k_blist_tbl[] = {
{ USB_DEVICE(0x0cf3, 0x311D), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0x311D), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },
{ } /* Terminating entry */ { } /* Terminating entry */
}; };

View file

@ -101,12 +101,16 @@ static struct usb_device_id btusb_table[] = {
{ USB_DEVICE(0x0c10, 0x0000) }, { USB_DEVICE(0x0c10, 0x0000) },
/* Broadcom BCM20702A0 */ /* Broadcom BCM20702A0 */
{ USB_DEVICE(0x0489, 0xe042) },
{ USB_DEVICE(0x0a5c, 0x21e3) }, { USB_DEVICE(0x0a5c, 0x21e3) },
{ USB_DEVICE(0x0a5c, 0x21e6) }, { USB_DEVICE(0x0a5c, 0x21e6) },
{ USB_DEVICE(0x0a5c, 0x21e8) }, { USB_DEVICE(0x0a5c, 0x21e8) },
{ USB_DEVICE(0x0a5c, 0x21f3) }, { USB_DEVICE(0x0a5c, 0x21f3) },
{ USB_DEVICE(0x413c, 0x8197) }, { USB_DEVICE(0x413c, 0x8197) },
/* Foxconn - Hon Hai */
{ USB_DEVICE(0x0489, 0xe033) },
{ } /* Terminating entry */ { } /* Terminating entry */
}; };
@ -133,6 +137,8 @@ static struct usb_device_id blacklist_table[] = {
{ USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },
/* Atheros AR5BBU12 with sflash firmware */ /* Atheros AR5BBU12 with sflash firmware */
{ USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE }, { USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE },

View file

@ -191,6 +191,190 @@ utf16_strncmp(const efi_char16_t *a, const efi_char16_t *b, size_t len)
} }
} }
static bool
validate_device_path(struct efi_variable *var, int match, u8 *buffer,
unsigned long len)
{
struct efi_generic_dev_path *node;
int offset = 0;
node = (struct efi_generic_dev_path *)buffer;
if (len < sizeof(*node))
return false;
while (offset <= len - sizeof(*node) &&
node->length >= sizeof(*node) &&
node->length <= len - offset) {
offset += node->length;
if ((node->type == EFI_DEV_END_PATH ||
node->type == EFI_DEV_END_PATH2) &&
node->sub_type == EFI_DEV_END_ENTIRE)
return true;
node = (struct efi_generic_dev_path *)(buffer + offset);
}
/*
* If we're here then either node->length pointed past the end
* of the buffer or we reached the end of the buffer without
* finding a device path end node.
*/
return false;
}
static bool
validate_boot_order(struct efi_variable *var, int match, u8 *buffer,
unsigned long len)
{
/* An array of 16-bit integers */
if ((len % 2) != 0)
return false;
return true;
}
static bool
validate_load_option(struct efi_variable *var, int match, u8 *buffer,
unsigned long len)
{
u16 filepathlength;
int i, desclength = 0, namelen;
namelen = utf16_strnlen(var->VariableName, sizeof(var->VariableName));
/* Either "Boot" or "Driver" followed by four digits of hex */
for (i = match; i < match+4; i++) {
if (var->VariableName[i] > 127 ||
hex_to_bin(var->VariableName[i] & 0xff) < 0)
return true;
}
/* Reject it if there's 4 digits of hex and then further content */
if (namelen > match + 4)
return false;
/* A valid entry must be at least 8 bytes */
if (len < 8)
return false;
filepathlength = buffer[4] | buffer[5] << 8;
/*
* There's no stored length for the description, so it has to be
* found by hand
*/
desclength = utf16_strsize((efi_char16_t *)(buffer + 6), len - 6) + 2;
/* Each boot entry must have a descriptor */
if (!desclength)
return false;
/*
* If the sum of the length of the description, the claimed filepath
* length and the original header are greater than the length of the
* variable, it's malformed
*/
if ((desclength + filepathlength + 6) > len)
return false;
/*
* And, finally, check the filepath
*/
return validate_device_path(var, match, buffer + desclength + 6,
filepathlength);
}
static bool
validate_uint16(struct efi_variable *var, int match, u8 *buffer,
unsigned long len)
{
/* A single 16-bit integer */
if (len != 2)
return false;
return true;
}
static bool
validate_ascii_string(struct efi_variable *var, int match, u8 *buffer,
unsigned long len)
{
int i;
for (i = 0; i < len; i++) {
if (buffer[i] > 127)
return false;
if (buffer[i] == 0)
return true;
}
return false;
}
struct variable_validate {
char *name;
bool (*validate)(struct efi_variable *var, int match, u8 *data,
unsigned long len);
};
static const struct variable_validate variable_validate[] = {
{ "BootNext", validate_uint16 },
{ "BootOrder", validate_boot_order },
{ "DriverOrder", validate_boot_order },
{ "Boot*", validate_load_option },
{ "Driver*", validate_load_option },
{ "ConIn", validate_device_path },
{ "ConInDev", validate_device_path },
{ "ConOut", validate_device_path },
{ "ConOutDev", validate_device_path },
{ "ErrOut", validate_device_path },
{ "ErrOutDev", validate_device_path },
{ "Timeout", validate_uint16 },
{ "Lang", validate_ascii_string },
{ "PlatformLang", validate_ascii_string },
{ "", NULL },
};
static bool
validate_var(struct efi_variable *var, u8 *data, unsigned long len)
{
int i;
u16 *unicode_name = var->VariableName;
for (i = 0; variable_validate[i].validate != NULL; i++) {
const char *name = variable_validate[i].name;
int match;
for (match = 0; ; match++) {
char c = name[match];
u16 u = unicode_name[match];
/* All special variables are plain ascii */
if (u > 127)
return true;
/* Wildcard in the matching name means we've matched */
if (c == '*')
return variable_validate[i].validate(var,
match, data, len);
/* Case sensitive match */
if (c != u)
break;
/* Reached the end of the string while matching */
if (!c)
return variable_validate[i].validate(var,
match, data, len);
}
}
return true;
}
static efi_status_t static efi_status_t
get_var_data_locked(struct efivars *efivars, struct efi_variable *var) get_var_data_locked(struct efivars *efivars, struct efi_variable *var)
{ {
@ -324,6 +508,12 @@ efivar_store_raw(struct efivar_entry *entry, const char *buf, size_t count)
return -EINVAL; return -EINVAL;
} }
if ((new_var->Attributes & ~EFI_VARIABLE_MASK) != 0 ||
validate_var(new_var, new_var->Data, new_var->DataSize) == false) {
printk(KERN_ERR "efivars: Malformed variable content\n");
return -EINVAL;
}
spin_lock(&efivars->lock); spin_lock(&efivars->lock);
status = efivars->ops->set_variable(new_var->VariableName, status = efivars->ops->set_variable(new_var->VariableName,
&new_var->VendorGuid, &new_var->VendorGuid,
@ -626,6 +816,12 @@ static ssize_t efivar_create(struct file *filp, struct kobject *kobj,
if (!capable(CAP_SYS_ADMIN)) if (!capable(CAP_SYS_ADMIN))
return -EACCES; return -EACCES;
if ((new_var->Attributes & ~EFI_VARIABLE_MASK) != 0 ||
validate_var(new_var, new_var->Data, new_var->DataSize) == false) {
printk(KERN_ERR "efivars: Malformed variable content\n");
return -EINVAL;
}
spin_lock(&efivars->lock); spin_lock(&efivars->lock);
/* /*

View file

@ -1224,6 +1224,9 @@ static int i915_emon_status(struct seq_file *m, void *unused)
unsigned long temp, chipset, gfx; unsigned long temp, chipset, gfx;
int ret; int ret;
if (!IS_GEN5(dev))
return -ENODEV;
ret = mutex_lock_interruptible(&dev->struct_mutex); ret = mutex_lock_interruptible(&dev->struct_mutex);
if (ret) if (ret)
return ret; return ret;

View file

@ -1701,6 +1701,9 @@ void i915_update_gfx_val(struct drm_i915_private *dev_priv)
unsigned long diffms; unsigned long diffms;
u32 count; u32 count;
if (dev_priv->info->gen != 5)
return;
getrawmonotonic(&now); getrawmonotonic(&now);
diff1 = timespec_sub(now, dev_priv->last_time2); diff1 = timespec_sub(now, dev_priv->last_time2);
@ -2121,12 +2124,14 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
setup_timer(&dev_priv->hangcheck_timer, i915_hangcheck_elapsed, setup_timer(&dev_priv->hangcheck_timer, i915_hangcheck_elapsed,
(unsigned long) dev); (unsigned long) dev);
if (IS_GEN5(dev)) {
spin_lock(&mchdev_lock); spin_lock(&mchdev_lock);
i915_mch_dev = dev_priv; i915_mch_dev = dev_priv;
dev_priv->mchdev_lock = &mchdev_lock; dev_priv->mchdev_lock = &mchdev_lock;
spin_unlock(&mchdev_lock); spin_unlock(&mchdev_lock);
ips_ping_for_i915_load(); ips_ping_for_i915_load();
}
return 0; return 0;

View file

@ -7072,9 +7072,6 @@ static void intel_decrease_pllclock(struct drm_crtc *crtc)
struct drm_device *dev = crtc->dev; struct drm_device *dev = crtc->dev;
drm_i915_private_t *dev_priv = dev->dev_private; drm_i915_private_t *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
int pipe = intel_crtc->pipe;
int dpll_reg = DPLL(pipe);
int dpll = I915_READ(dpll_reg);
if (HAS_PCH_SPLIT(dev)) if (HAS_PCH_SPLIT(dev))
return; return;
@ -7087,10 +7084,15 @@ static void intel_decrease_pllclock(struct drm_crtc *crtc)
* the manual case. * the manual case.
*/ */
if (!HAS_PIPE_CXSR(dev) && intel_crtc->lowfreq_avail) { if (!HAS_PIPE_CXSR(dev) && intel_crtc->lowfreq_avail) {
int pipe = intel_crtc->pipe;
int dpll_reg = DPLL(pipe);
u32 dpll;
DRM_DEBUG_DRIVER("downclocking LVDS\n"); DRM_DEBUG_DRIVER("downclocking LVDS\n");
assert_panel_unlocked(dev_priv, pipe); assert_panel_unlocked(dev_priv, pipe);
dpll = I915_READ(dpll_reg);
dpll |= DISPLAY_RATE_SELECT_FPA1; dpll |= DISPLAY_RATE_SELECT_FPA1;
I915_WRITE(dpll_reg, dpll); I915_WRITE(dpll_reg, dpll);
intel_wait_for_vblank(dev, pipe); intel_wait_for_vblank(dev, pipe);
@ -7098,7 +7100,6 @@ static void intel_decrease_pllclock(struct drm_crtc *crtc)
if (!(dpll & DISPLAY_RATE_SELECT_FPA1)) if (!(dpll & DISPLAY_RATE_SELECT_FPA1))
DRM_DEBUG_DRIVER("failed to downclock LVDS!\n"); DRM_DEBUG_DRIVER("failed to downclock LVDS!\n");
} }
} }
/** /**

View file

@ -136,7 +136,7 @@ static void i9xx_write_infoframe(struct drm_encoder *encoder,
val &= ~VIDEO_DIP_SELECT_MASK; val &= ~VIDEO_DIP_SELECT_MASK;
I915_WRITE(VIDEO_DIP_CTL, val | port | flags); I915_WRITE(VIDEO_DIP_CTL, VIDEO_DIP_ENABLE | val | port | flags);
for (i = 0; i < len; i += 4) { for (i = 0; i < len; i += 4) {
I915_WRITE(VIDEO_DIP_DATA, *data); I915_WRITE(VIDEO_DIP_DATA, *data);

View file

@ -750,7 +750,7 @@ static const struct dmi_system_id intel_no_lvds[] = {
.ident = "Hewlett-Packard t5745", .ident = "Hewlett-Packard t5745",
.matches = { .matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
DMI_MATCH(DMI_BOARD_NAME, "hp t5745"), DMI_MATCH(DMI_PRODUCT_NAME, "hp t5745"),
}, },
}, },
{ {
@ -758,7 +758,7 @@ static const struct dmi_system_id intel_no_lvds[] = {
.ident = "Hewlett-Packard st5747", .ident = "Hewlett-Packard st5747",
.matches = { .matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
DMI_MATCH(DMI_BOARD_NAME, "hp st5747"), DMI_MATCH(DMI_PRODUCT_NAME, "hp st5747"),
}, },
}, },
{ {

View file

@ -270,7 +270,7 @@ static bool nouveau_dsm_detect(void)
struct acpi_buffer buffer = {sizeof(acpi_method_name), acpi_method_name}; struct acpi_buffer buffer = {sizeof(acpi_method_name), acpi_method_name};
struct pci_dev *pdev = NULL; struct pci_dev *pdev = NULL;
int has_dsm = 0; int has_dsm = 0;
int has_optimus; int has_optimus = 0;
int vga_count = 0; int vga_count = 0;
bool guid_valid; bool guid_valid;
int retval; int retval;

View file

@ -6156,11 +6156,15 @@ dcb_fake_connectors(struct nvbios *bios)
/* heuristic: if we ever get a non-zero connector field, assume /* heuristic: if we ever get a non-zero connector field, assume
* that all the indices are valid and we don't need fake them. * that all the indices are valid and we don't need fake them.
*
* and, as usual, a blacklist of boards with bad bios data..
*/ */
if (!nv_match_device(bios->dev, 0x0392, 0x107d, 0x20a2)) {
for (i = 0; i < dcbt->entries; i++) { for (i = 0; i < dcbt->entries; i++) {
if (dcbt->entry[i].connector) if (dcbt->entry[i].connector)
return; return;
} }
}
/* no useful connector info available, we need to make it up /* no useful connector info available, we need to make it up
* ourselves. the rule here is: anything on the same i2c bus * ourselves. the rule here is: anything on the same i2c bus

View file

@ -32,7 +32,9 @@ static bool
hdmi_sor(struct drm_encoder *encoder) hdmi_sor(struct drm_encoder *encoder)
{ {
struct drm_nouveau_private *dev_priv = encoder->dev->dev_private; struct drm_nouveau_private *dev_priv = encoder->dev->dev_private;
if (dev_priv->chipset < 0xa3) if (dev_priv->chipset < 0xa3 ||
dev_priv->chipset == 0xaa ||
dev_priv->chipset == 0xac)
return false; return false;
return true; return true;
} }

View file

@ -65,7 +65,7 @@ nv10_gpio_drive(struct drm_device *dev, int line, int dir, int out)
if (line < 10) { if (line < 10) {
line = (line - 2) * 4; line = (line - 2) * 4;
reg = NV_PCRTC_GPIO_EXT; reg = NV_PCRTC_GPIO_EXT;
mask = 0x00000003 << ((line - 2) * 4); mask = 0x00000003;
data = (dir << 1) | out; data = (dir << 1) | out;
} else } else
if (line < 14) { if (line < 14) {

View file

@ -54,6 +54,11 @@ nvc0_mfb_isr(struct drm_device *dev)
nvc0_mfb_subp_isr(dev, unit, subp); nvc0_mfb_subp_isr(dev, unit, subp);
units &= ~(1 << unit); units &= ~(1 << unit);
} }
/* we do something horribly wrong and upset PMFB a lot, so mask off
* interrupts from it after the first one until it's fixed
*/
nv_mask(dev, 0x000640, 0x02000000, 0x00000000);
} }
static void static void

View file

@ -241,8 +241,8 @@ int radeon_wb_init(struct radeon_device *rdev)
rdev->wb.use_event = true; rdev->wb.use_event = true;
} }
} }
/* always use writeback/events on NI */ /* always use writeback/events on NI, APUs */
if (ASIC_IS_DCE5(rdev)) { if (rdev->family >= CHIP_PALM) {
rdev->wb.enabled = true; rdev->wb.enabled = true;
rdev->wb.use_event = true; rdev->wb.use_event = true;
} }

View file

@ -52,7 +52,7 @@ module_param_named(tjmax, force_tjmax, int, 0444);
MODULE_PARM_DESC(tjmax, "TjMax value in degrees Celsius"); MODULE_PARM_DESC(tjmax, "TjMax value in degrees Celsius");
#define BASE_SYSFS_ATTR_NO 2 /* Sysfs Base attr no for coretemp */ #define BASE_SYSFS_ATTR_NO 2 /* Sysfs Base attr no for coretemp */
#define NUM_REAL_CORES 16 /* Number of Real cores per cpu */ #define NUM_REAL_CORES 32 /* Number of Real cores per cpu */
#define CORETEMP_NAME_LENGTH 17 /* String Length of attrs */ #define CORETEMP_NAME_LENGTH 17 /* String Length of attrs */
#define MAX_CORE_ATTRS 4 /* Maximum no of basic attrs */ #define MAX_CORE_ATTRS 4 /* Maximum no of basic attrs */
#define TOTAL_ATTRS (MAX_CORE_ATTRS + 1) #define TOTAL_ATTRS (MAX_CORE_ATTRS + 1)
@ -709,6 +709,10 @@ static void __cpuinit put_core_offline(unsigned int cpu)
indx = TO_ATTR_NO(cpu); indx = TO_ATTR_NO(cpu);
/* The core id is too big, just return */
if (indx > MAX_CORE_DATA - 1)
return;
if (pdata->core_data[indx] && pdata->core_data[indx]->cpu == cpu) if (pdata->core_data[indx] && pdata->core_data[indx]->cpu == cpu)
coretemp_remove_core(pdata, &pdev->dev, indx); coretemp_remove_core(pdata, &pdev->dev, indx);

View file

@ -324,7 +324,7 @@ static s32 pch_i2c_wait_for_xfer_complete(struct i2c_algo_pch_data *adap)
{ {
long ret; long ret;
ret = wait_event_timeout(pch_event, ret = wait_event_timeout(pch_event,
(adap->pch_event_flag != 0), msecs_to_jiffies(50)); (adap->pch_event_flag != 0), msecs_to_jiffies(1000));
if (ret == 0) { if (ret == 0) {
pch_err(adap, "timeout: %x\n", adap->pch_event_flag); pch_err(adap, "timeout: %x\n", adap->pch_event_flag);
@ -1063,6 +1063,6 @@ module_exit(pch_pci_exit);
MODULE_DESCRIPTION("Intel EG20T PCH/LAPIS Semico ML7213/ML7223/ML7831 IOH I2C"); MODULE_DESCRIPTION("Intel EG20T PCH/LAPIS Semico ML7213/ML7223/ML7831 IOH I2C");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_AUTHOR("Tomoya MORINAGA. <tomoya-linux@dsn.lapis-semi.com>"); MODULE_AUTHOR("Tomoya MORINAGA. <tomoya.rohm@gmail.com>");
module_param(pch_i2c_speed, int, (S_IRUSR | S_IWUSR)); module_param(pch_i2c_speed, int, (S_IRUSR | S_IWUSR));
module_param(pch_clk, int, (S_IRUSR | S_IWUSR)); module_param(pch_clk, int, (S_IRUSR | S_IWUSR));

View file

@ -227,6 +227,7 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg,
return -EINVAL; return -EINVAL;
init_completion(&i2c->cmd_complete); init_completion(&i2c->cmd_complete);
i2c->cmd_err = 0;
flags = stop ? MXS_I2C_CTRL0_POST_SEND_STOP : 0; flags = stop ? MXS_I2C_CTRL0_POST_SEND_STOP : 0;
@ -252,6 +253,9 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg,
if (i2c->cmd_err == -ENXIO) if (i2c->cmd_err == -ENXIO)
mxs_i2c_reset(i2c); mxs_i2c_reset(i2c);
else
writel(MXS_I2C_QUEUECTRL_QUEUE_RUN,
i2c->regs + MXS_I2C_QUEUECTRL_CLR);
dev_dbg(i2c->dev, "Done with err=%d\n", i2c->cmd_err); dev_dbg(i2c->dev, "Done with err=%d\n", i2c->cmd_err);
@ -299,8 +303,6 @@ static irqreturn_t mxs_i2c_isr(int this_irq, void *dev_id)
MXS_I2C_CTRL1_SLAVE_STOP_IRQ | MXS_I2C_CTRL1_SLAVE_IRQ)) MXS_I2C_CTRL1_SLAVE_STOP_IRQ | MXS_I2C_CTRL1_SLAVE_IRQ))
/* MXS_I2C_CTRL1_OVERSIZE_XFER_TERM_IRQ is only for slaves */ /* MXS_I2C_CTRL1_OVERSIZE_XFER_TERM_IRQ is only for slaves */
i2c->cmd_err = -EIO; i2c->cmd_err = -EIO;
else
i2c->cmd_err = 0;
is_last_cmd = (readl(i2c->regs + MXS_I2C_QUEUESTAT) & is_last_cmd = (readl(i2c->regs + MXS_I2C_QUEUESTAT) &
MXS_I2C_QUEUESTAT_WRITE_QUEUE_CNT_MASK) == 0; MXS_I2C_QUEUESTAT_WRITE_QUEUE_CNT_MASK) == 0;
@ -384,8 +386,6 @@ static int __devexit mxs_i2c_remove(struct platform_device *pdev)
if (ret) if (ret)
return -EBUSY; return -EBUSY;
writel(MXS_I2C_QUEUECTRL_QUEUE_RUN,
i2c->regs + MXS_I2C_QUEUECTRL_CLR);
writel(MXS_I2C_CTRL0_SFTRST, i2c->regs + MXS_I2C_CTRL0_SET); writel(MXS_I2C_CTRL0_SFTRST, i2c->regs + MXS_I2C_CTRL0_SET);
platform_set_drvdata(pdev, NULL); platform_set_drvdata(pdev, NULL);

View file

@ -546,8 +546,7 @@ static int i2c_pnx_controller_suspend(struct platform_device *pdev,
{ {
struct i2c_pnx_algo_data *alg_data = platform_get_drvdata(pdev); struct i2c_pnx_algo_data *alg_data = platform_get_drvdata(pdev);
/* FIXME: shouldn't this be clk_disable? */ clk_disable(alg_data->clk);
clk_enable(alg_data->clk);
return 0; return 0;
} }

View file

@ -516,6 +516,14 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
if (likely(i2c_dev->msg_err == I2C_ERR_NONE)) if (likely(i2c_dev->msg_err == I2C_ERR_NONE))
return 0; return 0;
/*
* NACK interrupt is generated before the I2C controller generates the
* STOP condition on the bus. So wait for 2 clock periods before resetting
* the controller so that STOP condition has been delivered properly.
*/
if (i2c_dev->msg_err == I2C_ERR_NO_ACK)
udelay(DIV_ROUND_UP(2 * 1000000, i2c_dev->bus_clk_rate));
tegra_i2c_init(i2c_dev); tegra_i2c_init(i2c_dev);
if (i2c_dev->msg_err == I2C_ERR_NO_ACK) { if (i2c_dev->msg_err == I2C_ERR_NO_ACK) {
if (msg->flags & I2C_M_IGNORE_NAK) if (msg->flags & I2C_M_IGNORE_NAK)

View file

@ -274,7 +274,8 @@ static int synaptics_set_advanced_gesture_mode(struct psmouse *psmouse)
static unsigned char param = 0xc8; static unsigned char param = 0xc8;
struct synaptics_data *priv = psmouse->private; struct synaptics_data *priv = psmouse->private;
if (!SYN_CAP_ADV_GESTURE(priv->ext_cap_0c)) if (!(SYN_CAP_ADV_GESTURE(priv->ext_cap_0c) ||
SYN_CAP_IMAGE_SENSOR(priv->ext_cap_0c)))
return 0; return 0;
if (psmouse_sliced_command(psmouse, SYN_QUE_MODEL)) if (psmouse_sliced_command(psmouse, SYN_QUE_MODEL))

View file

@ -1727,8 +1727,7 @@ int bitmap_create(struct mddev *mddev)
bitmap->chunkshift = (ffz(~mddev->bitmap_info.chunksize) bitmap->chunkshift = (ffz(~mddev->bitmap_info.chunksize)
- BITMAP_BLOCK_SHIFT); - BITMAP_BLOCK_SHIFT);
/* now that chunksize and chunkshift are set, we can use these macros */ chunks = (blocks + (1 << bitmap->chunkshift) - 1) >>
chunks = (blocks + bitmap->chunkshift - 1) >>
bitmap->chunkshift; bitmap->chunkshift;
pages = (chunks + PAGE_COUNTER_RATIO - 1) / PAGE_COUNTER_RATIO; pages = (chunks + PAGE_COUNTER_RATIO - 1) / PAGE_COUNTER_RATIO;

View file

@ -101,9 +101,6 @@ typedef __u16 bitmap_counter_t;
#define BITMAP_BLOCK_SHIFT 9 #define BITMAP_BLOCK_SHIFT 9
/* how many blocks per chunk? (this is variable) */
#define CHUNK_BLOCK_RATIO(bitmap) ((bitmap)->mddev->bitmap_info.chunksize >> BITMAP_BLOCK_SHIFT)
#endif #endif
/* /*

View file

@ -25,6 +25,7 @@
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/dma-mapping.h> #include <linux/dma-mapping.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <plat/cpu.h>
#include <plat/usb.h> #include <plat/usb.h>
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>

View file

@ -879,8 +879,13 @@ static inline unsigned int tg3_has_work(struct tg3_napi *tnapi)
if (sblk->status & SD_STATUS_LINK_CHG) if (sblk->status & SD_STATUS_LINK_CHG)
work_exists = 1; work_exists = 1;
} }
/* check for RX/TX work to do */
if (sblk->idx[0].tx_consumer != tnapi->tx_cons || /* check for TX work to do */
if (sblk->idx[0].tx_consumer != tnapi->tx_cons)
work_exists = 1;
/* check for RX work to do */
if (tnapi->rx_rcb_prod_idx &&
*(tnapi->rx_rcb_prod_idx) != tnapi->rx_rcb_ptr) *(tnapi->rx_rcb_prod_idx) != tnapi->rx_rcb_ptr)
work_exists = 1; work_exists = 1;
@ -6124,6 +6129,9 @@ static int tg3_poll_work(struct tg3_napi *tnapi, int work_done, int budget)
return work_done; return work_done;
} }
if (!tnapi->rx_rcb_prod_idx)
return work_done;
/* run RX thread, within the bounds set by NAPI. /* run RX thread, within the bounds set by NAPI.
* All RX "locking" is done by ensuring outside * All RX "locking" is done by ensuring outside
* code synchronizes with tg3->napi.poll() * code synchronizes with tg3->napi.poll()
@ -7567,6 +7575,12 @@ static int tg3_alloc_consistent(struct tg3 *tp)
*/ */
switch (i) { switch (i) {
default: default:
if (tg3_flag(tp, ENABLE_RSS)) {
tnapi->rx_rcb_prod_idx = NULL;
break;
}
/* Fall through */
case 1:
tnapi->rx_rcb_prod_idx = &sblk->idx[0].rx_producer; tnapi->rx_rcb_prod_idx = &sblk->idx[0].rx_producer;
break; break;
case 2: case 2:

View file

@ -1149,6 +1149,48 @@ release_tpsram:
return ret; return ret;
} }
/**
* t3_synchronize_rx - wait for current Rx processing on a port to complete
* @adap: the adapter
* @p: the port
*
* Ensures that current Rx processing on any of the queues associated with
* the given port completes before returning. We do this by acquiring and
* releasing the locks of the response queues associated with the port.
*/
static void t3_synchronize_rx(struct adapter *adap, const struct port_info *p)
{
int i;
for (i = p->first_qset; i < p->first_qset + p->nqsets; i++) {
struct sge_rspq *q = &adap->sge.qs[i].rspq;
spin_lock_irq(&q->lock);
spin_unlock_irq(&q->lock);
}
}
static void cxgb_vlan_mode(struct net_device *dev, netdev_features_t features)
{
struct port_info *pi = netdev_priv(dev);
struct adapter *adapter = pi->adapter;
if (adapter->params.rev > 0) {
t3_set_vlan_accel(adapter, 1 << pi->port_id,
features & NETIF_F_HW_VLAN_RX);
} else {
/* single control for all ports */
unsigned int i, have_vlans = features & NETIF_F_HW_VLAN_RX;
for_each_port(adapter, i)
have_vlans |=
adapter->port[i]->features & NETIF_F_HW_VLAN_RX;
t3_set_vlan_accel(adapter, 1, have_vlans);
}
t3_synchronize_rx(adapter, pi);
}
/** /**
* cxgb_up - enable the adapter * cxgb_up - enable the adapter
* @adapter: adapter being enabled * @adapter: adapter being enabled
@ -1161,7 +1203,7 @@ release_tpsram:
*/ */
static int cxgb_up(struct adapter *adap) static int cxgb_up(struct adapter *adap)
{ {
int err; int i, err;
if (!(adap->flags & FULL_INIT_DONE)) { if (!(adap->flags & FULL_INIT_DONE)) {
err = t3_check_fw_version(adap); err = t3_check_fw_version(adap);
@ -1198,6 +1240,9 @@ static int cxgb_up(struct adapter *adap)
if (err) if (err)
goto out; goto out;
for_each_port(adap, i)
cxgb_vlan_mode(adap->port[i], adap->port[i]->features);
setup_rss(adap); setup_rss(adap);
if (!(adap->flags & NAPI_INIT)) if (!(adap->flags & NAPI_INIT))
init_napi(adap); init_napi(adap);
@ -2508,48 +2553,6 @@ static int cxgb_set_mac_addr(struct net_device *dev, void *p)
return 0; return 0;
} }
/**
* t3_synchronize_rx - wait for current Rx processing on a port to complete
* @adap: the adapter
* @p: the port
*
* Ensures that current Rx processing on any of the queues associated with
* the given port completes before returning. We do this by acquiring and
* releasing the locks of the response queues associated with the port.
*/
static void t3_synchronize_rx(struct adapter *adap, const struct port_info *p)
{
int i;
for (i = p->first_qset; i < p->first_qset + p->nqsets; i++) {
struct sge_rspq *q = &adap->sge.qs[i].rspq;
spin_lock_irq(&q->lock);
spin_unlock_irq(&q->lock);
}
}
static void cxgb_vlan_mode(struct net_device *dev, netdev_features_t features)
{
struct port_info *pi = netdev_priv(dev);
struct adapter *adapter = pi->adapter;
if (adapter->params.rev > 0) {
t3_set_vlan_accel(adapter, 1 << pi->port_id,
features & NETIF_F_HW_VLAN_RX);
} else {
/* single control for all ports */
unsigned int i, have_vlans = features & NETIF_F_HW_VLAN_RX;
for_each_port(adapter, i)
have_vlans |=
adapter->port[i]->features & NETIF_F_HW_VLAN_RX;
t3_set_vlan_accel(adapter, 1, have_vlans);
}
t3_synchronize_rx(adapter, pi);
}
static netdev_features_t cxgb_fix_features(struct net_device *dev, static netdev_features_t cxgb_fix_features(struct net_device *dev,
netdev_features_t features) netdev_features_t features)
{ {
@ -3353,9 +3356,6 @@ static int __devinit init_one(struct pci_dev *pdev,
err = sysfs_create_group(&adapter->port[0]->dev.kobj, err = sysfs_create_group(&adapter->port[0]->dev.kobj,
&cxgb3_attr_group); &cxgb3_attr_group);
for_each_port(adapter, i)
cxgb_vlan_mode(adapter->port[i], adapter->port[i]->features);
print_port_info(adapter, ai); print_port_info(adapter, ai);
return 0; return 0;

View file

@ -1259,55 +1259,21 @@ rio_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
{ {
int phy_addr; int phy_addr;
struct netdev_private *np = netdev_priv(dev); struct netdev_private *np = netdev_priv(dev);
struct mii_data *miidata = (struct mii_data *) &rq->ifr_ifru; struct mii_ioctl_data *miidata = if_mii(rq);
struct netdev_desc *desc;
int i;
phy_addr = np->phy_addr; phy_addr = np->phy_addr;
switch (cmd) { switch (cmd) {
case SIOCDEVPRIVATE: case SIOCGMIIPHY:
miidata->phy_id = phy_addr;
break; break;
case SIOCGMIIREG:
case SIOCDEVPRIVATE + 1: miidata->val_out = mii_read (dev, phy_addr, miidata->reg_num);
miidata->out_value = mii_read (dev, phy_addr, miidata->reg_num);
break; break;
case SIOCDEVPRIVATE + 2: case SIOCSMIIREG:
mii_write (dev, phy_addr, miidata->reg_num, miidata->in_value); if (!capable(CAP_NET_ADMIN))
return -EPERM;
mii_write (dev, phy_addr, miidata->reg_num, miidata->val_in);
break; break;
case SIOCDEVPRIVATE + 3:
break;
case SIOCDEVPRIVATE + 4:
break;
case SIOCDEVPRIVATE + 5:
netif_stop_queue (dev);
break;
case SIOCDEVPRIVATE + 6:
netif_wake_queue (dev);
break;
case SIOCDEVPRIVATE + 7:
printk
("tx_full=%x cur_tx=%lx old_tx=%lx cur_rx=%lx old_rx=%lx\n",
netif_queue_stopped(dev), np->cur_tx, np->old_tx, np->cur_rx,
np->old_rx);
break;
case SIOCDEVPRIVATE + 8:
printk("TX ring:\n");
for (i = 0; i < TX_RING_SIZE; i++) {
desc = &np->tx_ring[i];
printk
("%02x:cur:%08x next:%08x status:%08x frag1:%08x frag0:%08x",
i,
(u32) (np->tx_ring_dma + i * sizeof (*desc)),
(u32)le64_to_cpu(desc->next_desc),
(u32)le64_to_cpu(desc->status),
(u32)(le64_to_cpu(desc->fraginfo) >> 32),
(u32)le64_to_cpu(desc->fraginfo));
printk ("\n");
}
printk ("\n");
break;
default: default:
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }

View file

@ -365,13 +365,6 @@ struct ioctl_data {
char *data; char *data;
}; };
struct mii_data {
__u16 reserved;
__u16 reg_num;
__u16 in_value;
__u16 out_value;
};
/* The Rx and Tx buffer descriptors. */ /* The Rx and Tx buffer descriptors. */
struct netdev_desc { struct netdev_desc {
__le64 next_desc; __le64 next_desc;

View file

@ -116,10 +116,10 @@ static struct ucc_geth_info ugeth_primary_info = {
.maxGroupAddrInHash = 4, .maxGroupAddrInHash = 4,
.maxIndAddrInHash = 4, .maxIndAddrInHash = 4,
.prel = 7, .prel = 7,
.maxFrameLength = 1518, .maxFrameLength = 1518+16, /* Add extra bytes for VLANs etc. */
.minFrameLength = 64, .minFrameLength = 64,
.maxD1Length = 1520, .maxD1Length = 1520+16, /* Add extra bytes for VLANs etc. */
.maxD2Length = 1520, .maxD2Length = 1520+16, /* Add extra bytes for VLANs etc. */
.vlantype = 0x8100, .vlantype = 0x8100,
.ecamptr = ((uint32_t) NULL), .ecamptr = ((uint32_t) NULL),
.eventRegMask = UCCE_OTHER, .eventRegMask = UCCE_OTHER,

View file

@ -877,7 +877,7 @@ struct ucc_geth_hardware_statistics {
/* Driver definitions */ /* Driver definitions */
#define TX_BD_RING_LEN 0x10 #define TX_BD_RING_LEN 0x10
#define RX_BD_RING_LEN 0x10 #define RX_BD_RING_LEN 0x20
#define TX_RING_MOD_MASK(size) (size-1) #define TX_RING_MOD_MASK(size) (size-1)
#define RX_RING_MOD_MASK(size) (size-1) #define RX_RING_MOD_MASK(size) (size-1)

View file

@ -290,16 +290,18 @@ static void ehea_update_bcmc_registrations(void)
arr[i].adh = adapter->handle; arr[i].adh = adapter->handle;
arr[i].port_id = port->logical_port_id; arr[i].port_id = port->logical_port_id;
arr[i].reg_type = EHEA_BCMC_SCOPE_ALL | arr[i].reg_type = EHEA_BCMC_MULTICAST |
EHEA_BCMC_MULTICAST |
EHEA_BCMC_UNTAGGED; EHEA_BCMC_UNTAGGED;
if (mc_entry->macaddr == 0)
arr[i].reg_type |= EHEA_BCMC_SCOPE_ALL;
arr[i++].macaddr = mc_entry->macaddr; arr[i++].macaddr = mc_entry->macaddr;
arr[i].adh = adapter->handle; arr[i].adh = adapter->handle;
arr[i].port_id = port->logical_port_id; arr[i].port_id = port->logical_port_id;
arr[i].reg_type = EHEA_BCMC_SCOPE_ALL | arr[i].reg_type = EHEA_BCMC_MULTICAST |
EHEA_BCMC_MULTICAST |
EHEA_BCMC_VLANID_ALL; EHEA_BCMC_VLANID_ALL;
if (mc_entry->macaddr == 0)
arr[i].reg_type |= EHEA_BCMC_SCOPE_ALL;
arr[i++].macaddr = mc_entry->macaddr; arr[i++].macaddr = mc_entry->macaddr;
num_registrations -= 2; num_registrations -= 2;
} }
@ -1838,8 +1840,9 @@ static u64 ehea_multicast_reg_helper(struct ehea_port *port, u64 mc_mac_addr,
u64 hret; u64 hret;
u8 reg_type; u8 reg_type;
reg_type = EHEA_BCMC_SCOPE_ALL | EHEA_BCMC_MULTICAST reg_type = EHEA_BCMC_MULTICAST | EHEA_BCMC_UNTAGGED;
| EHEA_BCMC_UNTAGGED; if (mc_mac_addr == 0)
reg_type |= EHEA_BCMC_SCOPE_ALL;
hret = ehea_h_reg_dereg_bcmc(port->adapter->handle, hret = ehea_h_reg_dereg_bcmc(port->adapter->handle,
port->logical_port_id, port->logical_port_id,
@ -1847,8 +1850,9 @@ static u64 ehea_multicast_reg_helper(struct ehea_port *port, u64 mc_mac_addr,
if (hret) if (hret)
goto out; goto out;
reg_type = EHEA_BCMC_SCOPE_ALL | EHEA_BCMC_MULTICAST reg_type = EHEA_BCMC_MULTICAST | EHEA_BCMC_VLANID_ALL;
| EHEA_BCMC_VLANID_ALL; if (mc_mac_addr == 0)
reg_type |= EHEA_BCMC_SCOPE_ALL;
hret = ehea_h_reg_dereg_bcmc(port->adapter->handle, hret = ehea_h_reg_dereg_bcmc(port->adapter->handle,
port->logical_port_id, port->logical_port_id,
@ -1898,7 +1902,7 @@ static void ehea_allmulti(struct net_device *dev, int enable)
netdev_err(dev, netdev_err(dev,
"failed enabling IFF_ALLMULTI\n"); "failed enabling IFF_ALLMULTI\n");
} }
} else } else {
if (!enable) { if (!enable) {
/* Disable ALLMULTI */ /* Disable ALLMULTI */
hret = ehea_multicast_reg_helper(port, 0, H_DEREG_BCMC); hret = ehea_multicast_reg_helper(port, 0, H_DEREG_BCMC);
@ -1909,6 +1913,7 @@ static void ehea_allmulti(struct net_device *dev, int enable)
"failed disabling IFF_ALLMULTI\n"); "failed disabling IFF_ALLMULTI\n");
} }
} }
}
static void ehea_add_multicast_entry(struct ehea_port *port, u8 *mc_mac_addr) static void ehea_add_multicast_entry(struct ehea_port *port, u8 *mc_mac_addr)
{ {
@ -1941,11 +1946,7 @@ static void ehea_set_multicast_list(struct net_device *dev)
struct netdev_hw_addr *ha; struct netdev_hw_addr *ha;
int ret; int ret;
if (port->promisc) { ehea_promiscuous(dev, !!(dev->flags & IFF_PROMISC));
ehea_promiscuous(dev, 1);
return;
}
ehea_promiscuous(dev, 0);
if (dev->flags & IFF_ALLMULTI) { if (dev->flags & IFF_ALLMULTI) {
ehea_allmulti(dev, 1); ehea_allmulti(dev, 1);
@ -2463,6 +2464,7 @@ static int ehea_down(struct net_device *dev)
return 0; return 0;
ehea_drop_multicast_list(dev); ehea_drop_multicast_list(dev);
ehea_allmulti(dev, 0);
ehea_broadcast_reg_helper(port, H_DEREG_BCMC); ehea_broadcast_reg_helper(port, H_DEREG_BCMC);
ehea_free_interrupts(dev); ehea_free_interrupts(dev);
@ -3261,6 +3263,7 @@ static int __devinit ehea_probe_adapter(struct platform_device *dev,
struct ehea_adapter *adapter; struct ehea_adapter *adapter;
const u64 *adapter_handle; const u64 *adapter_handle;
int ret; int ret;
int i;
if (!dev || !dev->dev.of_node) { if (!dev || !dev->dev.of_node) {
pr_err("Invalid ibmebus device probed\n"); pr_err("Invalid ibmebus device probed\n");
@ -3314,17 +3317,9 @@ static int __devinit ehea_probe_adapter(struct platform_device *dev,
tasklet_init(&adapter->neq_tasklet, ehea_neq_tasklet, tasklet_init(&adapter->neq_tasklet, ehea_neq_tasklet,
(unsigned long)adapter); (unsigned long)adapter);
ret = ibmebus_request_irq(adapter->neq->attr.ist1,
ehea_interrupt_neq, IRQF_DISABLED,
"ehea_neq", adapter);
if (ret) {
dev_err(&dev->dev, "requesting NEQ IRQ failed\n");
goto out_kill_eq;
}
ret = ehea_create_device_sysfs(dev); ret = ehea_create_device_sysfs(dev);
if (ret) if (ret)
goto out_free_irq; goto out_kill_eq;
ret = ehea_setup_ports(adapter); ret = ehea_setup_ports(adapter);
if (ret) { if (ret) {
@ -3332,15 +3327,28 @@ static int __devinit ehea_probe_adapter(struct platform_device *dev,
goto out_rem_dev_sysfs; goto out_rem_dev_sysfs;
} }
ret = ibmebus_request_irq(adapter->neq->attr.ist1,
ehea_interrupt_neq, IRQF_DISABLED,
"ehea_neq", adapter);
if (ret) {
dev_err(&dev->dev, "requesting NEQ IRQ failed\n");
goto out_shutdown_ports;
}
ret = 0; ret = 0;
goto out; goto out;
out_shutdown_ports:
for (i = 0; i < EHEA_MAX_PORTS; i++)
if (adapter->port[i]) {
ehea_shutdown_single_port(adapter->port[i]);
adapter->port[i] = NULL;
}
out_rem_dev_sysfs: out_rem_dev_sysfs:
ehea_remove_device_sysfs(dev); ehea_remove_device_sysfs(dev);
out_free_irq:
ibmebus_free_irq(adapter->neq->attr.ist1, adapter);
out_kill_eq: out_kill_eq:
ehea_destroy_eq(adapter->neq); ehea_destroy_eq(adapter->neq);

View file

@ -450,7 +450,7 @@ u64 ehea_h_modify_ehea_port(const u64 adapter_handle, const u16 port_num,
void *cb_addr); void *cb_addr);
#define H_REGBCMC_PN EHEA_BMASK_IBM(48, 63) #define H_REGBCMC_PN EHEA_BMASK_IBM(48, 63)
#define H_REGBCMC_REGTYPE EHEA_BMASK_IBM(61, 63) #define H_REGBCMC_REGTYPE EHEA_BMASK_IBM(60, 63)
#define H_REGBCMC_MACADDR EHEA_BMASK_IBM(16, 63) #define H_REGBCMC_MACADDR EHEA_BMASK_IBM(16, 63)
#define H_REGBCMC_VLANID EHEA_BMASK_IBM(52, 63) #define H_REGBCMC_VLANID EHEA_BMASK_IBM(52, 63)

View file

@ -3799,7 +3799,7 @@ static int e1000_test_msi_interrupt(struct e1000_adapter *adapter)
/* fire an unusual interrupt on the test handler */ /* fire an unusual interrupt on the test handler */
ew32(ICS, E1000_ICS_RXSEQ); ew32(ICS, E1000_ICS_RXSEQ);
e1e_flush(); e1e_flush();
msleep(50); msleep(100);
e1000_irq_disable(adapter); e1000_irq_disable(adapter);

View file

@ -106,7 +106,7 @@ E1000_PARAM(RxAbsIntDelay, "Receive Absolute Interrupt Delay");
/* /*
* Interrupt Throttle Rate (interrupts/sec) * Interrupt Throttle Rate (interrupts/sec)
* *
* Valid Range: 100-100000 (0=off, 1=dynamic, 3=dynamic conservative) * Valid Range: 100-100000 or one of: 0=off, 1=dynamic, 3=dynamic conservative
*/ */
E1000_PARAM(InterruptThrottleRate, "Interrupt Throttling Rate"); E1000_PARAM(InterruptThrottleRate, "Interrupt Throttling Rate");
#define DEFAULT_ITR 3 #define DEFAULT_ITR 3
@ -344,54 +344,61 @@ void __devinit e1000e_check_options(struct e1000_adapter *adapter)
if (num_InterruptThrottleRate > bd) { if (num_InterruptThrottleRate > bd) {
adapter->itr = InterruptThrottleRate[bd]; adapter->itr = InterruptThrottleRate[bd];
/*
* Make sure a message is printed for non-special
* values. And in case of an invalid option, display
* warning, use default and got through itr/itr_setting
* adjustment logic below
*/
if ((adapter->itr > 4) &&
e1000_validate_option(&adapter->itr, &opt, adapter))
adapter->itr = opt.def;
} else {
/*
* If no option specified, use default value and go
* through the logic below to adjust itr/itr_setting
*/
adapter->itr = opt.def;
/*
* Make sure a message is printed for non-special
* default values
*/
if (adapter->itr > 40)
e_info("%s set to default %d\n", opt.name,
adapter->itr);
}
adapter->itr_setting = adapter->itr;
switch (adapter->itr) { switch (adapter->itr) {
case 0: case 0:
e_info("%s turned off\n", opt.name); e_info("%s turned off\n", opt.name);
break; break;
case 1: case 1:
e_info("%s set to dynamic mode\n", opt.name); e_info("%s set to dynamic mode\n", opt.name);
adapter->itr_setting = adapter->itr;
adapter->itr = 20000; adapter->itr = 20000;
break; break;
case 3: case 3:
e_info("%s set to dynamic conservative mode\n", e_info("%s set to dynamic conservative mode\n",
opt.name); opt.name);
adapter->itr_setting = adapter->itr;
adapter->itr = 20000; adapter->itr = 20000;
break; break;
case 4: case 4:
e_info("%s set to simplified (2000-8000 ints) " e_info("%s set to simplified (2000-8000 ints) mode\n",
"mode\n", opt.name); opt.name);
adapter->itr_setting = 4;
break; break;
default: default:
/* /*
* Save the setting, because the dynamic bits * Save the setting, because the dynamic bits
* change itr. * change itr.
*/ *
if (e1000_validate_option(&adapter->itr, &opt,
adapter) &&
(adapter->itr == 3)) {
/*
* In case of invalid user value,
* default to conservative mode.
*/
adapter->itr_setting = adapter->itr;
adapter->itr = 20000;
} else {
/*
* Clear the lower two bits because * Clear the lower two bits because
* they are used as control. * they are used as control.
*/ */
adapter->itr_setting = adapter->itr_setting &= ~3;
adapter->itr & ~3;
}
break; break;
} }
} else {
adapter->itr_setting = opt.def;
adapter->itr = 20000;
}
} }
{ /* Interrupt Mode */ { /* Interrupt Mode */
static struct e1000_option opt = { static struct e1000_option opt = {

View file

@ -2731,14 +2731,14 @@ static int __devinit igbvf_probe(struct pci_dev *pdev,
netdev->addr_len); netdev->addr_len);
} }
if (!is_valid_ether_addr(netdev->perm_addr)) { if (!is_valid_ether_addr(netdev->dev_addr)) {
dev_err(&pdev->dev, "Invalid MAC Address: %pM\n", dev_err(&pdev->dev, "Invalid MAC Address: %pM\n",
netdev->dev_addr); netdev->dev_addr);
err = -EIO; err = -EIO;
goto err_hw_init; goto err_hw_init;
} }
memcpy(netdev->perm_addr, adapter->hw.mac.addr, netdev->addr_len); memcpy(netdev->perm_addr, netdev->dev_addr, netdev->addr_len);
setup_timer(&adapter->watchdog_timer, &igbvf_watchdog, setup_timer(&adapter->watchdog_timer, &igbvf_watchdog,
(unsigned long) adapter); (unsigned long) adapter);

View file

@ -437,6 +437,7 @@ int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter,
*/ */
if ((fh->fh_r_ctl == FC_RCTL_DD_SOL_DATA) && if ((fh->fh_r_ctl == FC_RCTL_DD_SOL_DATA) &&
(fctl & FC_FC_END_SEQ)) { (fctl & FC_FC_END_SEQ)) {
skb_linearize(skb);
crc = (struct fcoe_crc_eof *)skb_put(skb, sizeof(*crc)); crc = (struct fcoe_crc_eof *)skb_put(skb, sizeof(*crc));
crc->fcoe_eof = FC_EOF_T; crc->fcoe_eof = FC_EOF_T;
} }

View file

@ -4873,10 +4873,6 @@ static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake)
} }
ixgbe_clear_interrupt_scheme(adapter); ixgbe_clear_interrupt_scheme(adapter);
#ifdef CONFIG_DCB
kfree(adapter->ixgbe_ieee_pfc);
kfree(adapter->ixgbe_ieee_ets);
#endif
#ifdef CONFIG_PM #ifdef CONFIG_PM
retval = pci_save_state(pdev); retval = pci_save_state(pdev);
@ -7224,6 +7220,11 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev)
ixgbe_release_hw_control(adapter); ixgbe_release_hw_control(adapter);
#ifdef CONFIG_DCB
kfree(adapter->ixgbe_ieee_pfc);
kfree(adapter->ixgbe_ieee_ets);
#endif
iounmap(adapter->hw.hw_addr); iounmap(adapter->hw.hw_addr);
pci_release_selected_regions(pdev, pci_select_bars(pdev, pci_release_selected_regions(pdev, pci_select_bars(pdev,
IORESOURCE_MEM)); IORESOURCE_MEM));

View file

@ -2494,8 +2494,13 @@ static struct sk_buff *receive_copy(struct sky2_port *sky2,
skb_copy_from_linear_data(re->skb, skb->data, length); skb_copy_from_linear_data(re->skb, skb->data, length);
skb->ip_summed = re->skb->ip_summed; skb->ip_summed = re->skb->ip_summed;
skb->csum = re->skb->csum; skb->csum = re->skb->csum;
skb->rxhash = re->skb->rxhash;
skb->vlan_tci = re->skb->vlan_tci;
pci_dma_sync_single_for_device(sky2->hw->pdev, re->data_addr, pci_dma_sync_single_for_device(sky2->hw->pdev, re->data_addr,
length, PCI_DMA_FROMDEVICE); length, PCI_DMA_FROMDEVICE);
re->skb->vlan_tci = 0;
re->skb->rxhash = 0;
re->skb->ip_summed = CHECKSUM_NONE; re->skb->ip_summed = CHECKSUM_NONE;
skb_put(skb, length); skb_put(skb, length);
} }
@ -2580,9 +2585,6 @@ static struct sk_buff *sky2_receive(struct net_device *dev,
struct sk_buff *skb = NULL; struct sk_buff *skb = NULL;
u16 count = (status & GMR_FS_LEN) >> 16; u16 count = (status & GMR_FS_LEN) >> 16;
if (status & GMR_FS_VLAN)
count -= VLAN_HLEN; /* Account for vlan tag */
netif_printk(sky2, rx_status, KERN_DEBUG, dev, netif_printk(sky2, rx_status, KERN_DEBUG, dev,
"rx slot %u status 0x%x len %d\n", "rx slot %u status 0x%x len %d\n",
sky2->rx_next, status, length); sky2->rx_next, status, length);
@ -2590,6 +2592,9 @@ static struct sk_buff *sky2_receive(struct net_device *dev,
sky2->rx_next = (sky2->rx_next + 1) % sky2->rx_pending; sky2->rx_next = (sky2->rx_next + 1) % sky2->rx_pending;
prefetch(sky2->rx_ring + sky2->rx_next); prefetch(sky2->rx_ring + sky2->rx_next);
if (vlan_tx_tag_present(re->skb))
count -= VLAN_HLEN; /* Account for vlan tag */
/* This chip has hardware problems that generates bogus status. /* This chip has hardware problems that generates bogus status.
* So do only marginal checking and expect higher level protocols * So do only marginal checking and expect higher level protocols
* to handle crap frames. * to handle crap frames.
@ -2647,11 +2652,8 @@ static inline void sky2_tx_done(struct net_device *dev, u16 last)
} }
static inline void sky2_skb_rx(const struct sky2_port *sky2, static inline void sky2_skb_rx(const struct sky2_port *sky2,
u32 status, struct sk_buff *skb) struct sk_buff *skb)
{ {
if (status & GMR_FS_VLAN)
__vlan_hwaccel_put_tag(skb, be16_to_cpu(sky2->rx_tag));
if (skb->ip_summed == CHECKSUM_NONE) if (skb->ip_summed == CHECKSUM_NONE)
netif_receive_skb(skb); netif_receive_skb(skb);
else else
@ -2705,6 +2707,14 @@ static void sky2_rx_checksum(struct sky2_port *sky2, u32 status)
} }
} }
static void sky2_rx_tag(struct sky2_port *sky2, u16 length)
{
struct sk_buff *skb;
skb = sky2->rx_ring[sky2->rx_next].skb;
__vlan_hwaccel_put_tag(skb, be16_to_cpu(length));
}
static void sky2_rx_hash(struct sky2_port *sky2, u32 status) static void sky2_rx_hash(struct sky2_port *sky2, u32 status)
{ {
struct sk_buff *skb; struct sk_buff *skb;
@ -2763,8 +2773,7 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx)
} }
skb->protocol = eth_type_trans(skb, dev); skb->protocol = eth_type_trans(skb, dev);
sky2_skb_rx(sky2, skb);
sky2_skb_rx(sky2, status, skb);
/* Stop after net poll weight */ /* Stop after net poll weight */
if (++work_done >= to_do) if (++work_done >= to_do)
@ -2772,11 +2781,11 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx)
break; break;
case OP_RXVLAN: case OP_RXVLAN:
sky2->rx_tag = length; sky2_rx_tag(sky2, length);
break; break;
case OP_RXCHKSVLAN: case OP_RXCHKSVLAN:
sky2->rx_tag = length; sky2_rx_tag(sky2, length);
/* fall through */ /* fall through */
case OP_RXCHKS: case OP_RXCHKS:
if (likely(dev->features & NETIF_F_RXCSUM)) if (likely(dev->features & NETIF_F_RXCSUM))

View file

@ -2241,7 +2241,6 @@ struct sky2_port {
u16 rx_pending; u16 rx_pending;
u16 rx_data_size; u16 rx_data_size;
u16 rx_nfrags; u16 rx_nfrags;
u16 rx_tag;
struct { struct {
unsigned long last; unsigned long last;

View file

@ -2339,7 +2339,7 @@ static int gem_suspend(struct pci_dev *pdev, pm_message_t state)
netif_device_detach(dev); netif_device_detach(dev);
/* Switch off chip, remember WOL setting */ /* Switch off chip, remember WOL setting */
gp->asleep_wol = gp->wake_on_lan; gp->asleep_wol = !!gp->wake_on_lan;
gem_do_stop(dev, gp->asleep_wol); gem_do_stop(dev, gp->asleep_wol);
/* Unlock the network stack */ /* Unlock the network stack */

View file

@ -1511,7 +1511,7 @@ static int emac_devioctl(struct net_device *ndev, struct ifreq *ifrq, int cmd)
static int match_first_device(struct device *dev, void *data) static int match_first_device(struct device *dev, void *data)
{ {
return 1; return !strncmp(dev_name(dev), "davinci_mdio", 12);
} }
/** /**

View file

@ -228,7 +228,7 @@ tlan_get_skb(const struct tlan_list *tag)
unsigned long addr; unsigned long addr;
addr = tag->buffer[9].address; addr = tag->buffer[9].address;
addr |= (tag->buffer[8].address << 16) << 16; addr |= ((unsigned long) tag->buffer[8].address << 16) << 16;
return (struct sk_buff *) addr; return (struct sk_buff *) addr;
} }

View file

@ -355,7 +355,7 @@ static struct sk_buff *asix_tx_fixup(struct usbnet *dev, struct sk_buff *skb,
u32 packet_len; u32 packet_len;
u32 padbytes = 0xffff0000; u32 padbytes = 0xffff0000;
padlen = ((skb->len + 4) % 512) ? 0 : 4; padlen = ((skb->len + 4) & (dev->maxpacket - 1)) ? 0 : 4;
if ((!skb_cloned(skb)) && if ((!skb_cloned(skb)) &&
((headroom + tailroom) >= (4 + padlen))) { ((headroom + tailroom) >= (4 + padlen))) {
@ -377,7 +377,7 @@ static struct sk_buff *asix_tx_fixup(struct usbnet *dev, struct sk_buff *skb,
cpu_to_le32s(&packet_len); cpu_to_le32s(&packet_len);
skb_copy_to_linear_data(skb, &packet_len, sizeof(packet_len)); skb_copy_to_linear_data(skb, &packet_len, sizeof(packet_len));
if ((skb->len % 512) == 0) { if (padlen) {
cpu_to_le32s(&padbytes); cpu_to_le32s(&padbytes);
memcpy(skb_tail_pointer(skb), &padbytes, sizeof(padbytes)); memcpy(skb_tail_pointer(skb), &padbytes, sizeof(padbytes));
skb_put(skb, sizeof(padbytes)); skb_put(skb, sizeof(padbytes));

View file

@ -98,7 +98,7 @@ static int __must_check smsc75xx_read_reg(struct usbnet *dev, u32 index,
if (unlikely(ret < 0)) if (unlikely(ret < 0))
netdev_warn(dev->net, netdev_warn(dev->net,
"Failed to read register index 0x%08x", index); "Failed to read reg index 0x%08x: %d", index, ret);
le32_to_cpus(buf); le32_to_cpus(buf);
*data = *buf; *data = *buf;
@ -128,7 +128,7 @@ static int __must_check smsc75xx_write_reg(struct usbnet *dev, u32 index,
if (unlikely(ret < 0)) if (unlikely(ret < 0))
netdev_warn(dev->net, netdev_warn(dev->net,
"Failed to write register index 0x%08x", index); "Failed to write reg index 0x%08x: %d", index, ret);
kfree(buf); kfree(buf);
@ -171,7 +171,7 @@ static int smsc75xx_mdio_read(struct net_device *netdev, int phy_id, int idx)
idx &= dev->mii.reg_num_mask; idx &= dev->mii.reg_num_mask;
addr = ((phy_id << MII_ACCESS_PHY_ADDR_SHIFT) & MII_ACCESS_PHY_ADDR) addr = ((phy_id << MII_ACCESS_PHY_ADDR_SHIFT) & MII_ACCESS_PHY_ADDR)
| ((idx << MII_ACCESS_REG_ADDR_SHIFT) & MII_ACCESS_REG_ADDR) | ((idx << MII_ACCESS_REG_ADDR_SHIFT) & MII_ACCESS_REG_ADDR)
| MII_ACCESS_READ; | MII_ACCESS_READ | MII_ACCESS_BUSY;
ret = smsc75xx_write_reg(dev, MII_ACCESS, addr); ret = smsc75xx_write_reg(dev, MII_ACCESS, addr);
check_warn_goto_done(ret, "Error writing MII_ACCESS"); check_warn_goto_done(ret, "Error writing MII_ACCESS");
@ -210,7 +210,7 @@ static void smsc75xx_mdio_write(struct net_device *netdev, int phy_id, int idx,
idx &= dev->mii.reg_num_mask; idx &= dev->mii.reg_num_mask;
addr = ((phy_id << MII_ACCESS_PHY_ADDR_SHIFT) & MII_ACCESS_PHY_ADDR) addr = ((phy_id << MII_ACCESS_PHY_ADDR_SHIFT) & MII_ACCESS_PHY_ADDR)
| ((idx << MII_ACCESS_REG_ADDR_SHIFT) & MII_ACCESS_REG_ADDR) | ((idx << MII_ACCESS_REG_ADDR_SHIFT) & MII_ACCESS_REG_ADDR)
| MII_ACCESS_WRITE; | MII_ACCESS_WRITE | MII_ACCESS_BUSY;
ret = smsc75xx_write_reg(dev, MII_ACCESS, addr); ret = smsc75xx_write_reg(dev, MII_ACCESS, addr);
check_warn_goto_done(ret, "Error writing MII_ACCESS"); check_warn_goto_done(ret, "Error writing MII_ACCESS");
@ -508,9 +508,10 @@ static int smsc75xx_link_reset(struct usbnet *dev)
u16 lcladv, rmtadv; u16 lcladv, rmtadv;
int ret; int ret;
/* clear interrupt status */ /* read and write to clear phy interrupt status */
ret = smsc75xx_mdio_read(dev->net, mii->phy_id, PHY_INT_SRC); ret = smsc75xx_mdio_read(dev->net, mii->phy_id, PHY_INT_SRC);
check_warn_return(ret, "Error reading PHY_INT_SRC"); check_warn_return(ret, "Error reading PHY_INT_SRC");
smsc75xx_mdio_write(dev->net, mii->phy_id, PHY_INT_SRC, 0xffff);
ret = smsc75xx_write_reg(dev, INT_STS, INT_STS_CLEAR_ALL); ret = smsc75xx_write_reg(dev, INT_STS, INT_STS_CLEAR_ALL);
check_warn_return(ret, "Error writing INT_STS"); check_warn_return(ret, "Error writing INT_STS");
@ -643,7 +644,7 @@ static int smsc75xx_set_mac_address(struct usbnet *dev)
static int smsc75xx_phy_initialize(struct usbnet *dev) static int smsc75xx_phy_initialize(struct usbnet *dev)
{ {
int bmcr, timeout = 0; int bmcr, ret, timeout = 0;
/* Initialize MII structure */ /* Initialize MII structure */
dev->mii.dev = dev->net; dev->mii.dev = dev->net;
@ -651,6 +652,7 @@ static int smsc75xx_phy_initialize(struct usbnet *dev)
dev->mii.mdio_write = smsc75xx_mdio_write; dev->mii.mdio_write = smsc75xx_mdio_write;
dev->mii.phy_id_mask = 0x1f; dev->mii.phy_id_mask = 0x1f;
dev->mii.reg_num_mask = 0x1f; dev->mii.reg_num_mask = 0x1f;
dev->mii.supports_gmii = 1;
dev->mii.phy_id = SMSC75XX_INTERNAL_PHY_ID; dev->mii.phy_id = SMSC75XX_INTERNAL_PHY_ID;
/* reset phy and wait for reset to complete */ /* reset phy and wait for reset to complete */
@ -661,7 +663,7 @@ static int smsc75xx_phy_initialize(struct usbnet *dev)
bmcr = smsc75xx_mdio_read(dev->net, dev->mii.phy_id, MII_BMCR); bmcr = smsc75xx_mdio_read(dev->net, dev->mii.phy_id, MII_BMCR);
check_warn_return(bmcr, "Error reading MII_BMCR"); check_warn_return(bmcr, "Error reading MII_BMCR");
timeout++; timeout++;
} while ((bmcr & MII_BMCR) && (timeout < 100)); } while ((bmcr & BMCR_RESET) && (timeout < 100));
if (timeout >= 100) { if (timeout >= 100) {
netdev_warn(dev->net, "timeout on PHY Reset"); netdev_warn(dev->net, "timeout on PHY Reset");
@ -671,10 +673,13 @@ static int smsc75xx_phy_initialize(struct usbnet *dev)
smsc75xx_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE, smsc75xx_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE,
ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP | ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP |
ADVERTISE_PAUSE_ASYM); ADVERTISE_PAUSE_ASYM);
smsc75xx_mdio_write(dev->net, dev->mii.phy_id, MII_CTRL1000,
ADVERTISE_1000FULL);
/* read to clear */ /* read and write to clear phy interrupt status */
smsc75xx_mdio_read(dev->net, dev->mii.phy_id, PHY_INT_SRC); ret = smsc75xx_mdio_read(dev->net, dev->mii.phy_id, PHY_INT_SRC);
check_warn_return(bmcr, "Error reading PHY_INT_SRC"); check_warn_return(ret, "Error reading PHY_INT_SRC");
smsc75xx_mdio_write(dev->net, dev->mii.phy_id, PHY_INT_SRC, 0xffff);
smsc75xx_mdio_write(dev->net, dev->mii.phy_id, PHY_INT_MASK, smsc75xx_mdio_write(dev->net, dev->mii.phy_id, PHY_INT_MASK,
PHY_INT_MASK_DEFAULT); PHY_INT_MASK_DEFAULT);
@ -946,6 +951,14 @@ static int smsc75xx_reset(struct usbnet *dev)
ret = smsc75xx_write_reg(dev, INT_EP_CTL, buf); ret = smsc75xx_write_reg(dev, INT_EP_CTL, buf);
check_warn_return(ret, "Failed to write INT_EP_CTL: %d", ret); check_warn_return(ret, "Failed to write INT_EP_CTL: %d", ret);
/* allow mac to detect speed and duplex from phy */
ret = smsc75xx_read_reg(dev, MAC_CR, &buf);
check_warn_return(ret, "Failed to read MAC_CR: %d", ret);
buf |= (MAC_CR_ADD | MAC_CR_ASD);
ret = smsc75xx_write_reg(dev, MAC_CR, buf);
check_warn_return(ret, "Failed to write MAC_CR: %d", ret);
ret = smsc75xx_read_reg(dev, MAC_TX, &buf); ret = smsc75xx_read_reg(dev, MAC_TX, &buf);
check_warn_return(ret, "Failed to read MAC_TX: %d", ret); check_warn_return(ret, "Failed to read MAC_TX: %d", ret);
@ -1212,7 +1225,7 @@ static const struct driver_info smsc75xx_info = {
.rx_fixup = smsc75xx_rx_fixup, .rx_fixup = smsc75xx_rx_fixup,
.tx_fixup = smsc75xx_tx_fixup, .tx_fixup = smsc75xx_tx_fixup,
.status = smsc75xx_status, .status = smsc75xx_status,
.flags = FLAG_ETHER | FLAG_SEND_ZLP, .flags = FLAG_ETHER | FLAG_SEND_ZLP | FLAG_LINK_INTR,
}; };
static const struct usb_device_id products[] = { static const struct usb_device_id products[] = {

Some files were not shown because too many files have changed in this diff Show more