Merge 4.4-rc6 into tty-next

We want the serial/tty fixes in here as well.

Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Greg Kroah-Hartman 2015-12-21 11:06:07 -08:00
commit 462a1196a5
263 changed files with 2277 additions and 1241 deletions

View File

@ -22,8 +22,7 @@ Required properties:
Optional properties: Optional properties:
- ti,hwmods: Name of the hwmods associated to the eDMA CC - ti,hwmods: Name of the hwmods associated to the eDMA CC
- ti,edma-memcpy-channels: List of channels allocated to be used for memcpy, iow - ti,edma-memcpy-channels: List of channels allocated to be used for memcpy, iow
these channels will be SW triggered channels. The list must these channels will be SW triggered channels. See example.
contain 16 bits numbers, see example.
- ti,edma-reserved-slot-ranges: PaRAM slot ranges which should not be used by - ti,edma-reserved-slot-ranges: PaRAM slot ranges which should not be used by
the driver, they are allocated to be used by for example the the driver, they are allocated to be used by for example the
DSP. See example. DSP. See example.
@ -56,10 +55,9 @@ edma: edma@49000000 {
ti,tptcs = <&edma_tptc0 7>, <&edma_tptc1 7>, <&edma_tptc2 0>; ti,tptcs = <&edma_tptc0 7>, <&edma_tptc1 7>, <&edma_tptc2 0>;
/* Channel 20 and 21 is allocated for memcpy */ /* Channel 20 and 21 is allocated for memcpy */
ti,edma-memcpy-channels = /bits/ 16 <20 21>; ti,edma-memcpy-channels = <20 21>;
/* The following PaRAM slots are reserved: 35-45 and 100-110 */ /* The following PaRAM slots are reserved: 35-44 and 100-109 */
ti,edma-reserved-slot-ranges = /bits/ 16 <35 10>, ti,edma-reserved-slot-ranges = <35 10>, <100 10>;
/bits/ 16 <100 10>;
}; };
edma_tptc0: tptc@49800000 { edma_tptc0: tptc@49800000 {

View File

@ -12,7 +12,7 @@ Each key is represented as a sub-node of "allwinner,sun4i-a10-lradc-keys":
Required subnode-properties: Required subnode-properties:
- label: Descriptive name of the key. - label: Descriptive name of the key.
- linux,code: Keycode to emit. - linux,code: Keycode to emit.
- channel: Channel this key is attached to, mut be 0 or 1. - channel: Channel this key is attached to, must be 0 or 1.
- voltage: Voltage in µV at lradc input when this key is pressed. - voltage: Voltage in µV at lradc input when this key is pressed.
Example: Example:

View File

@ -6,7 +6,9 @@ used for what purposes, but which don't use an on-flash partition table such
as RedBoot. as RedBoot.
The partition table should be a subnode of the mtd node and should be named The partition table should be a subnode of the mtd node and should be named
'partitions'. Partitions are defined in subnodes of the partitions node. 'partitions'. This node should have the following property:
- compatible : (required) must be "fixed-partitions"
Partitions are then defined in subnodes of the partitions node.
For backwards compatibility partitions as direct subnodes of the mtd device are For backwards compatibility partitions as direct subnodes of the mtd device are
supported. This use is discouraged. supported. This use is discouraged.
@ -36,6 +38,7 @@ Examples:
flash@0 { flash@0 {
partitions { partitions {
compatible = "fixed-partitions";
#address-cells = <1>; #address-cells = <1>;
#size-cells = <1>; #size-cells = <1>;
@ -53,6 +56,7 @@ flash@0 {
flash@1 { flash@1 {
partitions { partitions {
compatible = "fixed-partitions";
#address-cells = <1>; #address-cells = <1>;
#size-cells = <2>; #size-cells = <2>;
@ -66,6 +70,7 @@ flash@1 {
flash@2 { flash@2 {
partitions { partitions {
compatible = "fixed-partitions";
#address-cells = <2>; #address-cells = <2>;
#size-cells = <2>; #size-cells = <2>;

View File

@ -181,17 +181,3 @@ For general information, go to the Intel support website at:
If an issue is identified with the released source code on the supported If an issue is identified with the released source code on the supported
kernel with a supported adapter, email the specific information related to the kernel with a supported adapter, email the specific information related to the
issue to e1000-devel@lists.sourceforge.net. issue to e1000-devel@lists.sourceforge.net.
License
=======
This software program is released under the terms of a license agreement
between you ('Licensee') and Intel. Do not use or load this software or any
associated materials (collectively, the 'Software') until you have carefully
read the full terms and conditions of the file COPYING located in this software
package. By loading or using the Software, you agree to the terms of this
Agreement. If you do not agree with the terms of this Agreement, do not install
or use the Software.
* Other names and brands may be claimed as the property of others.

View File

@ -5578,7 +5578,7 @@ R: Jesse Brandeburg <jesse.brandeburg@intel.com>
R: Shannon Nelson <shannon.nelson@intel.com> R: Shannon Nelson <shannon.nelson@intel.com>
R: Carolyn Wyborny <carolyn.wyborny@intel.com> R: Carolyn Wyborny <carolyn.wyborny@intel.com>
R: Don Skidmore <donald.c.skidmore@intel.com> R: Don Skidmore <donald.c.skidmore@intel.com>
R: Matthew Vick <matthew.vick@intel.com> R: Bruce Allan <bruce.w.allan@intel.com>
R: John Ronciak <john.ronciak@intel.com> R: John Ronciak <john.ronciak@intel.com>
R: Mitch Williams <mitch.a.williams@intel.com> R: Mitch Williams <mitch.a.williams@intel.com>
L: intel-wired-lan@lists.osuosl.org L: intel-wired-lan@lists.osuosl.org
@ -8380,6 +8380,14 @@ L: linux-samsung-soc@vger.kernel.org (moderated for non-subscribers)
S: Maintained S: Maintained
F: drivers/pinctrl/samsung/ F: drivers/pinctrl/samsung/
PIN CONTROLLER - SINGLE
M: Tony Lindgren <tony@atomide.com>
M: Haojian Zhuang <haojian.zhuang@linaro.org>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
L: linux-omap@vger.kernel.org
S: Maintained
F: drivers/pinctrl/pinctrl-single.c
PIN CONTROLLER - ST SPEAR PIN CONTROLLER - ST SPEAR
M: Viresh Kumar <vireshk@kernel.org> M: Viresh Kumar <vireshk@kernel.org>
L: spear-devel@list.st.com L: spear-devel@list.st.com
@ -8946,6 +8954,13 @@ F: drivers/rpmsg/
F: Documentation/rpmsg.txt F: Documentation/rpmsg.txt
F: include/linux/rpmsg.h F: include/linux/rpmsg.h
RENESAS ETHERNET DRIVERS
R: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
L: netdev@vger.kernel.org
L: linux-sh@vger.kernel.org
F: drivers/net/ethernet/renesas/
F: include/linux/sh_eth.h
RESET CONTROLLER FRAMEWORK RESET CONTROLLER FRAMEWORK
M: Philipp Zabel <p.zabel@pengutronix.de> M: Philipp Zabel <p.zabel@pengutronix.de>
S: Maintained S: Maintained

View File

@ -1,7 +1,7 @@
VERSION = 4 VERSION = 4
PATCHLEVEL = 4 PATCHLEVEL = 4
SUBLEVEL = 0 SUBLEVEL = 0
EXTRAVERSION = -rc5 EXTRAVERSION = -rc6
NAME = Blurry Fish Butt NAME = Blurry Fish Butt
# *DOCUMENTATION* # *DOCUMENTATION*

View File

@ -445,6 +445,7 @@ config LINUX_LINK_BASE
However some customers have peripherals mapped at this addr, so However some customers have peripherals mapped at this addr, so
Linux needs to be scooted a bit. Linux needs to be scooted a bit.
If you don't know what the above means, leave this setting alone. If you don't know what the above means, leave this setting alone.
This needs to match memory start address specified in Device Tree
config HIGHMEM config HIGHMEM
bool "High Memory Support" bool "High Memory Support"

View File

@ -46,6 +46,7 @@
snps,pbl = < 32 >; snps,pbl = < 32 >;
clocks = <&apbclk>; clocks = <&apbclk>;
clock-names = "stmmaceth"; clock-names = "stmmaceth";
max-speed = <100>;
}; };
ehci@0x40000 { ehci@0x40000 {

View File

@ -17,7 +17,8 @@
memory { memory {
device_type = "memory"; device_type = "memory";
reg = <0x0 0x80000000 0x0 0x40000000 /* 1 GB low mem */ /* CONFIG_LINUX_LINK_BASE needs to match low mem start */
reg = <0x0 0x80000000 0x0 0x20000000 /* 512 MB low mem */
0x1 0x00000000 0x0 0x40000000>; /* 1 GB highmem */ 0x1 0x00000000 0x0 0x40000000>; /* 1 GB highmem */
}; };

View File

@ -23,7 +23,7 @@
* @dt_compat: Array of device tree 'compatible' strings * @dt_compat: Array of device tree 'compatible' strings
* (XXX: although only 1st entry is looked at) * (XXX: although only 1st entry is looked at)
* @init_early: Very early callback [called from setup_arch()] * @init_early: Very early callback [called from setup_arch()]
* @init_cpu_smp: for each CPU as it is coming up (SMP as well as UP) * @init_per_cpu: for each CPU as it is coming up (SMP as well as UP)
* [(M):init_IRQ(), (o):start_kernel_secondary()] * [(M):init_IRQ(), (o):start_kernel_secondary()]
* @init_machine: arch initcall level callback (e.g. populate static * @init_machine: arch initcall level callback (e.g. populate static
* platform devices or parse Devicetree) * platform devices or parse Devicetree)
@ -35,7 +35,7 @@ struct machine_desc {
const char **dt_compat; const char **dt_compat;
void (*init_early)(void); void (*init_early)(void);
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
void (*init_cpu_smp)(unsigned int); void (*init_per_cpu)(unsigned int);
#endif #endif
void (*init_machine)(void); void (*init_machine)(void);
void (*init_late)(void); void (*init_late)(void);

View File

@ -48,7 +48,7 @@ extern int smp_ipi_irq_setup(int cpu, int irq);
* @init_early_smp: A SMP specific h/w block can init itself * @init_early_smp: A SMP specific h/w block can init itself
* Could be common across platforms so not covered by * Could be common across platforms so not covered by
* mach_desc->init_early() * mach_desc->init_early()
* @init_irq_cpu: Called for each core so SMP h/w block driver can do * @init_per_cpu: Called for each core so SMP h/w block driver can do
* any needed setup per cpu (e.g. IPI request) * any needed setup per cpu (e.g. IPI request)
* @cpu_kick: For Master to kickstart a cpu (optionally at a PC) * @cpu_kick: For Master to kickstart a cpu (optionally at a PC)
* @ipi_send: To send IPI to a @cpu * @ipi_send: To send IPI to a @cpu
@ -57,7 +57,7 @@ extern int smp_ipi_irq_setup(int cpu, int irq);
struct plat_smp_ops { struct plat_smp_ops {
const char *info; const char *info;
void (*init_early_smp)(void); void (*init_early_smp)(void);
void (*init_irq_cpu)(int cpu); void (*init_per_cpu)(int cpu);
void (*cpu_kick)(int cpu, unsigned long pc); void (*cpu_kick)(int cpu, unsigned long pc);
void (*ipi_send)(int cpu); void (*ipi_send)(int cpu);
void (*ipi_clear)(int irq); void (*ipi_clear)(int irq);

View File

@ -112,7 +112,6 @@ struct unwind_frame_info {
extern int arc_unwind(struct unwind_frame_info *frame); extern int arc_unwind(struct unwind_frame_info *frame);
extern void arc_unwind_init(void); extern void arc_unwind_init(void);
extern void arc_unwind_setup(void);
extern void *unwind_add_table(struct module *module, const void *table_start, extern void *unwind_add_table(struct module *module, const void *table_start,
unsigned long table_size); unsigned long table_size);
extern void unwind_remove_table(void *handle, int init_only); extern void unwind_remove_table(void *handle, int init_only);
@ -152,9 +151,6 @@ static inline void arc_unwind_init(void)
{ {
} }
static inline void arc_unwind_setup(void)
{
}
#define unwind_add_table(a, b, c) #define unwind_add_table(a, b, c)
#define unwind_remove_table(a, b) #define unwind_remove_table(a, b)

View File

@ -106,10 +106,21 @@ static struct irq_chip arcv2_irq_chip = {
static int arcv2_irq_map(struct irq_domain *d, unsigned int irq, static int arcv2_irq_map(struct irq_domain *d, unsigned int irq,
irq_hw_number_t hw) irq_hw_number_t hw)
{ {
if (irq == TIMER0_IRQ || irq == IPI_IRQ) /*
* core intc IRQs [16, 23]:
* Statically assigned always private-per-core (Timers, WDT, IPI, PCT)
*/
if (hw < 24) {
/*
* A subsequent request_percpu_irq() fails if percpu_devid is
* not set. That in turns sets NOAUTOEN, meaning each core needs
* to call enable_percpu_irq()
*/
irq_set_percpu_devid(irq);
irq_set_chip_and_handler(irq, &arcv2_irq_chip, handle_percpu_irq); irq_set_chip_and_handler(irq, &arcv2_irq_chip, handle_percpu_irq);
else } else {
irq_set_chip_and_handler(irq, &arcv2_irq_chip, handle_level_irq); irq_set_chip_and_handler(irq, &arcv2_irq_chip, handle_level_irq);
}
return 0; return 0;
} }

View File

@ -29,11 +29,11 @@ void __init init_IRQ(void)
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
/* a SMP H/w block could do IPI IRQ request here */ /* a SMP H/w block could do IPI IRQ request here */
if (plat_smp_ops.init_irq_cpu) if (plat_smp_ops.init_per_cpu)
plat_smp_ops.init_irq_cpu(smp_processor_id()); plat_smp_ops.init_per_cpu(smp_processor_id());
if (machine_desc->init_cpu_smp) if (machine_desc->init_per_cpu)
machine_desc->init_cpu_smp(smp_processor_id()); machine_desc->init_per_cpu(smp_processor_id());
#endif #endif
} }
@ -51,6 +51,18 @@ void arch_do_IRQ(unsigned int irq, struct pt_regs *regs)
set_irq_regs(old_regs); set_irq_regs(old_regs);
} }
/*
* API called for requesting percpu interrupts - called by each CPU
* - For boot CPU, actually request the IRQ with genirq core + enables
* - For subsequent callers only enable called locally
*
* Relies on being called by boot cpu first (i.e. request called ahead) of
* any enable as expected by genirq. Hence Suitable only for TIMER, IPI
* which are guaranteed to be setup on boot core first.
* Late probed peripherals such as perf can't use this as there no guarantee
* of being called on boot CPU first.
*/
void arc_request_percpu_irq(int irq, int cpu, void arc_request_percpu_irq(int irq, int cpu,
irqreturn_t (*isr)(int irq, void *dev), irqreturn_t (*isr)(int irq, void *dev),
const char *irq_nm, const char *irq_nm,
@ -60,14 +72,17 @@ void arc_request_percpu_irq(int irq, int cpu,
if (!cpu) { if (!cpu) {
int rc; int rc;
#ifdef CONFIG_ISA_ARCOMPACT
/* /*
* These 2 calls are essential to making percpu IRQ APIs work * A subsequent request_percpu_irq() fails if percpu_devid is
* Ideally these details could be hidden in irq chip map function * not set. That in turns sets NOAUTOEN, meaning each core needs
* but the issue is IPIs IRQs being static (non-DT) and platform * to call enable_percpu_irq()
* specific, so we can't identify them there. *
* For ARCv2, this is done in irq map function since we know
* which irqs are strictly per cpu
*/ */
irq_set_percpu_devid(irq); irq_set_percpu_devid(irq);
irq_modify_status(irq, IRQ_NOAUTOEN, 0); /* @irq, @clr, @set */ #endif
rc = request_percpu_irq(irq, isr, irq_nm, percpu_dev); rc = request_percpu_irq(irq, isr, irq_nm, percpu_dev);
if (rc) if (rc)

View File

@ -132,7 +132,7 @@ static void mcip_probe_n_setup(void)
struct plat_smp_ops plat_smp_ops = { struct plat_smp_ops plat_smp_ops = {
.info = smp_cpuinfo_buf, .info = smp_cpuinfo_buf,
.init_early_smp = mcip_probe_n_setup, .init_early_smp = mcip_probe_n_setup,
.init_irq_cpu = mcip_setup_per_cpu, .init_per_cpu = mcip_setup_per_cpu,
.ipi_send = mcip_ipi_send, .ipi_send = mcip_ipi_send,
.ipi_clear = mcip_ipi_clear, .ipi_clear = mcip_ipi_clear,
}; };

View File

@ -428,12 +428,11 @@ static irqreturn_t arc_pmu_intr(int irq, void *dev)
#endif /* CONFIG_ISA_ARCV2 */ #endif /* CONFIG_ISA_ARCV2 */
void arc_cpu_pmu_irq_init(void) static void arc_cpu_pmu_irq_init(void *data)
{ {
struct arc_pmu_cpu *pmu_cpu = this_cpu_ptr(&arc_pmu_cpu); int irq = *(int *)data;
arc_request_percpu_irq(arc_pmu->irq, smp_processor_id(), arc_pmu_intr, enable_percpu_irq(irq, IRQ_TYPE_NONE);
"ARC perf counters", pmu_cpu);
/* Clear all pending interrupt flags */ /* Clear all pending interrupt flags */
write_aux_reg(ARC_REG_PCT_INT_ACT, 0xffffffff); write_aux_reg(ARC_REG_PCT_INT_ACT, 0xffffffff);
@ -515,7 +514,6 @@ static int arc_pmu_device_probe(struct platform_device *pdev)
if (has_interrupts) { if (has_interrupts) {
int irq = platform_get_irq(pdev, 0); int irq = platform_get_irq(pdev, 0);
unsigned long flags;
if (irq < 0) { if (irq < 0) {
pr_err("Cannot get IRQ number for the platform\n"); pr_err("Cannot get IRQ number for the platform\n");
@ -524,24 +522,12 @@ static int arc_pmu_device_probe(struct platform_device *pdev)
arc_pmu->irq = irq; arc_pmu->irq = irq;
/* /* intc map function ensures irq_set_percpu_devid() called */
* arc_cpu_pmu_irq_init() needs to be called on all cores for request_percpu_irq(irq, arc_pmu_intr, "ARC perf counters",
* their respective local PMU. this_cpu_ptr(&arc_pmu_cpu));
* However we use opencoded on_each_cpu() to ensure it is called
* on core0 first, so that arc_request_percpu_irq() sets up on_each_cpu(arc_cpu_pmu_irq_init, &irq, 1);
* AUTOEN etc. Otherwise enable_percpu_irq() fails to enable
* perf IRQ on non master cores.
* see arc_request_percpu_irq()
*/
preempt_disable();
local_irq_save(flags);
arc_cpu_pmu_irq_init();
local_irq_restore(flags);
smp_call_function((smp_call_func_t)arc_cpu_pmu_irq_init, 0, 1);
preempt_enable();
/* Clean all pending interrupt flags */
write_aux_reg(ARC_REG_PCT_INT_ACT, 0xffffffff);
} else } else
arc_pmu->pmu.capabilities |= PERF_PMU_CAP_NO_INTERRUPT; arc_pmu->pmu.capabilities |= PERF_PMU_CAP_NO_INTERRUPT;

View File

@ -429,7 +429,6 @@ void __init setup_arch(char **cmdline_p)
#endif #endif
arc_unwind_init(); arc_unwind_init();
arc_unwind_setup();
} }
static int __init customize_machine(void) static int __init customize_machine(void)

View File

@ -132,11 +132,11 @@ void start_kernel_secondary(void)
pr_info("## CPU%u LIVE ##: Executing Code...\n", cpu); pr_info("## CPU%u LIVE ##: Executing Code...\n", cpu);
/* Some SMP H/w setup - for each cpu */ /* Some SMP H/w setup - for each cpu */
if (plat_smp_ops.init_irq_cpu) if (plat_smp_ops.init_per_cpu)
plat_smp_ops.init_irq_cpu(cpu); plat_smp_ops.init_per_cpu(cpu);
if (machine_desc->init_cpu_smp) if (machine_desc->init_per_cpu)
machine_desc->init_cpu_smp(cpu); machine_desc->init_per_cpu(cpu);
arc_local_timer_setup(); arc_local_timer_setup();

View File

@ -170,6 +170,23 @@ static struct unwind_table *find_table(unsigned long pc)
static unsigned long read_pointer(const u8 **pLoc, static unsigned long read_pointer(const u8 **pLoc,
const void *end, signed ptrType); const void *end, signed ptrType);
static void init_unwind_hdr(struct unwind_table *table,
void *(*alloc) (unsigned long));
/*
* wrappers for header alloc (vs. calling one vs. other at call site)
* to elide section mismatches warnings
*/
static void *__init unw_hdr_alloc_early(unsigned long sz)
{
return __alloc_bootmem_nopanic(sz, sizeof(unsigned int),
MAX_DMA_ADDRESS);
}
static void *unw_hdr_alloc(unsigned long sz)
{
return kmalloc(sz, GFP_KERNEL);
}
static void init_unwind_table(struct unwind_table *table, const char *name, static void init_unwind_table(struct unwind_table *table, const char *name,
const void *core_start, unsigned long core_size, const void *core_start, unsigned long core_size,
@ -209,6 +226,8 @@ void __init arc_unwind_init(void)
__start_unwind, __end_unwind - __start_unwind, __start_unwind, __end_unwind - __start_unwind,
NULL, 0); NULL, 0);
/*__start_unwind_hdr, __end_unwind_hdr - __start_unwind_hdr);*/ /*__start_unwind_hdr, __end_unwind_hdr - __start_unwind_hdr);*/
init_unwind_hdr(&root_table, unw_hdr_alloc_early);
} }
static const u32 bad_cie, not_fde; static const u32 bad_cie, not_fde;
@ -241,8 +260,8 @@ static void swap_eh_frame_hdr_table_entries(void *p1, void *p2, int size)
e2->fde = v; e2->fde = v;
} }
static void __init setup_unwind_table(struct unwind_table *table, static void init_unwind_hdr(struct unwind_table *table,
void *(*alloc) (unsigned long)) void *(*alloc) (unsigned long))
{ {
const u8 *ptr; const u8 *ptr;
unsigned long tableSize = table->size, hdrSize; unsigned long tableSize = table->size, hdrSize;
@ -274,13 +293,13 @@ static void __init setup_unwind_table(struct unwind_table *table,
const u32 *cie = cie_for_fde(fde, table); const u32 *cie = cie_for_fde(fde, table);
signed ptrType; signed ptrType;
if (cie == &not_fde) if (cie == &not_fde) /* only process FDE here */
continue; continue;
if (cie == NULL || cie == &bad_cie) if (cie == NULL || cie == &bad_cie)
return; continue; /* say FDE->CIE.version != 1 */
ptrType = fde_pointer_type(cie); ptrType = fde_pointer_type(cie);
if (ptrType < 0) if (ptrType < 0)
return; continue;
ptr = (const u8 *)(fde + 2); ptr = (const u8 *)(fde + 2);
if (!read_pointer(&ptr, (const u8 *)(fde + 1) + *fde, if (!read_pointer(&ptr, (const u8 *)(fde + 1) + *fde,
@ -300,9 +319,11 @@ static void __init setup_unwind_table(struct unwind_table *table,
hdrSize = 4 + sizeof(unsigned long) + sizeof(unsigned int) hdrSize = 4 + sizeof(unsigned long) + sizeof(unsigned int)
+ 2 * n * sizeof(unsigned long); + 2 * n * sizeof(unsigned long);
header = alloc(hdrSize); header = alloc(hdrSize);
if (!header) if (!header)
return; return;
header->version = 1; header->version = 1;
header->eh_frame_ptr_enc = DW_EH_PE_abs | DW_EH_PE_native; header->eh_frame_ptr_enc = DW_EH_PE_abs | DW_EH_PE_native;
header->fde_count_enc = DW_EH_PE_abs | DW_EH_PE_data4; header->fde_count_enc = DW_EH_PE_abs | DW_EH_PE_data4;
@ -322,6 +343,10 @@ static void __init setup_unwind_table(struct unwind_table *table,
if (fde[1] == 0xffffffff) if (fde[1] == 0xffffffff)
continue; /* this is a CIE */ continue; /* this is a CIE */
if (*(u8 *)(cie + 2) != 1)
continue; /* FDE->CIE.version not supported */
ptr = (const u8 *)(fde + 2); ptr = (const u8 *)(fde + 2);
header->table[n].start = read_pointer(&ptr, header->table[n].start = read_pointer(&ptr,
(const u8 *)(fde + 1) + (const u8 *)(fde + 1) +
@ -342,18 +367,6 @@ static void __init setup_unwind_table(struct unwind_table *table,
table->header = (const void *)header; table->header = (const void *)header;
} }
static void *__init balloc(unsigned long sz)
{
return __alloc_bootmem_nopanic(sz,
sizeof(unsigned int),
__pa(MAX_DMA_ADDRESS));
}
void __init arc_unwind_setup(void)
{
setup_unwind_table(&root_table, balloc);
}
#ifdef CONFIG_MODULES #ifdef CONFIG_MODULES
static struct unwind_table *last_table; static struct unwind_table *last_table;
@ -377,6 +390,8 @@ void *unwind_add_table(struct module *module, const void *table_start,
table_start, table_size, table_start, table_size,
NULL, 0); NULL, 0);
init_unwind_hdr(table, unw_hdr_alloc);
#ifdef UNWIND_DEBUG #ifdef UNWIND_DEBUG
unw_debug("Table added for [%s] %lx %lx\n", unw_debug("Table added for [%s] %lx %lx\n",
module->name, table->core.pc, table->core.range); module->name, table->core.pc, table->core.range);
@ -439,6 +454,7 @@ void unwind_remove_table(void *handle, int init_only)
info.init_only = init_only; info.init_only = init_only;
unlink_table(&info); /* XXX: SMP */ unlink_table(&info); /* XXX: SMP */
kfree(table->header);
kfree(table); kfree(table);
} }
@ -507,7 +523,8 @@ static const u32 *cie_for_fde(const u32 *fde, const struct unwind_table *table)
if (*cie <= sizeof(*cie) + 4 || *cie >= fde[1] - sizeof(*fde) if (*cie <= sizeof(*cie) + 4 || *cie >= fde[1] - sizeof(*fde)
|| (*cie & (sizeof(*cie) - 1)) || (*cie & (sizeof(*cie) - 1))
|| (cie[1] != 0xffffffff)) || (cie[1] != 0xffffffff)
|| ( *(u8 *)(cie + 2) != 1)) /* version 1 supported */
return NULL; /* this is not a (valid) CIE */ return NULL; /* this is not a (valid) CIE */
return cie; return cie;
} }

View File

@ -51,7 +51,9 @@ void __init early_init_dt_add_memory_arch(u64 base, u64 size)
int in_use = 0; int in_use = 0;
if (!low_mem_sz) { if (!low_mem_sz) {
BUG_ON(base != low_mem_start); if (base != low_mem_start)
panic("CONFIG_LINUX_LINK_BASE != DT memory { }");
low_mem_sz = size; low_mem_sz = size;
in_use = 1; in_use = 1;
} else { } else {

View File

@ -510,10 +510,14 @@ __copy_to_user_std(void __user *to, const void *from, unsigned long n);
static inline unsigned long __must_check static inline unsigned long __must_check
__copy_to_user(void __user *to, const void *from, unsigned long n) __copy_to_user(void __user *to, const void *from, unsigned long n)
{ {
#ifndef CONFIG_UACCESS_WITH_MEMCPY
unsigned int __ua_flags = uaccess_save_and_enable(); unsigned int __ua_flags = uaccess_save_and_enable();
n = arm_copy_to_user(to, from, n); n = arm_copy_to_user(to, from, n);
uaccess_restore(__ua_flags); uaccess_restore(__ua_flags);
return n; return n;
#else
return arm_copy_to_user(to, from, n);
#endif
} }
extern unsigned long __must_check extern unsigned long __must_check

View File

@ -95,6 +95,22 @@ void __show_regs(struct pt_regs *regs)
{ {
unsigned long flags; unsigned long flags;
char buf[64]; char buf[64];
#ifndef CONFIG_CPU_V7M
unsigned int domain;
#ifdef CONFIG_CPU_SW_DOMAIN_PAN
/*
* Get the domain register for the parent context. In user
* mode, we don't save the DACR, so lets use what it should
* be. For other modes, we place it after the pt_regs struct.
*/
if (user_mode(regs))
domain = DACR_UACCESS_ENABLE;
else
domain = *(unsigned int *)(regs + 1);
#else
domain = get_domain();
#endif
#endif
show_regs_print_info(KERN_DEFAULT); show_regs_print_info(KERN_DEFAULT);
@ -123,21 +139,8 @@ void __show_regs(struct pt_regs *regs)
#ifndef CONFIG_CPU_V7M #ifndef CONFIG_CPU_V7M
{ {
unsigned int domain = get_domain();
const char *segment; const char *segment;
#ifdef CONFIG_CPU_SW_DOMAIN_PAN
/*
* Get the domain register for the parent context. In user
* mode, we don't save the DACR, so lets use what it should
* be. For other modes, we place it after the pt_regs struct.
*/
if (user_mode(regs))
domain = DACR_UACCESS_ENABLE;
else
domain = *(unsigned int *)(regs + 1);
#endif
if ((domain & domain_mask(DOMAIN_USER)) == if ((domain & domain_mask(DOMAIN_USER)) ==
domain_val(DOMAIN_USER, DOMAIN_NOACCESS)) domain_val(DOMAIN_USER, DOMAIN_NOACCESS))
segment = "none"; segment = "none";
@ -163,11 +166,11 @@ void __show_regs(struct pt_regs *regs)
buf[0] = '\0'; buf[0] = '\0';
#ifdef CONFIG_CPU_CP15_MMU #ifdef CONFIG_CPU_CP15_MMU
{ {
unsigned int transbase, dac = get_domain(); unsigned int transbase;
asm("mrc p15, 0, %0, c2, c0\n\t" asm("mrc p15, 0, %0, c2, c0\n\t"
: "=r" (transbase)); : "=r" (transbase));
snprintf(buf, sizeof(buf), " Table: %08x DAC: %08x", snprintf(buf, sizeof(buf), " Table: %08x DAC: %08x",
transbase, dac); transbase, domain);
} }
#endif #endif
asm("mrc p15, 0, %0, c1, c0\n" : "=r" (ctrl)); asm("mrc p15, 0, %0, c1, c0\n" : "=r" (ctrl));

View File

@ -36,10 +36,10 @@
*/ */
#define __user_swpX_asm(data, addr, res, temp, B) \ #define __user_swpX_asm(data, addr, res, temp, B) \
__asm__ __volatile__( \ __asm__ __volatile__( \
" mov %2, %1\n" \ "0: ldrex"B" %2, [%3]\n" \
"0: ldrex"B" %1, [%3]\n" \ "1: strex"B" %0, %1, [%3]\n" \
"1: strex"B" %0, %2, [%3]\n" \
" cmp %0, #0\n" \ " cmp %0, #0\n" \
" moveq %1, %2\n" \
" movne %0, %4\n" \ " movne %0, %4\n" \
"2:\n" \ "2:\n" \
" .section .text.fixup,\"ax\"\n" \ " .section .text.fixup,\"ax\"\n" \

View File

@ -88,6 +88,7 @@ pin_page_for_write(const void __user *_addr, pte_t **ptep, spinlock_t **ptlp)
static unsigned long noinline static unsigned long noinline
__copy_to_user_memcpy(void __user *to, const void *from, unsigned long n) __copy_to_user_memcpy(void __user *to, const void *from, unsigned long n)
{ {
unsigned long ua_flags;
int atomic; int atomic;
if (unlikely(segment_eq(get_fs(), KERNEL_DS))) { if (unlikely(segment_eq(get_fs(), KERNEL_DS))) {
@ -118,7 +119,9 @@ __copy_to_user_memcpy(void __user *to, const void *from, unsigned long n)
if (tocopy > n) if (tocopy > n)
tocopy = n; tocopy = n;
ua_flags = uaccess_save_and_enable();
memcpy((void *)to, from, tocopy); memcpy((void *)to, from, tocopy);
uaccess_restore(ua_flags);
to += tocopy; to += tocopy;
from += tocopy; from += tocopy;
n -= tocopy; n -= tocopy;
@ -145,14 +148,21 @@ arm_copy_to_user(void __user *to, const void *from, unsigned long n)
* With frame pointer disabled, tail call optimization kicks in * With frame pointer disabled, tail call optimization kicks in
* as well making this test almost invisible. * as well making this test almost invisible.
*/ */
if (n < 64) if (n < 64) {
return __copy_to_user_std(to, from, n); unsigned long ua_flags = uaccess_save_and_enable();
return __copy_to_user_memcpy(to, from, n); n = __copy_to_user_std(to, from, n);
uaccess_restore(ua_flags);
} else {
n = __copy_to_user_memcpy(to, from, n);
}
return n;
} }
static unsigned long noinline static unsigned long noinline
__clear_user_memset(void __user *addr, unsigned long n) __clear_user_memset(void __user *addr, unsigned long n)
{ {
unsigned long ua_flags;
if (unlikely(segment_eq(get_fs(), KERNEL_DS))) { if (unlikely(segment_eq(get_fs(), KERNEL_DS))) {
memset((void *)addr, 0, n); memset((void *)addr, 0, n);
return 0; return 0;
@ -175,7 +185,9 @@ __clear_user_memset(void __user *addr, unsigned long n)
if (tocopy > n) if (tocopy > n)
tocopy = n; tocopy = n;
ua_flags = uaccess_save_and_enable();
memset((void *)addr, 0, tocopy); memset((void *)addr, 0, tocopy);
uaccess_restore(ua_flags);
addr += tocopy; addr += tocopy;
n -= tocopy; n -= tocopy;
@ -193,9 +205,14 @@ out:
unsigned long arm_clear_user(void __user *addr, unsigned long n) unsigned long arm_clear_user(void __user *addr, unsigned long n)
{ {
/* See rational for this in __copy_to_user() above. */ /* See rational for this in __copy_to_user() above. */
if (n < 64) if (n < 64) {
return __clear_user_std(addr, n); unsigned long ua_flags = uaccess_save_and_enable();
return __clear_user_memset(addr, n); n = __clear_user_std(addr, n);
uaccess_restore(ua_flags);
} else {
n = __clear_user_memset(addr, n);
}
return n;
} }
#if 0 #if 0

View File

@ -165,13 +165,28 @@ static void flush_context(unsigned int cpu)
__flush_icache_all(); __flush_icache_all();
} }
static int is_reserved_asid(u64 asid) static bool check_update_reserved_asid(u64 asid, u64 newasid)
{ {
int cpu; int cpu;
for_each_possible_cpu(cpu) bool hit = false;
if (per_cpu(reserved_asids, cpu) == asid)
return 1; /*
return 0; * Iterate over the set of reserved ASIDs looking for a match.
* If we find one, then we can update our mm to use newasid
* (i.e. the same ASID in the current generation) but we can't
* exit the loop early, since we need to ensure that all copies
* of the old ASID are updated to reflect the mm. Failure to do
* so could result in us missing the reserved ASID in a future
* generation.
*/
for_each_possible_cpu(cpu) {
if (per_cpu(reserved_asids, cpu) == asid) {
hit = true;
per_cpu(reserved_asids, cpu) = newasid;
}
}
return hit;
} }
static u64 new_context(struct mm_struct *mm, unsigned int cpu) static u64 new_context(struct mm_struct *mm, unsigned int cpu)
@ -181,12 +196,14 @@ static u64 new_context(struct mm_struct *mm, unsigned int cpu)
u64 generation = atomic64_read(&asid_generation); u64 generation = atomic64_read(&asid_generation);
if (asid != 0) { if (asid != 0) {
u64 newasid = generation | (asid & ~ASID_MASK);
/* /*
* If our current ASID was active during a rollover, we * If our current ASID was active during a rollover, we
* can continue to use it and this was just a false alarm. * can continue to use it and this was just a false alarm.
*/ */
if (is_reserved_asid(asid)) if (check_update_reserved_asid(asid, newasid))
return generation | (asid & ~ASID_MASK); return newasid;
/* /*
* We had a valid ASID in a previous life, so try to re-use * We had a valid ASID in a previous life, so try to re-use
@ -194,7 +211,7 @@ static u64 new_context(struct mm_struct *mm, unsigned int cpu)
*/ */
asid &= ~ASID_MASK; asid &= ~ASID_MASK;
if (!__test_and_set_bit(asid, asid_map)) if (!__test_and_set_bit(asid, asid_map))
goto bump_gen; return newasid;
} }
/* /*
@ -216,11 +233,8 @@ static u64 new_context(struct mm_struct *mm, unsigned int cpu)
__set_bit(asid, asid_map); __set_bit(asid, asid_map);
cur_idx = asid; cur_idx = asid;
bump_gen:
asid |= generation;
cpumask_clear(mm_cpumask(mm)); cpumask_clear(mm_cpumask(mm));
return asid; return asid | generation;
} }
void check_and_switch_context(struct mm_struct *mm, struct task_struct *tsk) void check_and_switch_context(struct mm_struct *mm, struct task_struct *tsk)

View File

@ -1521,7 +1521,7 @@ static int __map_sg_chunk(struct device *dev, struct scatterlist *sg,
return -ENOMEM; return -ENOMEM;
for (count = 0, s = sg; count < (size >> PAGE_SHIFT); s = sg_next(s)) { for (count = 0, s = sg; count < (size >> PAGE_SHIFT); s = sg_next(s)) {
phys_addr_t phys = sg_phys(s) & PAGE_MASK; phys_addr_t phys = page_to_phys(sg_page(s));
unsigned int len = PAGE_ALIGN(s->offset + s->length); unsigned int len = PAGE_ALIGN(s->offset + s->length);
if (!is_coherent && if (!is_coherent &&

View File

@ -22,6 +22,7 @@
#include <linux/memblock.h> #include <linux/memblock.h>
#include <linux/dma-contiguous.h> #include <linux/dma-contiguous.h>
#include <linux/sizes.h> #include <linux/sizes.h>
#include <linux/stop_machine.h>
#include <asm/cp15.h> #include <asm/cp15.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
@ -627,12 +628,10 @@ static struct section_perm ro_perms[] = {
* safe to be called with preemption disabled, as under stop_machine(). * safe to be called with preemption disabled, as under stop_machine().
*/ */
static inline void section_update(unsigned long addr, pmdval_t mask, static inline void section_update(unsigned long addr, pmdval_t mask,
pmdval_t prot) pmdval_t prot, struct mm_struct *mm)
{ {
struct mm_struct *mm;
pmd_t *pmd; pmd_t *pmd;
mm = current->active_mm;
pmd = pmd_offset(pud_offset(pgd_offset(mm, addr), addr), addr); pmd = pmd_offset(pud_offset(pgd_offset(mm, addr), addr), addr);
#ifdef CONFIG_ARM_LPAE #ifdef CONFIG_ARM_LPAE
@ -656,49 +655,82 @@ static inline bool arch_has_strict_perms(void)
return !!(get_cr() & CR_XP); return !!(get_cr() & CR_XP);
} }
#define set_section_perms(perms, field) { \ void set_section_perms(struct section_perm *perms, int n, bool set,
size_t i; \ struct mm_struct *mm)
unsigned long addr; \ {
\ size_t i;
if (!arch_has_strict_perms()) \ unsigned long addr;
return; \
\ if (!arch_has_strict_perms())
for (i = 0; i < ARRAY_SIZE(perms); i++) { \ return;
if (!IS_ALIGNED(perms[i].start, SECTION_SIZE) || \
!IS_ALIGNED(perms[i].end, SECTION_SIZE)) { \ for (i = 0; i < n; i++) {
pr_err("BUG: section %lx-%lx not aligned to %lx\n", \ if (!IS_ALIGNED(perms[i].start, SECTION_SIZE) ||
perms[i].start, perms[i].end, \ !IS_ALIGNED(perms[i].end, SECTION_SIZE)) {
SECTION_SIZE); \ pr_err("BUG: section %lx-%lx not aligned to %lx\n",
continue; \ perms[i].start, perms[i].end,
} \ SECTION_SIZE);
\ continue;
for (addr = perms[i].start; \ }
addr < perms[i].end; \
addr += SECTION_SIZE) \ for (addr = perms[i].start;
section_update(addr, perms[i].mask, \ addr < perms[i].end;
perms[i].field); \ addr += SECTION_SIZE)
} \ section_update(addr, perms[i].mask,
set ? perms[i].prot : perms[i].clear, mm);
}
} }
static inline void fix_kernmem_perms(void) static void update_sections_early(struct section_perm perms[], int n)
{ {
set_section_perms(nx_perms, prot); struct task_struct *t, *s;
read_lock(&tasklist_lock);
for_each_process(t) {
if (t->flags & PF_KTHREAD)
continue;
for_each_thread(t, s)
set_section_perms(perms, n, true, s->mm);
}
read_unlock(&tasklist_lock);
set_section_perms(perms, n, true, current->active_mm);
set_section_perms(perms, n, true, &init_mm);
}
int __fix_kernmem_perms(void *unused)
{
update_sections_early(nx_perms, ARRAY_SIZE(nx_perms));
return 0;
}
void fix_kernmem_perms(void)
{
stop_machine(__fix_kernmem_perms, NULL, NULL);
} }
#ifdef CONFIG_DEBUG_RODATA #ifdef CONFIG_DEBUG_RODATA
int __mark_rodata_ro(void *unused)
{
update_sections_early(ro_perms, ARRAY_SIZE(ro_perms));
return 0;
}
void mark_rodata_ro(void) void mark_rodata_ro(void)
{ {
set_section_perms(ro_perms, prot); stop_machine(__mark_rodata_ro, NULL, NULL);
} }
void set_kernel_text_rw(void) void set_kernel_text_rw(void)
{ {
set_section_perms(ro_perms, clear); set_section_perms(ro_perms, ARRAY_SIZE(ro_perms), false,
current->active_mm);
} }
void set_kernel_text_ro(void) void set_kernel_text_ro(void)
{ {
set_section_perms(ro_perms, prot); set_section_perms(ro_perms, ARRAY_SIZE(ro_perms), true,
current->active_mm);
} }
#endif /* CONFIG_DEBUG_RODATA */ #endif /* CONFIG_DEBUG_RODATA */

View File

@ -95,7 +95,7 @@ ENDPROC(cpu_v7_dcache_clean_area)
.equ cpu_v7_suspend_size, 4 * 9 .equ cpu_v7_suspend_size, 4 * 9
#ifdef CONFIG_ARM_CPU_SUSPEND #ifdef CONFIG_ARM_CPU_SUSPEND
ENTRY(cpu_v7_do_suspend) ENTRY(cpu_v7_do_suspend)
stmfd sp!, {r4 - r10, lr} stmfd sp!, {r4 - r11, lr}
mrc p15, 0, r4, c13, c0, 0 @ FCSE/PID mrc p15, 0, r4, c13, c0, 0 @ FCSE/PID
mrc p15, 0, r5, c13, c0, 3 @ User r/o thread ID mrc p15, 0, r5, c13, c0, 3 @ User r/o thread ID
stmia r0!, {r4 - r5} stmia r0!, {r4 - r5}
@ -112,7 +112,7 @@ ENTRY(cpu_v7_do_suspend)
mrc p15, 0, r9, c1, c0, 1 @ Auxiliary control register mrc p15, 0, r9, c1, c0, 1 @ Auxiliary control register
mrc p15, 0, r10, c1, c0, 2 @ Co-processor access control mrc p15, 0, r10, c1, c0, 2 @ Co-processor access control
stmia r0, {r5 - r11} stmia r0, {r5 - r11}
ldmfd sp!, {r4 - r10, pc} ldmfd sp!, {r4 - r11, pc}
ENDPROC(cpu_v7_do_suspend) ENDPROC(cpu_v7_do_suspend)
ENTRY(cpu_v7_do_resume) ENTRY(cpu_v7_do_resume)

View File

@ -11,7 +11,7 @@
#define NR_syscalls 322 /* length of syscall table */ #define NR_syscalls 323 /* length of syscall table */
/* /*
* The following defines stop scripts/checksyscalls.sh from complaining about * The following defines stop scripts/checksyscalls.sh from complaining about

View File

@ -335,5 +335,6 @@
#define __NR_userfaultfd 1343 #define __NR_userfaultfd 1343
#define __NR_membarrier 1344 #define __NR_membarrier 1344
#define __NR_kcmp 1345 #define __NR_kcmp 1345
#define __NR_mlock2 1346
#endif /* _UAPI_ASM_IA64_UNISTD_H */ #endif /* _UAPI_ASM_IA64_UNISTD_H */

View File

@ -1771,5 +1771,6 @@ sys_call_table:
data8 sys_userfaultfd data8 sys_userfaultfd
data8 sys_membarrier data8 sys_membarrier
data8 sys_kcmp // 1345 data8 sys_kcmp // 1345
data8 sys_mlock2
.org sys_call_table + 8*NR_syscalls // guard against failures to increase NR_syscalls .org sys_call_table + 8*NR_syscalls // guard against failures to increase NR_syscalls

View File

@ -61,7 +61,8 @@ static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl,
/* FIXME this part of code is untested */ /* FIXME this part of code is untested */
for_each_sg(sgl, sg, nents, i) { for_each_sg(sgl, sg, nents, i) {
sg->dma_address = sg_phys(sg); sg->dma_address = sg_phys(sg);
__dma_sync(sg_phys(sg), sg->length, direction); __dma_sync(page_to_phys(sg_page(sg)) + sg->offset,
sg->length, direction);
} }
return nents; return nents;

View File

@ -370,16 +370,16 @@ COMPAT_SYS(execveat)
PPC64ONLY(switch_endian) PPC64ONLY(switch_endian)
SYSCALL_SPU(userfaultfd) SYSCALL_SPU(userfaultfd)
SYSCALL_SPU(membarrier) SYSCALL_SPU(membarrier)
SYSCALL(semop) SYSCALL(ni_syscall)
SYSCALL(semget) SYSCALL(ni_syscall)
COMPAT_SYS(semctl) SYSCALL(ni_syscall)
COMPAT_SYS(semtimedop) SYSCALL(ni_syscall)
COMPAT_SYS(msgsnd) SYSCALL(ni_syscall)
COMPAT_SYS(msgrcv) SYSCALL(ni_syscall)
SYSCALL(msgget) SYSCALL(ni_syscall)
COMPAT_SYS(msgctl) SYSCALL(ni_syscall)
COMPAT_SYS(shmat) SYSCALL(ni_syscall)
SYSCALL(shmdt) SYSCALL(ni_syscall)
SYSCALL(shmget) SYSCALL(ni_syscall)
COMPAT_SYS(shmctl) SYSCALL(ni_syscall)
SYSCALL(mlock2) SYSCALL(mlock2)

View File

@ -388,18 +388,6 @@
#define __NR_switch_endian 363 #define __NR_switch_endian 363
#define __NR_userfaultfd 364 #define __NR_userfaultfd 364
#define __NR_membarrier 365 #define __NR_membarrier 365
#define __NR_semop 366
#define __NR_semget 367
#define __NR_semctl 368
#define __NR_semtimedop 369
#define __NR_msgsnd 370
#define __NR_msgrcv 371
#define __NR_msgget 372
#define __NR_msgctl 373
#define __NR_shmat 374
#define __NR_shmdt 375
#define __NR_shmget 376
#define __NR_shmctl 377
#define __NR_mlock2 378 #define __NR_mlock2 378
#endif /* _UAPI_ASM_POWERPC_UNISTD_H_ */ #endif /* _UAPI_ASM_POWERPC_UNISTD_H_ */

View File

@ -83,7 +83,19 @@ static void opal_event_unmask(struct irq_data *d)
set_bit(d->hwirq, &opal_event_irqchip.mask); set_bit(d->hwirq, &opal_event_irqchip.mask);
opal_poll_events(&events); opal_poll_events(&events);
opal_handle_events(be64_to_cpu(events)); last_outstanding_events = be64_to_cpu(events);
/*
* We can't just handle the events now with opal_handle_events().
* If we did we would deadlock when opal_event_unmask() is called from
* handle_level_irq() with the irq descriptor lock held, because
* calling opal_handle_events() would call generic_handle_irq() and
* then handle_level_irq() which would try to take the descriptor lock
* again. Instead queue the events for later.
*/
if (last_outstanding_events & opal_event_irqchip.mask)
/* Need to retrigger the interrupt */
irq_work_queue(&opal_event_irq_work);
} }
static int opal_event_set_type(struct irq_data *d, unsigned int flow_type) static int opal_event_set_type(struct irq_data *d, unsigned int flow_type)

View File

@ -278,7 +278,7 @@ static void opal_handle_message(void)
/* Sanity check */ /* Sanity check */
if (type >= OPAL_MSG_TYPE_MAX) { if (type >= OPAL_MSG_TYPE_MAX) {
pr_warning("%s: Unknown message type: %u\n", __func__, type); pr_warn_once("%s: Unknown message type: %u\n", __func__, type);
return; return;
} }
opal_message_do_notify(type, (void *)&msg); opal_message_do_notify(type, (void *)&msg);

View File

@ -89,7 +89,7 @@ static struct addr_marker address_markers[] = {
{ 0/* VMALLOC_START */, "vmalloc() Area" }, { 0/* VMALLOC_START */, "vmalloc() Area" },
{ 0/*VMALLOC_END*/, "vmalloc() End" }, { 0/*VMALLOC_END*/, "vmalloc() End" },
# ifdef CONFIG_HIGHMEM # ifdef CONFIG_HIGHMEM
{ 0/*PKMAP_BASE*/, "Persisent kmap() Area" }, { 0/*PKMAP_BASE*/, "Persistent kmap() Area" },
# endif # endif
{ 0/*FIXADDR_START*/, "Fixmap Area" }, { 0/*FIXADDR_START*/, "Fixmap Area" },
#endif #endif

View File

@ -2495,14 +2495,9 @@ void __init xen_init_mmu_ops(void)
{ {
x86_init.paging.pagetable_init = xen_pagetable_init; x86_init.paging.pagetable_init = xen_pagetable_init;
/* Optimization - we can use the HVM one but it has no idea which if (xen_feature(XENFEAT_auto_translated_physmap))
* VCPUs are descheduled - which means that it will needlessly IPI
* them. Xen knows so let it do the job.
*/
if (xen_feature(XENFEAT_auto_translated_physmap)) {
pv_mmu_ops.flush_tlb_others = xen_flush_tlb_others;
return; return;
}
pv_mmu_ops = xen_mmu_ops; pv_mmu_ops = xen_mmu_ops;
memset(dummy_mapping, 0xff, PAGE_SIZE); memset(dummy_mapping, 0xff, PAGE_SIZE);

View File

@ -68,26 +68,16 @@ static void xen_pv_post_suspend(int suspend_cancelled)
void xen_arch_pre_suspend(void) void xen_arch_pre_suspend(void)
{ {
int cpu;
for_each_online_cpu(cpu)
xen_pmu_finish(cpu);
if (xen_pv_domain()) if (xen_pv_domain())
xen_pv_pre_suspend(); xen_pv_pre_suspend();
} }
void xen_arch_post_suspend(int cancelled) void xen_arch_post_suspend(int cancelled)
{ {
int cpu;
if (xen_pv_domain()) if (xen_pv_domain())
xen_pv_post_suspend(cancelled); xen_pv_post_suspend(cancelled);
else else
xen_hvm_post_suspend(cancelled); xen_hvm_post_suspend(cancelled);
for_each_online_cpu(cpu)
xen_pmu_init(cpu);
} }
static void xen_vcpu_notify_restore(void *data) static void xen_vcpu_notify_restore(void *data)
@ -106,10 +96,20 @@ static void xen_vcpu_notify_suspend(void *data)
void xen_arch_resume(void) void xen_arch_resume(void)
{ {
int cpu;
on_each_cpu(xen_vcpu_notify_restore, NULL, 1); on_each_cpu(xen_vcpu_notify_restore, NULL, 1);
for_each_online_cpu(cpu)
xen_pmu_init(cpu);
} }
void xen_arch_suspend(void) void xen_arch_suspend(void)
{ {
int cpu;
for_each_online_cpu(cpu)
xen_pmu_finish(cpu);
on_each_cpu(xen_vcpu_notify_suspend, NULL, 1); on_each_cpu(xen_vcpu_notify_suspend, NULL, 1);
} }

View File

@ -277,12 +277,12 @@ static int ablkcipher_walk_first(struct ablkcipher_request *req,
if (WARN_ON_ONCE(in_irq())) if (WARN_ON_ONCE(in_irq()))
return -EDEADLK; return -EDEADLK;
walk->iv = req->info;
walk->nbytes = walk->total; walk->nbytes = walk->total;
if (unlikely(!walk->total)) if (unlikely(!walk->total))
return 0; return 0;
walk->iv_buffer = NULL; walk->iv_buffer = NULL;
walk->iv = req->info;
if (unlikely(((unsigned long)walk->iv & alignmask))) { if (unlikely(((unsigned long)walk->iv & alignmask))) {
int err = ablkcipher_copy_iv(walk, tfm, alignmask); int err = ablkcipher_copy_iv(walk, tfm, alignmask);

View File

@ -326,12 +326,12 @@ static int blkcipher_walk_first(struct blkcipher_desc *desc,
if (WARN_ON_ONCE(in_irq())) if (WARN_ON_ONCE(in_irq()))
return -EDEADLK; return -EDEADLK;
walk->iv = desc->info;
walk->nbytes = walk->total; walk->nbytes = walk->total;
if (unlikely(!walk->total)) if (unlikely(!walk->total))
return 0; return 0;
walk->buffer = NULL; walk->buffer = NULL;
walk->iv = desc->info;
if (unlikely(((unsigned long)walk->iv & walk->alignmask))) { if (unlikely(((unsigned long)walk->iv & walk->alignmask))) {
int err = blkcipher_copy_iv(walk); int err = blkcipher_copy_iv(walk);
if (err) if (err)

View File

@ -1810,7 +1810,7 @@ static void acpi_nfit_notify(struct acpi_device *adev, u32 event)
if (!dev->driver) { if (!dev->driver) {
/* dev->driver may be null if we're being removed */ /* dev->driver may be null if we're being removed */
dev_dbg(dev, "%s: no driver found for dev\n", __func__); dev_dbg(dev, "%s: no driver found for dev\n", __func__);
return; goto out_unlock;
} }
if (!acpi_desc) { if (!acpi_desc) {

View File

@ -390,6 +390,7 @@ static int pm_genpd_runtime_suspend(struct device *dev)
struct generic_pm_domain *genpd; struct generic_pm_domain *genpd;
bool (*stop_ok)(struct device *__dev); bool (*stop_ok)(struct device *__dev);
struct gpd_timing_data *td = &dev_gpd_data(dev)->td; struct gpd_timing_data *td = &dev_gpd_data(dev)->td;
bool runtime_pm = pm_runtime_enabled(dev);
ktime_t time_start; ktime_t time_start;
s64 elapsed_ns; s64 elapsed_ns;
int ret; int ret;
@ -400,12 +401,19 @@ static int pm_genpd_runtime_suspend(struct device *dev)
if (IS_ERR(genpd)) if (IS_ERR(genpd))
return -EINVAL; return -EINVAL;
/*
* A runtime PM centric subsystem/driver may re-use the runtime PM
* callbacks for other purposes than runtime PM. In those scenarios
* runtime PM is disabled. Under these circumstances, we shall skip
* validating/measuring the PM QoS latency.
*/
stop_ok = genpd->gov ? genpd->gov->stop_ok : NULL; stop_ok = genpd->gov ? genpd->gov->stop_ok : NULL;
if (stop_ok && !stop_ok(dev)) if (runtime_pm && stop_ok && !stop_ok(dev))
return -EBUSY; return -EBUSY;
/* Measure suspend latency. */ /* Measure suspend latency. */
time_start = ktime_get(); if (runtime_pm)
time_start = ktime_get();
ret = genpd_save_dev(genpd, dev); ret = genpd_save_dev(genpd, dev);
if (ret) if (ret)
@ -418,13 +426,15 @@ static int pm_genpd_runtime_suspend(struct device *dev)
} }
/* Update suspend latency value if the measured time exceeds it. */ /* Update suspend latency value if the measured time exceeds it. */
elapsed_ns = ktime_to_ns(ktime_sub(ktime_get(), time_start)); if (runtime_pm) {
if (elapsed_ns > td->suspend_latency_ns) { elapsed_ns = ktime_to_ns(ktime_sub(ktime_get(), time_start));
td->suspend_latency_ns = elapsed_ns; if (elapsed_ns > td->suspend_latency_ns) {
dev_dbg(dev, "suspend latency exceeded, %lld ns\n", td->suspend_latency_ns = elapsed_ns;
elapsed_ns); dev_dbg(dev, "suspend latency exceeded, %lld ns\n",
genpd->max_off_time_changed = true; elapsed_ns);
td->constraint_changed = true; genpd->max_off_time_changed = true;
td->constraint_changed = true;
}
} }
/* /*
@ -453,6 +463,7 @@ static int pm_genpd_runtime_resume(struct device *dev)
{ {
struct generic_pm_domain *genpd; struct generic_pm_domain *genpd;
struct gpd_timing_data *td = &dev_gpd_data(dev)->td; struct gpd_timing_data *td = &dev_gpd_data(dev)->td;
bool runtime_pm = pm_runtime_enabled(dev);
ktime_t time_start; ktime_t time_start;
s64 elapsed_ns; s64 elapsed_ns;
int ret; int ret;
@ -479,14 +490,14 @@ static int pm_genpd_runtime_resume(struct device *dev)
out: out:
/* Measure resume latency. */ /* Measure resume latency. */
if (timed) if (timed && runtime_pm)
time_start = ktime_get(); time_start = ktime_get();
genpd_start_dev(genpd, dev); genpd_start_dev(genpd, dev);
genpd_restore_dev(genpd, dev); genpd_restore_dev(genpd, dev);
/* Update resume latency value if the measured time exceeds it. */ /* Update resume latency value if the measured time exceeds it. */
if (timed) { if (timed && runtime_pm) {
elapsed_ns = ktime_to_ns(ktime_sub(ktime_get(), time_start)); elapsed_ns = ktime_to_ns(ktime_sub(ktime_get(), time_start));
if (elapsed_ns > td->resume_latency_ns) { if (elapsed_ns > td->resume_latency_ns) {
td->resume_latency_ns = elapsed_ns; td->resume_latency_ns = elapsed_ns;

View File

@ -950,6 +950,8 @@ static int xen_blkbk_parse_indirect(struct blkif_request *req,
goto unmap; goto unmap;
for (n = 0, i = 0; n < nseg; n++) { for (n = 0, i = 0; n < nseg; n++) {
uint8_t first_sect, last_sect;
if ((n % SEGS_PER_INDIRECT_FRAME) == 0) { if ((n % SEGS_PER_INDIRECT_FRAME) == 0) {
/* Map indirect segments */ /* Map indirect segments */
if (segments) if (segments)
@ -957,15 +959,18 @@ static int xen_blkbk_parse_indirect(struct blkif_request *req,
segments = kmap_atomic(pages[n/SEGS_PER_INDIRECT_FRAME]->page); segments = kmap_atomic(pages[n/SEGS_PER_INDIRECT_FRAME]->page);
} }
i = n % SEGS_PER_INDIRECT_FRAME; i = n % SEGS_PER_INDIRECT_FRAME;
pending_req->segments[n]->gref = segments[i].gref; pending_req->segments[n]->gref = segments[i].gref;
seg[n].nsec = segments[i].last_sect -
segments[i].first_sect + 1; first_sect = READ_ONCE(segments[i].first_sect);
seg[n].offset = (segments[i].first_sect << 9); last_sect = READ_ONCE(segments[i].last_sect);
if ((segments[i].last_sect >= (XEN_PAGE_SIZE >> 9)) || if (last_sect >= (XEN_PAGE_SIZE >> 9) || last_sect < first_sect) {
(segments[i].last_sect < segments[i].first_sect)) {
rc = -EINVAL; rc = -EINVAL;
goto unmap; goto unmap;
} }
seg[n].nsec = last_sect - first_sect + 1;
seg[n].offset = first_sect << 9;
preq->nr_sects += seg[n].nsec; preq->nr_sects += seg[n].nsec;
} }

View File

@ -408,8 +408,8 @@ static inline void blkif_get_x86_32_req(struct blkif_request *dst,
struct blkif_x86_32_request *src) struct blkif_x86_32_request *src)
{ {
int i, n = BLKIF_MAX_SEGMENTS_PER_REQUEST, j; int i, n = BLKIF_MAX_SEGMENTS_PER_REQUEST, j;
dst->operation = src->operation; dst->operation = READ_ONCE(src->operation);
switch (src->operation) { switch (dst->operation) {
case BLKIF_OP_READ: case BLKIF_OP_READ:
case BLKIF_OP_WRITE: case BLKIF_OP_WRITE:
case BLKIF_OP_WRITE_BARRIER: case BLKIF_OP_WRITE_BARRIER:
@ -456,8 +456,8 @@ static inline void blkif_get_x86_64_req(struct blkif_request *dst,
struct blkif_x86_64_request *src) struct blkif_x86_64_request *src)
{ {
int i, n = BLKIF_MAX_SEGMENTS_PER_REQUEST, j; int i, n = BLKIF_MAX_SEGMENTS_PER_REQUEST, j;
dst->operation = src->operation; dst->operation = READ_ONCE(src->operation);
switch (src->operation) { switch (dst->operation) {
case BLKIF_OP_READ: case BLKIF_OP_READ:
case BLKIF_OP_WRITE: case BLKIF_OP_WRITE:
case BLKIF_OP_WRITE_BARRIER: case BLKIF_OP_WRITE_BARRIER:

View File

@ -226,7 +226,7 @@ config ARM_TEGRA20_CPUFREQ
config ARM_TEGRA124_CPUFREQ config ARM_TEGRA124_CPUFREQ
tristate "Tegra124 CPUFreq support" tristate "Tegra124 CPUFreq support"
depends on ARCH_TEGRA && CPUFREQ_DT depends on ARCH_TEGRA && CPUFREQ_DT && REGULATOR
default y default y
help help
This adds the CPUFreq driver support for Tegra124 SOCs. This adds the CPUFreq driver support for Tegra124 SOCs.

View File

@ -1123,7 +1123,7 @@ static int intel_pstate_set_policy(struct cpufreq_policy *policy)
limits->max_sysfs_pct); limits->max_sysfs_pct);
limits->max_perf_pct = max(limits->min_policy_pct, limits->max_perf_pct = max(limits->min_policy_pct,
limits->max_perf_pct); limits->max_perf_pct);
limits->max_perf = round_up(limits->max_perf, 8); limits->max_perf = round_up(limits->max_perf, FRAC_BITS);
/* Make sure min_perf_pct <= max_perf_pct */ /* Make sure min_perf_pct <= max_perf_pct */
limits->min_perf_pct = min(limits->max_perf_pct, limits->min_perf_pct); limits->min_perf_pct = min(limits->max_perf_pct, limits->min_perf_pct);

View File

@ -156,7 +156,7 @@
#define AT_XDMAC_CC_WRIP (0x1 << 23) /* Write in Progress (read only) */ #define AT_XDMAC_CC_WRIP (0x1 << 23) /* Write in Progress (read only) */
#define AT_XDMAC_CC_WRIP_DONE (0x0 << 23) #define AT_XDMAC_CC_WRIP_DONE (0x0 << 23)
#define AT_XDMAC_CC_WRIP_IN_PROGRESS (0x1 << 23) #define AT_XDMAC_CC_WRIP_IN_PROGRESS (0x1 << 23)
#define AT_XDMAC_CC_PERID(i) (0x7f & (h) << 24) /* Channel Peripheral Identifier */ #define AT_XDMAC_CC_PERID(i) (0x7f & (i) << 24) /* Channel Peripheral Identifier */
#define AT_XDMAC_CDS_MSP 0x2C /* Channel Data Stride Memory Set Pattern */ #define AT_XDMAC_CDS_MSP 0x2C /* Channel Data Stride Memory Set Pattern */
#define AT_XDMAC_CSUS 0x30 /* Channel Source Microblock Stride */ #define AT_XDMAC_CSUS 0x30 /* Channel Source Microblock Stride */
#define AT_XDMAC_CDUS 0x34 /* Channel Destination Microblock Stride */ #define AT_XDMAC_CDUS 0x34 /* Channel Destination Microblock Stride */
@ -965,7 +965,9 @@ at_xdmac_prep_interleaved(struct dma_chan *chan,
NULL, NULL,
src_addr, dst_addr, src_addr, dst_addr,
xt, xt->sgl); xt, xt->sgl);
for (i = 0; i < xt->numf; i++)
/* Length of the block is (BLEN+1) microblocks. */
for (i = 0; i < xt->numf - 1; i++)
at_xdmac_increment_block_count(chan, first); at_xdmac_increment_block_count(chan, first);
dev_dbg(chan2dev(chan), "%s: add desc 0x%p to descs_list 0x%p\n", dev_dbg(chan2dev(chan), "%s: add desc 0x%p to descs_list 0x%p\n",
@ -1086,6 +1088,7 @@ at_xdmac_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
/* Check remaining length and change data width if needed. */ /* Check remaining length and change data width if needed. */
dwidth = at_xdmac_align_width(chan, dwidth = at_xdmac_align_width(chan,
src_addr | dst_addr | xfer_size); src_addr | dst_addr | xfer_size);
chan_cc &= ~AT_XDMAC_CC_DWIDTH_MASK;
chan_cc |= AT_XDMAC_CC_DWIDTH(dwidth); chan_cc |= AT_XDMAC_CC_DWIDTH(dwidth);
ublen = xfer_size >> dwidth; ublen = xfer_size >> dwidth;
@ -1333,7 +1336,7 @@ at_xdmac_prep_dma_memset_sg(struct dma_chan *chan, struct scatterlist *sgl,
* since we don't care about the stride anymore. * since we don't care about the stride anymore.
*/ */
if ((i == (sg_len - 1)) && if ((i == (sg_len - 1)) &&
sg_dma_len(ppsg) == sg_dma_len(psg)) { sg_dma_len(psg) == sg_dma_len(sg)) {
dev_dbg(chan2dev(chan), dev_dbg(chan2dev(chan),
"%s: desc 0x%p can be merged with desc 0x%p\n", "%s: desc 0x%p can be merged with desc 0x%p\n",
__func__, desc, pdesc); __func__, desc, pdesc);

View File

@ -31,6 +31,7 @@
*/ */
#include <linux/dmaengine.h> #include <linux/dmaengine.h>
#include <linux/dma-mapping.h> #include <linux/dma-mapping.h>
#include <linux/dmapool.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
@ -62,6 +63,11 @@ struct bcm2835_dma_cb {
uint32_t pad[2]; uint32_t pad[2];
}; };
struct bcm2835_cb_entry {
struct bcm2835_dma_cb *cb;
dma_addr_t paddr;
};
struct bcm2835_chan { struct bcm2835_chan {
struct virt_dma_chan vc; struct virt_dma_chan vc;
struct list_head node; struct list_head node;
@ -72,18 +78,18 @@ struct bcm2835_chan {
int ch; int ch;
struct bcm2835_desc *desc; struct bcm2835_desc *desc;
struct dma_pool *cb_pool;
void __iomem *chan_base; void __iomem *chan_base;
int irq_number; int irq_number;
}; };
struct bcm2835_desc { struct bcm2835_desc {
struct bcm2835_chan *c;
struct virt_dma_desc vd; struct virt_dma_desc vd;
enum dma_transfer_direction dir; enum dma_transfer_direction dir;
unsigned int control_block_size; struct bcm2835_cb_entry *cb_list;
struct bcm2835_dma_cb *control_block_base;
dma_addr_t control_block_base_phys;
unsigned int frames; unsigned int frames;
size_t size; size_t size;
@ -143,10 +149,13 @@ static inline struct bcm2835_desc *to_bcm2835_dma_desc(
static void bcm2835_dma_desc_free(struct virt_dma_desc *vd) static void bcm2835_dma_desc_free(struct virt_dma_desc *vd)
{ {
struct bcm2835_desc *desc = container_of(vd, struct bcm2835_desc, vd); struct bcm2835_desc *desc = container_of(vd, struct bcm2835_desc, vd);
dma_free_coherent(desc->vd.tx.chan->device->dev, int i;
desc->control_block_size,
desc->control_block_base, for (i = 0; i < desc->frames; i++)
desc->control_block_base_phys); dma_pool_free(desc->c->cb_pool, desc->cb_list[i].cb,
desc->cb_list[i].paddr);
kfree(desc->cb_list);
kfree(desc); kfree(desc);
} }
@ -199,7 +208,7 @@ static void bcm2835_dma_start_desc(struct bcm2835_chan *c)
c->desc = d = to_bcm2835_dma_desc(&vd->tx); c->desc = d = to_bcm2835_dma_desc(&vd->tx);
writel(d->control_block_base_phys, c->chan_base + BCM2835_DMA_ADDR); writel(d->cb_list[0].paddr, c->chan_base + BCM2835_DMA_ADDR);
writel(BCM2835_DMA_ACTIVE, c->chan_base + BCM2835_DMA_CS); writel(BCM2835_DMA_ACTIVE, c->chan_base + BCM2835_DMA_CS);
} }
@ -232,9 +241,16 @@ static irqreturn_t bcm2835_dma_callback(int irq, void *data)
static int bcm2835_dma_alloc_chan_resources(struct dma_chan *chan) static int bcm2835_dma_alloc_chan_resources(struct dma_chan *chan)
{ {
struct bcm2835_chan *c = to_bcm2835_dma_chan(chan); struct bcm2835_chan *c = to_bcm2835_dma_chan(chan);
struct device *dev = c->vc.chan.device->dev;
dev_dbg(c->vc.chan.device->dev, dev_dbg(dev, "Allocating DMA channel %d\n", c->ch);
"Allocating DMA channel %d\n", c->ch);
c->cb_pool = dma_pool_create(dev_name(dev), dev,
sizeof(struct bcm2835_dma_cb), 0, 0);
if (!c->cb_pool) {
dev_err(dev, "unable to allocate descriptor pool\n");
return -ENOMEM;
}
return request_irq(c->irq_number, return request_irq(c->irq_number,
bcm2835_dma_callback, 0, "DMA IRQ", c); bcm2835_dma_callback, 0, "DMA IRQ", c);
@ -246,6 +262,7 @@ static void bcm2835_dma_free_chan_resources(struct dma_chan *chan)
vchan_free_chan_resources(&c->vc); vchan_free_chan_resources(&c->vc);
free_irq(c->irq_number, c); free_irq(c->irq_number, c);
dma_pool_destroy(c->cb_pool);
dev_dbg(c->vc.chan.device->dev, "Freeing DMA channel %u\n", c->ch); dev_dbg(c->vc.chan.device->dev, "Freeing DMA channel %u\n", c->ch);
} }
@ -261,8 +278,7 @@ static size_t bcm2835_dma_desc_size_pos(struct bcm2835_desc *d, dma_addr_t addr)
size_t size; size_t size;
for (size = i = 0; i < d->frames; i++) { for (size = i = 0; i < d->frames; i++) {
struct bcm2835_dma_cb *control_block = struct bcm2835_dma_cb *control_block = d->cb_list[i].cb;
&d->control_block_base[i];
size_t this_size = control_block->length; size_t this_size = control_block->length;
dma_addr_t dma; dma_addr_t dma;
@ -343,6 +359,7 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_dma_cyclic(
dma_addr_t dev_addr; dma_addr_t dev_addr;
unsigned int es, sync_type; unsigned int es, sync_type;
unsigned int frame; unsigned int frame;
int i;
/* Grab configuration */ /* Grab configuration */
if (!is_slave_direction(direction)) { if (!is_slave_direction(direction)) {
@ -374,27 +391,31 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_dma_cyclic(
if (!d) if (!d)
return NULL; return NULL;
d->c = c;
d->dir = direction; d->dir = direction;
d->frames = buf_len / period_len; d->frames = buf_len / period_len;
/* Allocate memory for control blocks */ d->cb_list = kcalloc(d->frames, sizeof(*d->cb_list), GFP_KERNEL);
d->control_block_size = d->frames * sizeof(struct bcm2835_dma_cb); if (!d->cb_list) {
d->control_block_base = dma_zalloc_coherent(chan->device->dev,
d->control_block_size, &d->control_block_base_phys,
GFP_NOWAIT);
if (!d->control_block_base) {
kfree(d); kfree(d);
return NULL; return NULL;
} }
/* Allocate memory for control blocks */
for (i = 0; i < d->frames; i++) {
struct bcm2835_cb_entry *cb_entry = &d->cb_list[i];
cb_entry->cb = dma_pool_zalloc(c->cb_pool, GFP_ATOMIC,
&cb_entry->paddr);
if (!cb_entry->cb)
goto error_cb;
}
/* /*
* Iterate over all frames, create a control block * Iterate over all frames, create a control block
* for each frame and link them together. * for each frame and link them together.
*/ */
for (frame = 0; frame < d->frames; frame++) { for (frame = 0; frame < d->frames; frame++) {
struct bcm2835_dma_cb *control_block = struct bcm2835_dma_cb *control_block = d->cb_list[frame].cb;
&d->control_block_base[frame];
/* Setup adresses */ /* Setup adresses */
if (d->dir == DMA_DEV_TO_MEM) { if (d->dir == DMA_DEV_TO_MEM) {
@ -428,12 +449,21 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_dma_cyclic(
* This DMA engine driver currently only supports cyclic DMA. * This DMA engine driver currently only supports cyclic DMA.
* Therefore, wrap around at number of frames. * Therefore, wrap around at number of frames.
*/ */
control_block->next = d->control_block_base_phys + control_block->next = d->cb_list[((frame + 1) % d->frames)].paddr;
sizeof(struct bcm2835_dma_cb)
* ((frame + 1) % d->frames);
} }
return vchan_tx_prep(&c->vc, &d->vd, flags); return vchan_tx_prep(&c->vc, &d->vd, flags);
error_cb:
i--;
for (; i >= 0; i--) {
struct bcm2835_cb_entry *cb_entry = &d->cb_list[i];
dma_pool_free(c->cb_pool, cb_entry->cb, cb_entry->paddr);
}
kfree(d->cb_list);
kfree(d);
return NULL;
} }
static int bcm2835_dma_slave_config(struct dma_chan *chan, static int bcm2835_dma_slave_config(struct dma_chan *chan,

View File

@ -1752,16 +1752,14 @@ static enum dma_status edma_tx_status(struct dma_chan *chan,
return ret; return ret;
} }
static bool edma_is_memcpy_channel(int ch_num, u16 *memcpy_channels) static bool edma_is_memcpy_channel(int ch_num, s32 *memcpy_channels)
{ {
s16 *memcpy_ch = memcpy_channels;
if (!memcpy_channels) if (!memcpy_channels)
return false; return false;
while (*memcpy_ch != -1) { while (*memcpy_channels != -1) {
if (*memcpy_ch == ch_num) if (*memcpy_channels == ch_num)
return true; return true;
memcpy_ch++; memcpy_channels++;
} }
return false; return false;
} }
@ -1775,7 +1773,7 @@ static void edma_dma_init(struct edma_cc *ecc, bool legacy_mode)
{ {
struct dma_device *s_ddev = &ecc->dma_slave; struct dma_device *s_ddev = &ecc->dma_slave;
struct dma_device *m_ddev = NULL; struct dma_device *m_ddev = NULL;
s16 *memcpy_channels = ecc->info->memcpy_channels; s32 *memcpy_channels = ecc->info->memcpy_channels;
int i, j; int i, j;
dma_cap_zero(s_ddev->cap_mask); dma_cap_zero(s_ddev->cap_mask);
@ -1996,16 +1994,16 @@ static struct edma_soc_info *edma_setup_info_from_dt(struct device *dev,
prop = of_find_property(dev->of_node, "ti,edma-memcpy-channels", &sz); prop = of_find_property(dev->of_node, "ti,edma-memcpy-channels", &sz);
if (prop) { if (prop) {
const char pname[] = "ti,edma-memcpy-channels"; const char pname[] = "ti,edma-memcpy-channels";
size_t nelm = sz / sizeof(s16); size_t nelm = sz / sizeof(s32);
s16 *memcpy_ch; s32 *memcpy_ch;
memcpy_ch = devm_kcalloc(dev, nelm + 1, sizeof(s16), memcpy_ch = devm_kcalloc(dev, nelm + 1, sizeof(s32),
GFP_KERNEL); GFP_KERNEL);
if (!memcpy_ch) if (!memcpy_ch)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
ret = of_property_read_u16_array(dev->of_node, pname, ret = of_property_read_u32_array(dev->of_node, pname,
(u16 *)memcpy_ch, nelm); (u32 *)memcpy_ch, nelm);
if (ret) if (ret)
return ERR_PTR(ret); return ERR_PTR(ret);
@ -2017,31 +2015,50 @@ static struct edma_soc_info *edma_setup_info_from_dt(struct device *dev,
&sz); &sz);
if (prop) { if (prop) {
const char pname[] = "ti,edma-reserved-slot-ranges"; const char pname[] = "ti,edma-reserved-slot-ranges";
u32 (*tmp)[2];
s16 (*rsv_slots)[2]; s16 (*rsv_slots)[2];
size_t nelm = sz / sizeof(*rsv_slots); size_t nelm = sz / sizeof(*tmp);
struct edma_rsv_info *rsv_info; struct edma_rsv_info *rsv_info;
int i;
if (!nelm) if (!nelm)
return info; return info;
rsv_info = devm_kzalloc(dev, sizeof(*rsv_info), GFP_KERNEL); tmp = kcalloc(nelm, sizeof(*tmp), GFP_KERNEL);
if (!rsv_info) if (!tmp)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
rsv_info = devm_kzalloc(dev, sizeof(*rsv_info), GFP_KERNEL);
if (!rsv_info) {
kfree(tmp);
return ERR_PTR(-ENOMEM);
}
rsv_slots = devm_kcalloc(dev, nelm + 1, sizeof(*rsv_slots), rsv_slots = devm_kcalloc(dev, nelm + 1, sizeof(*rsv_slots),
GFP_KERNEL); GFP_KERNEL);
if (!rsv_slots) if (!rsv_slots) {
kfree(tmp);
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
}
ret = of_property_read_u16_array(dev->of_node, pname, ret = of_property_read_u32_array(dev->of_node, pname,
(u16 *)rsv_slots, nelm * 2); (u32 *)tmp, nelm * 2);
if (ret) if (ret) {
kfree(tmp);
return ERR_PTR(ret); return ERR_PTR(ret);
}
for (i = 0; i < nelm; i++) {
rsv_slots[i][0] = tmp[i][0];
rsv_slots[i][1] = tmp[i][1];
}
rsv_slots[nelm][0] = -1; rsv_slots[nelm][0] = -1;
rsv_slots[nelm][1] = -1; rsv_slots[nelm][1] = -1;
info->rsv = rsv_info; info->rsv = rsv_info;
info->rsv->rsv_slots = (const s16 (*)[2])rsv_slots; info->rsv->rsv_slots = (const s16 (*)[2])rsv_slots;
kfree(tmp);
} }
return info; return info;

View File

@ -317,6 +317,7 @@ mic_dma_prep_memcpy_lock(struct dma_chan *ch, dma_addr_t dma_dest,
struct mic_dma_chan *mic_ch = to_mic_dma_chan(ch); struct mic_dma_chan *mic_ch = to_mic_dma_chan(ch);
struct device *dev = mic_dma_ch_to_device(mic_ch); struct device *dev = mic_dma_ch_to_device(mic_ch);
int result; int result;
struct dma_async_tx_descriptor *tx = NULL;
if (!len && !flags) if (!len && !flags)
return NULL; return NULL;
@ -324,10 +325,13 @@ mic_dma_prep_memcpy_lock(struct dma_chan *ch, dma_addr_t dma_dest,
spin_lock(&mic_ch->prep_lock); spin_lock(&mic_ch->prep_lock);
result = mic_dma_do_dma(mic_ch, flags, dma_src, dma_dest, len); result = mic_dma_do_dma(mic_ch, flags, dma_src, dma_dest, len);
if (result >= 0) if (result >= 0)
return allocate_tx(mic_ch); tx = allocate_tx(mic_ch);
dev_err(dev, "Error enqueueing dma, error=%d\n", result);
if (!tx)
dev_err(dev, "Error enqueueing dma, error=%d\n", result);
spin_unlock(&mic_ch->prep_lock); spin_unlock(&mic_ch->prep_lock);
return NULL; return tx;
} }
static struct dma_async_tx_descriptor * static struct dma_async_tx_descriptor *
@ -335,13 +339,14 @@ mic_dma_prep_interrupt_lock(struct dma_chan *ch, unsigned long flags)
{ {
struct mic_dma_chan *mic_ch = to_mic_dma_chan(ch); struct mic_dma_chan *mic_ch = to_mic_dma_chan(ch);
int ret; int ret;
struct dma_async_tx_descriptor *tx = NULL;
spin_lock(&mic_ch->prep_lock); spin_lock(&mic_ch->prep_lock);
ret = mic_dma_do_dma(mic_ch, flags, 0, 0, 0); ret = mic_dma_do_dma(mic_ch, flags, 0, 0, 0);
if (!ret) if (!ret)
return allocate_tx(mic_ch); tx = allocate_tx(mic_ch);
spin_unlock(&mic_ch->prep_lock); spin_unlock(&mic_ch->prep_lock);
return NULL; return tx;
} }
/* Return the status of the transaction */ /* Return the status of the transaction */

View File

@ -113,7 +113,7 @@ static int ar934x_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
__raw_writel(BIT(offset), ctrl->base + AR71XX_GPIO_REG_CLEAR); __raw_writel(BIT(offset), ctrl->base + AR71XX_GPIO_REG_CLEAR);
__raw_writel( __raw_writel(
__raw_readl(ctrl->base + AR71XX_GPIO_REG_OE) & BIT(offset), __raw_readl(ctrl->base + AR71XX_GPIO_REG_OE) & ~BIT(offset),
ctrl->base + AR71XX_GPIO_REG_OE); ctrl->base + AR71XX_GPIO_REG_OE);
spin_unlock_irqrestore(&ctrl->lock, flags); spin_unlock_irqrestore(&ctrl->lock, flags);

View File

@ -141,9 +141,9 @@ static int bgpio_get_set(struct gpio_chip *gc, unsigned int gpio)
unsigned long pinmask = bgc->pin2mask(bgc, gpio); unsigned long pinmask = bgc->pin2mask(bgc, gpio);
if (bgc->dir & pinmask) if (bgc->dir & pinmask)
return bgc->read_reg(bgc->reg_set) & pinmask; return !!(bgc->read_reg(bgc->reg_set) & pinmask);
else else
return bgc->read_reg(bgc->reg_dat) & pinmask; return !!(bgc->read_reg(bgc->reg_dat) & pinmask);
} }
static int bgpio_get(struct gpio_chip *gc, unsigned int gpio) static int bgpio_get(struct gpio_chip *gc, unsigned int gpio)

View File

@ -1279,7 +1279,13 @@ static int _gpiod_get_raw_value(const struct gpio_desc *desc)
chip = desc->chip; chip = desc->chip;
offset = gpio_chip_hwgpio(desc); offset = gpio_chip_hwgpio(desc);
value = chip->get ? chip->get(chip, offset) : -EIO; value = chip->get ? chip->get(chip, offset) : -EIO;
value = value < 0 ? value : !!value; /*
* FIXME: fix all drivers to clamp to [0,1] or return negative,
* then change this to:
* value = value < 0 ? value : !!value;
* so we can properly propagate error codes.
*/
value = !!value;
trace_gpio_value(desc_to_gpio(desc), 1, value); trace_gpio_value(desc_to_gpio(desc), 1, value);
return value; return value;
} }

View File

@ -229,7 +229,8 @@ static int drm_helper_probe_single_connector_modes_merge_bits(struct drm_connect
mode_flags |= DRM_MODE_FLAG_3D_MASK; mode_flags |= DRM_MODE_FLAG_3D_MASK;
list_for_each_entry(mode, &connector->modes, head) { list_for_each_entry(mode, &connector->modes, head) {
mode->status = drm_mode_validate_basic(mode); if (mode->status == MODE_OK)
mode->status = drm_mode_validate_basic(mode);
if (mode->status == MODE_OK) if (mode->status == MODE_OK)
mode->status = drm_mode_validate_size(mode, maxX, maxY); mode->status = drm_mode_validate_size(mode, maxX, maxY);

View File

@ -141,8 +141,6 @@ static void i915_gem_context_clean(struct intel_context *ctx)
if (!ppgtt) if (!ppgtt)
return; return;
WARN_ON(!list_empty(&ppgtt->base.active_list));
list_for_each_entry_safe(vma, next, &ppgtt->base.inactive_list, list_for_each_entry_safe(vma, next, &ppgtt->base.inactive_list,
mm_list) { mm_list) {
if (WARN_ON(__i915_vma_unbind_no_wait(vma))) if (WARN_ON(__i915_vma_unbind_no_wait(vma)))

View File

@ -6309,9 +6309,11 @@ static void intel_crtc_disable_noatomic(struct drm_crtc *crtc)
if (to_intel_plane_state(crtc->primary->state)->visible) { if (to_intel_plane_state(crtc->primary->state)->visible) {
intel_crtc_wait_for_pending_flips(crtc); intel_crtc_wait_for_pending_flips(crtc);
intel_pre_disable_primary(crtc); intel_pre_disable_primary(crtc);
intel_crtc_disable_planes(crtc, 1 << drm_plane_index(crtc->primary));
to_intel_plane_state(crtc->primary->state)->visible = false;
} }
intel_crtc_disable_planes(crtc, crtc->state->plane_mask);
dev_priv->display.crtc_disable(crtc); dev_priv->display.crtc_disable(crtc);
intel_crtc->active = false; intel_crtc->active = false;
intel_update_watermarks(crtc); intel_update_watermarks(crtc);

View File

@ -4782,8 +4782,7 @@ static void gen9_enable_rc6(struct drm_device *dev)
/* 2b: Program RC6 thresholds.*/ /* 2b: Program RC6 thresholds.*/
/* WaRsDoubleRc6WrlWithCoarsePowerGating: Doubling WRL only when CPG is enabled */ /* WaRsDoubleRc6WrlWithCoarsePowerGating: Doubling WRL only when CPG is enabled */
if (IS_SKYLAKE(dev) && !((IS_SKL_GT3(dev) || IS_SKL_GT4(dev)) && if (IS_SKYLAKE(dev))
(INTEL_REVID(dev) <= SKL_REVID_E0)))
I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 108 << 16); I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 108 << 16);
else else
I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 54 << 16); I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 54 << 16);
@ -4825,7 +4824,7 @@ static void gen9_enable_rc6(struct drm_device *dev)
* WaRsDisableCoarsePowerGating:skl,bxt - Render/Media PG need to be disabled with RC6. * WaRsDisableCoarsePowerGating:skl,bxt - Render/Media PG need to be disabled with RC6.
*/ */
if ((IS_BROXTON(dev) && (INTEL_REVID(dev) < BXT_REVID_B0)) || if ((IS_BROXTON(dev) && (INTEL_REVID(dev) < BXT_REVID_B0)) ||
((IS_SKL_GT3(dev) || IS_SKL_GT4(dev)) && (INTEL_REVID(dev) <= SKL_REVID_E0))) ((IS_SKL_GT3(dev) || IS_SKL_GT4(dev)) && (INTEL_REVID(dev) <= SKL_REVID_F0)))
I915_WRITE(GEN9_PG_ENABLE, 0); I915_WRITE(GEN9_PG_ENABLE, 0);
else else
I915_WRITE(GEN9_PG_ENABLE, (rc6_mask & GEN6_RC_CTL_RC6_ENABLE) ? I915_WRITE(GEN9_PG_ENABLE, (rc6_mask & GEN6_RC_CTL_RC6_ENABLE) ?

View File

@ -112,11 +112,8 @@ static int omap_fbdev_create(struct drm_fb_helper *helper,
dma_addr_t paddr; dma_addr_t paddr;
int ret; int ret;
/* only doing ARGB32 since this is what is needed to alpha-blend
* with video overlays:
*/
sizes->surface_bpp = 32; sizes->surface_bpp = 32;
sizes->surface_depth = 32; sizes->surface_depth = 24;
DBG("create fbdev: %dx%d@%d (%dx%d)", sizes->surface_width, DBG("create fbdev: %dx%d@%d (%dx%d)", sizes->surface_width,
sizes->surface_height, sizes->surface_bpp, sizes->surface_height, sizes->surface_bpp,

View File

@ -1217,6 +1217,7 @@ config SENSORS_PWM_FAN
config SENSORS_SHT15 config SENSORS_SHT15
tristate "Sensiron humidity and temperature sensors. SHT15 and compat." tristate "Sensiron humidity and temperature sensors. SHT15 and compat."
depends on GPIOLIB || COMPILE_TEST depends on GPIOLIB || COMPILE_TEST
select BITREVERSE
help help
If you say yes here you get support for the Sensiron SHT10, SHT11, If you say yes here you get support for the Sensiron SHT10, SHT11,
SHT15, SHT71, SHT75 humidity and temperature sensors. SHT15, SHT71, SHT75 humidity and temperature sensors.

View File

@ -58,6 +58,7 @@ struct tmp102 {
u16 config_orig; u16 config_orig;
unsigned long last_update; unsigned long last_update;
int temp[3]; int temp[3];
bool first_time;
}; };
/* convert left adjusted 13-bit TMP102 register value to milliCelsius */ /* convert left adjusted 13-bit TMP102 register value to milliCelsius */
@ -93,6 +94,7 @@ static struct tmp102 *tmp102_update_device(struct device *dev)
tmp102->temp[i] = tmp102_reg_to_mC(status); tmp102->temp[i] = tmp102_reg_to_mC(status);
} }
tmp102->last_update = jiffies; tmp102->last_update = jiffies;
tmp102->first_time = false;
} }
mutex_unlock(&tmp102->lock); mutex_unlock(&tmp102->lock);
return tmp102; return tmp102;
@ -102,6 +104,12 @@ static int tmp102_read_temp(void *dev, int *temp)
{ {
struct tmp102 *tmp102 = tmp102_update_device(dev); struct tmp102 *tmp102 = tmp102_update_device(dev);
/* Is it too early even to return a conversion? */
if (tmp102->first_time) {
dev_dbg(dev, "%s: Conversion not ready yet..\n", __func__);
return -EAGAIN;
}
*temp = tmp102->temp[0]; *temp = tmp102->temp[0];
return 0; return 0;
@ -114,6 +122,10 @@ static ssize_t tmp102_show_temp(struct device *dev,
struct sensor_device_attribute *sda = to_sensor_dev_attr(attr); struct sensor_device_attribute *sda = to_sensor_dev_attr(attr);
struct tmp102 *tmp102 = tmp102_update_device(dev); struct tmp102 *tmp102 = tmp102_update_device(dev);
/* Is it too early even to return a read? */
if (tmp102->first_time)
return -EAGAIN;
return sprintf(buf, "%d\n", tmp102->temp[sda->index]); return sprintf(buf, "%d\n", tmp102->temp[sda->index]);
} }
@ -207,7 +219,9 @@ static int tmp102_probe(struct i2c_client *client,
status = -ENODEV; status = -ENODEV;
goto fail_restore_config; goto fail_restore_config;
} }
tmp102->last_update = jiffies - HZ; tmp102->last_update = jiffies;
/* Mark that we are not ready with data until conversion is complete */
tmp102->first_time = true;
mutex_init(&tmp102->lock); mutex_init(&tmp102->lock);
hwmon_dev = hwmon_device_register_with_groups(dev, client->name, hwmon_dev = hwmon_device_register_with_groups(dev, client->name,

View File

@ -202,8 +202,15 @@ static void i2c_davinci_calc_clk_dividers(struct davinci_i2c_dev *dev)
* d is always 6 on Keystone I2C controller * d is always 6 on Keystone I2C controller
*/ */
/* get minimum of 7 MHz clock, but max of 12 MHz */ /*
psc = (input_clock / 7000000) - 1; * Both Davinci and current Keystone User Guides recommend a value
* between 7MHz and 12MHz. In reality 7MHz module clock doesn't
* always produce enough margin between SDA and SCL transitions.
* Measurements show that the higher the module clock is, the
* bigger is the margin, providing more reliable communication.
* So we better target for 12MHz.
*/
psc = (input_clock / 12000000) - 1;
if ((input_clock / (psc + 1)) > 12000000) if ((input_clock / (psc + 1)) > 12000000)
psc++; /* better to run under spec than over */ psc++; /* better to run under spec than over */
d = (psc >= 2) ? 5 : 7 - psc; d = (psc >= 2) ? 5 : 7 - psc;

View File

@ -813,6 +813,12 @@ static irqreturn_t i2c_dw_isr(int this_irq, void *dev_id)
tx_aborted: tx_aborted:
if ((stat & (DW_IC_INTR_TX_ABRT | DW_IC_INTR_STOP_DET)) || dev->msg_err) if ((stat & (DW_IC_INTR_TX_ABRT | DW_IC_INTR_STOP_DET)) || dev->msg_err)
complete(&dev->cmd_complete); complete(&dev->cmd_complete);
else if (unlikely(dev->accessor_flags & ACCESS_INTR_MASK)) {
/* workaround to trigger pending interrupt */
stat = dw_readl(dev, DW_IC_INTR_MASK);
i2c_dw_disable_int(dev);
dw_writel(dev, stat, DW_IC_INTR_MASK);
}
return IRQ_HANDLED; return IRQ_HANDLED;
} }

View File

@ -111,6 +111,7 @@ struct dw_i2c_dev {
#define ACCESS_SWAP 0x00000001 #define ACCESS_SWAP 0x00000001
#define ACCESS_16BIT 0x00000002 #define ACCESS_16BIT 0x00000002
#define ACCESS_INTR_MASK 0x00000004
extern int i2c_dw_init(struct dw_i2c_dev *dev); extern int i2c_dw_init(struct dw_i2c_dev *dev);
extern void i2c_dw_disable(struct dw_i2c_dev *dev); extern void i2c_dw_disable(struct dw_i2c_dev *dev);

View File

@ -93,6 +93,7 @@ static void dw_i2c_acpi_params(struct platform_device *pdev, char method[],
static int dw_i2c_acpi_configure(struct platform_device *pdev) static int dw_i2c_acpi_configure(struct platform_device *pdev)
{ {
struct dw_i2c_dev *dev = platform_get_drvdata(pdev); struct dw_i2c_dev *dev = platform_get_drvdata(pdev);
const struct acpi_device_id *id;
dev->adapter.nr = -1; dev->adapter.nr = -1;
dev->tx_fifo_depth = 32; dev->tx_fifo_depth = 32;
@ -106,6 +107,10 @@ static int dw_i2c_acpi_configure(struct platform_device *pdev)
dw_i2c_acpi_params(pdev, "FMCN", &dev->fs_hcnt, &dev->fs_lcnt, dw_i2c_acpi_params(pdev, "FMCN", &dev->fs_hcnt, &dev->fs_lcnt,
&dev->sda_hold_time); &dev->sda_hold_time);
id = acpi_match_device(pdev->dev.driver->acpi_match_table, &pdev->dev);
if (id && id->driver_data)
dev->accessor_flags |= (u32)id->driver_data;
return 0; return 0;
} }
@ -116,7 +121,7 @@ static const struct acpi_device_id dw_i2c_acpi_match[] = {
{ "INT3433", 0 }, { "INT3433", 0 },
{ "80860F41", 0 }, { "80860F41", 0 },
{ "808622C1", 0 }, { "808622C1", 0 },
{ "AMD0010", 0 }, { "AMD0010", ACCESS_INTR_MASK },
{ } { }
}; };
MODULE_DEVICE_TABLE(acpi, dw_i2c_acpi_match); MODULE_DEVICE_TABLE(acpi, dw_i2c_acpi_match);
@ -240,12 +245,10 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
} }
r = i2c_dw_probe(dev); r = i2c_dw_probe(dev);
if (r) { if (r && !dev->pm_runtime_disabled)
pm_runtime_disable(&pdev->dev); pm_runtime_disable(&pdev->dev);
return r;
}
return 0; return r;
} }
static int dw_i2c_plat_remove(struct platform_device *pdev) static int dw_i2c_plat_remove(struct platform_device *pdev)
@ -260,7 +263,8 @@ static int dw_i2c_plat_remove(struct platform_device *pdev)
pm_runtime_dont_use_autosuspend(&pdev->dev); pm_runtime_dont_use_autosuspend(&pdev->dev);
pm_runtime_put_sync(&pdev->dev); pm_runtime_put_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev); if (!dev->pm_runtime_disabled)
pm_runtime_disable(&pdev->dev);
return 0; return 0;
} }

View File

@ -1119,6 +1119,8 @@ static int i2c_imx_probe(struct platform_device *pdev)
i2c_imx, IMX_I2C_I2CR); i2c_imx, IMX_I2C_I2CR);
imx_i2c_write_reg(i2c_imx->hwdata->i2sr_clr_opcode, i2c_imx, IMX_I2C_I2SR); imx_i2c_write_reg(i2c_imx->hwdata->i2sr_clr_opcode, i2c_imx, IMX_I2C_I2SR);
i2c_imx_init_recovery_info(i2c_imx, pdev);
/* Add I2C adapter */ /* Add I2C adapter */
ret = i2c_add_numbered_adapter(&i2c_imx->adapter); ret = i2c_add_numbered_adapter(&i2c_imx->adapter);
if (ret < 0) { if (ret < 0) {
@ -1126,8 +1128,6 @@ static int i2c_imx_probe(struct platform_device *pdev)
goto clk_disable; goto clk_disable;
} }
i2c_imx_init_recovery_info(i2c_imx, pdev);
/* Set up platform driver data */ /* Set up platform driver data */
platform_set_drvdata(pdev, i2c_imx); platform_set_drvdata(pdev, i2c_imx);
clk_disable_unprepare(i2c_imx->clk); clk_disable_unprepare(i2c_imx->clk);

View File

@ -146,6 +146,8 @@ struct mv64xxx_i2c_data {
bool errata_delay; bool errata_delay;
struct reset_control *rstc; struct reset_control *rstc;
bool irq_clear_inverted; bool irq_clear_inverted;
/* Clk div is 2 to the power n, not 2 to the power n + 1 */
bool clk_n_base_0;
}; };
static struct mv64xxx_i2c_regs mv64xxx_i2c_regs_mv64xxx = { static struct mv64xxx_i2c_regs mv64xxx_i2c_regs_mv64xxx = {
@ -757,25 +759,29 @@ MODULE_DEVICE_TABLE(of, mv64xxx_i2c_of_match_table);
#ifdef CONFIG_OF #ifdef CONFIG_OF
#ifdef CONFIG_HAVE_CLK #ifdef CONFIG_HAVE_CLK
static int static int
mv64xxx_calc_freq(const int tclk, const int n, const int m) mv64xxx_calc_freq(struct mv64xxx_i2c_data *drv_data,
const int tclk, const int n, const int m)
{ {
return tclk / (10 * (m + 1) * (2 << n)); if (drv_data->clk_n_base_0)
return tclk / (10 * (m + 1) * (1 << n));
else
return tclk / (10 * (m + 1) * (2 << n));
} }
static bool static bool
mv64xxx_find_baud_factors(const u32 req_freq, const u32 tclk, u32 *best_n, mv64xxx_find_baud_factors(struct mv64xxx_i2c_data *drv_data,
u32 *best_m) const u32 req_freq, const u32 tclk)
{ {
int freq, delta, best_delta = INT_MAX; int freq, delta, best_delta = INT_MAX;
int m, n; int m, n;
for (n = 0; n <= 7; n++) for (n = 0; n <= 7; n++)
for (m = 0; m <= 15; m++) { for (m = 0; m <= 15; m++) {
freq = mv64xxx_calc_freq(tclk, n, m); freq = mv64xxx_calc_freq(drv_data, tclk, n, m);
delta = req_freq - freq; delta = req_freq - freq;
if (delta >= 0 && delta < best_delta) { if (delta >= 0 && delta < best_delta) {
*best_m = m; drv_data->freq_m = m;
*best_n = n; drv_data->freq_n = n;
best_delta = delta; best_delta = delta;
} }
if (best_delta == 0) if (best_delta == 0)
@ -813,8 +819,11 @@ mv64xxx_of_config(struct mv64xxx_i2c_data *drv_data,
if (of_property_read_u32(np, "clock-frequency", &bus_freq)) if (of_property_read_u32(np, "clock-frequency", &bus_freq))
bus_freq = 100000; /* 100kHz by default */ bus_freq = 100000; /* 100kHz by default */
if (!mv64xxx_find_baud_factors(bus_freq, tclk, if (of_device_is_compatible(np, "allwinner,sun4i-a10-i2c") ||
&drv_data->freq_n, &drv_data->freq_m)) { of_device_is_compatible(np, "allwinner,sun6i-a31-i2c"))
drv_data->clk_n_base_0 = true;
if (!mv64xxx_find_baud_factors(drv_data, bus_freq, tclk)) {
rc = -EINVAL; rc = -EINVAL;
goto out; goto out;
} }

View File

@ -576,7 +576,7 @@ static int rcar_reg_slave(struct i2c_client *slave)
if (slave->flags & I2C_CLIENT_TEN) if (slave->flags & I2C_CLIENT_TEN)
return -EAFNOSUPPORT; return -EAFNOSUPPORT;
pm_runtime_forbid(rcar_i2c_priv_to_dev(priv)); pm_runtime_get_sync(rcar_i2c_priv_to_dev(priv));
priv->slave = slave; priv->slave = slave;
rcar_i2c_write(priv, ICSAR, slave->addr); rcar_i2c_write(priv, ICSAR, slave->addr);
@ -598,7 +598,7 @@ static int rcar_unreg_slave(struct i2c_client *slave)
priv->slave = NULL; priv->slave = NULL;
pm_runtime_allow(rcar_i2c_priv_to_dev(priv)); pm_runtime_put(rcar_i2c_priv_to_dev(priv));
return 0; return 0;
} }

View File

@ -908,7 +908,7 @@ static int rk3x_i2c_probe(struct platform_device *pdev)
&i2c->scl_fall_ns)) &i2c->scl_fall_ns))
i2c->scl_fall_ns = 300; i2c->scl_fall_ns = 300;
if (of_property_read_u32(pdev->dev.of_node, "i2c-sda-falling-time-ns", if (of_property_read_u32(pdev->dev.of_node, "i2c-sda-falling-time-ns",
&i2c->scl_fall_ns)) &i2c->sda_fall_ns))
i2c->sda_fall_ns = i2c->scl_fall_ns; i2c->sda_fall_ns = i2c->scl_fall_ns;
strlcpy(i2c->adap.name, "rk3x-i2c", sizeof(i2c->adap.name)); strlcpy(i2c->adap.name, "rk3x-i2c", sizeof(i2c->adap.name));

View File

@ -822,7 +822,7 @@ static int st_i2c_probe(struct platform_device *pdev)
adap = &i2c_dev->adap; adap = &i2c_dev->adap;
i2c_set_adapdata(adap, i2c_dev); i2c_set_adapdata(adap, i2c_dev);
snprintf(adap->name, sizeof(adap->name), "ST I2C(0x%pa)", &res->start); snprintf(adap->name, sizeof(adap->name), "ST I2C(%pa)", &res->start);
adap->owner = THIS_MODULE; adap->owner = THIS_MODULE;
adap->timeout = 2 * HZ; adap->timeout = 2 * HZ;
adap->retries = 0; adap->retries = 0;

View File

@ -592,6 +592,7 @@ static void db9_attach(struct parport *pp)
return; return;
} }
memset(&db9_parport_cb, 0, sizeof(db9_parport_cb));
db9_parport_cb.flags = PARPORT_FLAG_EXCL; db9_parport_cb.flags = PARPORT_FLAG_EXCL;
pd = parport_register_dev_model(pp, "db9", &db9_parport_cb, port_idx); pd = parport_register_dev_model(pp, "db9", &db9_parport_cb, port_idx);

View File

@ -951,6 +951,7 @@ static void gc_attach(struct parport *pp)
pads = gc_cfg[port_idx].args + 1; pads = gc_cfg[port_idx].args + 1;
n_pads = gc_cfg[port_idx].nargs - 1; n_pads = gc_cfg[port_idx].nargs - 1;
memset(&gc_parport_cb, 0, sizeof(gc_parport_cb));
gc_parport_cb.flags = PARPORT_FLAG_EXCL; gc_parport_cb.flags = PARPORT_FLAG_EXCL;
pd = parport_register_dev_model(pp, "gamecon", &gc_parport_cb, pd = parport_register_dev_model(pp, "gamecon", &gc_parport_cb,

View File

@ -181,6 +181,7 @@ static void tgfx_attach(struct parport *pp)
n_buttons = tgfx_cfg[port_idx].args + 1; n_buttons = tgfx_cfg[port_idx].args + 1;
n_devs = tgfx_cfg[port_idx].nargs - 1; n_devs = tgfx_cfg[port_idx].nargs - 1;
memset(&tgfx_parport_cb, 0, sizeof(tgfx_parport_cb));
tgfx_parport_cb.flags = PARPORT_FLAG_EXCL; tgfx_parport_cb.flags = PARPORT_FLAG_EXCL;
pd = parport_register_dev_model(pp, "turbografx", &tgfx_parport_cb, pd = parport_register_dev_model(pp, "turbografx", &tgfx_parport_cb,

View File

@ -218,6 +218,7 @@ static void walkera0701_attach(struct parport *pp)
w->parport = pp; w->parport = pp;
memset(&walkera0701_parport_cb, 0, sizeof(walkera0701_parport_cb));
walkera0701_parport_cb.flags = PARPORT_FLAG_EXCL; walkera0701_parport_cb.flags = PARPORT_FLAG_EXCL;
walkera0701_parport_cb.irq_func = walkera0701_irq_handler; walkera0701_parport_cb.irq_func = walkera0701_irq_handler;
walkera0701_parport_cb.private = w; walkera0701_parport_cb.private = w;

View File

@ -97,8 +97,7 @@ static void arizona_haptics_work(struct work_struct *work)
ret = regmap_update_bits(arizona->regmap, ret = regmap_update_bits(arizona->regmap,
ARIZONA_HAPTICS_CONTROL_1, ARIZONA_HAPTICS_CONTROL_1,
ARIZONA_HAP_CTRL_MASK, ARIZONA_HAP_CTRL_MASK, 0);
1 << ARIZONA_HAP_CTRL_SHIFT);
if (ret != 0) { if (ret != 0) {
dev_err(arizona->dev, "Failed to stop haptics: %d\n", dev_err(arizona->dev, "Failed to stop haptics: %d\n",
ret); ret);

View File

@ -41,6 +41,7 @@
#define DRIVER_NAME "elan_i2c" #define DRIVER_NAME "elan_i2c"
#define ELAN_DRIVER_VERSION "1.6.1" #define ELAN_DRIVER_VERSION "1.6.1"
#define ELAN_VENDOR_ID 0x04f3
#define ETP_MAX_PRESSURE 255 #define ETP_MAX_PRESSURE 255
#define ETP_FWIDTH_REDUCE 90 #define ETP_FWIDTH_REDUCE 90
#define ETP_FINGER_WIDTH 15 #define ETP_FINGER_WIDTH 15
@ -914,6 +915,8 @@ static int elan_setup_input_device(struct elan_tp_data *data)
input->name = "Elan Touchpad"; input->name = "Elan Touchpad";
input->id.bustype = BUS_I2C; input->id.bustype = BUS_I2C;
input->id.vendor = ELAN_VENDOR_ID;
input->id.product = data->product_id;
input_set_drvdata(input, data); input_set_drvdata(input, data);
error = input_mt_init_slots(input, ETP_MAX_FINGERS, error = input_mt_init_slots(input, ETP_MAX_FINGERS,

View File

@ -145,6 +145,7 @@ static int parkbd_getport(struct parport *pp)
{ {
struct pardev_cb parkbd_parport_cb; struct pardev_cb parkbd_parport_cb;
memset(&parkbd_parport_cb, 0, sizeof(parkbd_parport_cb));
parkbd_parport_cb.irq_func = parkbd_interrupt; parkbd_parport_cb.irq_func = parkbd_interrupt;
parkbd_parport_cb.flags = PARPORT_FLAG_EXCL; parkbd_parport_cb.flags = PARPORT_FLAG_EXCL;

View File

@ -1819,6 +1819,14 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
input_set_abs_params(inputdev, ABS_TILT_Y, AIPTEK_TILT_MIN, AIPTEK_TILT_MAX, 0, 0); input_set_abs_params(inputdev, ABS_TILT_Y, AIPTEK_TILT_MIN, AIPTEK_TILT_MAX, 0, 0);
input_set_abs_params(inputdev, ABS_WHEEL, AIPTEK_WHEEL_MIN, AIPTEK_WHEEL_MAX - 1, 0, 0); input_set_abs_params(inputdev, ABS_WHEEL, AIPTEK_WHEEL_MIN, AIPTEK_WHEEL_MAX - 1, 0, 0);
/* Verify that a device really has an endpoint */
if (intf->altsetting[0].desc.bNumEndpoints < 1) {
dev_err(&intf->dev,
"interface has %d endpoints, but must have minimum 1\n",
intf->altsetting[0].desc.bNumEndpoints);
err = -EINVAL;
goto fail3;
}
endpoint = &intf->altsetting[0].endpoint[0].desc; endpoint = &intf->altsetting[0].endpoint[0].desc;
/* Go set up our URB, which is called when the tablet receives /* Go set up our URB, which is called when the tablet receives
@ -1861,6 +1869,7 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
if (i == ARRAY_SIZE(speeds)) { if (i == ARRAY_SIZE(speeds)) {
dev_info(&intf->dev, dev_info(&intf->dev,
"Aiptek tried all speeds, no sane response\n"); "Aiptek tried all speeds, no sane response\n");
err = -EINVAL;
goto fail3; goto fail3;
} }

View File

@ -2487,6 +2487,31 @@ static struct mxt_acpi_platform_data samus_platform_data[] = {
{ } { }
}; };
static unsigned int chromebook_tp_buttons[] = {
KEY_RESERVED,
KEY_RESERVED,
KEY_RESERVED,
KEY_RESERVED,
KEY_RESERVED,
BTN_LEFT
};
static struct mxt_acpi_platform_data chromebook_platform_data[] = {
{
/* Touchpad */
.hid = "ATML0000",
.pdata = {
.t19_num_keys = ARRAY_SIZE(chromebook_tp_buttons),
.t19_keymap = chromebook_tp_buttons,
},
},
{
/* Touchscreen */
.hid = "ATML0001",
},
{ }
};
static const struct dmi_system_id mxt_dmi_table[] = { static const struct dmi_system_id mxt_dmi_table[] = {
{ {
/* 2015 Google Pixel */ /* 2015 Google Pixel */
@ -2497,6 +2522,14 @@ static const struct dmi_system_id mxt_dmi_table[] = {
}, },
.driver_data = samus_platform_data, .driver_data = samus_platform_data,
}, },
{
/* Other Google Chromebooks */
.ident = "Chromebook",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "GOOGLE"),
},
.driver_data = chromebook_platform_data,
},
{ } { }
}; };
@ -2701,6 +2734,7 @@ static const struct i2c_device_id mxt_id[] = {
{ "qt602240_ts", 0 }, { "qt602240_ts", 0 },
{ "atmel_mxt_ts", 0 }, { "atmel_mxt_ts", 0 },
{ "atmel_mxt_tp", 0 }, { "atmel_mxt_tp", 0 },
{ "maxtouch", 0 },
{ "mXT224", 0 }, { "mXT224", 0 },
{ } { }
}; };

View File

@ -1316,7 +1316,13 @@ static int __maybe_unused elants_i2c_suspend(struct device *dev)
disable_irq(client->irq); disable_irq(client->irq);
if (device_may_wakeup(dev) || ts->keep_power_in_suspend) { if (device_may_wakeup(dev)) {
/*
* The device will automatically enter idle mode
* that has reduced power consumption.
*/
ts->wake_irq_enabled = (enable_irq_wake(client->irq) == 0);
} else if (ts->keep_power_in_suspend) {
for (retry_cnt = 0; retry_cnt < MAX_RETRIES; retry_cnt++) { for (retry_cnt = 0; retry_cnt < MAX_RETRIES; retry_cnt++) {
error = elants_i2c_send(client, set_sleep_cmd, error = elants_i2c_send(client, set_sleep_cmd,
sizeof(set_sleep_cmd)); sizeof(set_sleep_cmd));
@ -1326,10 +1332,6 @@ static int __maybe_unused elants_i2c_suspend(struct device *dev)
dev_err(&client->dev, dev_err(&client->dev,
"suspend command failed: %d\n", error); "suspend command failed: %d\n", error);
} }
if (device_may_wakeup(dev))
ts->wake_irq_enabled =
(enable_irq_wake(client->irq) == 0);
} else { } else {
elants_i2c_power_off(ts); elants_i2c_power_off(ts);
} }
@ -1345,10 +1347,11 @@ static int __maybe_unused elants_i2c_resume(struct device *dev)
int retry_cnt; int retry_cnt;
int error; int error;
if (device_may_wakeup(dev) && ts->wake_irq_enabled) if (device_may_wakeup(dev)) {
disable_irq_wake(client->irq); if (ts->wake_irq_enabled)
disable_irq_wake(client->irq);
if (ts->keep_power_in_suspend) { elants_i2c_sw_reset(client);
} else if (ts->keep_power_in_suspend) {
for (retry_cnt = 0; retry_cnt < MAX_RETRIES; retry_cnt++) { for (retry_cnt = 0; retry_cnt < MAX_RETRIES; retry_cnt++) {
error = elants_i2c_send(client, set_active_cmd, error = elants_i2c_send(client, set_active_cmd,
sizeof(set_active_cmd)); sizeof(set_active_cmd));

View File

@ -494,6 +494,22 @@ static void handle_fault_error(struct fault *fault)
} }
} }
static bool access_error(struct vm_area_struct *vma, struct fault *fault)
{
unsigned long requested = 0;
if (fault->flags & PPR_FAULT_EXEC)
requested |= VM_EXEC;
if (fault->flags & PPR_FAULT_READ)
requested |= VM_READ;
if (fault->flags & PPR_FAULT_WRITE)
requested |= VM_WRITE;
return (requested & ~vma->vm_flags) != 0;
}
static void do_fault(struct work_struct *work) static void do_fault(struct work_struct *work)
{ {
struct fault *fault = container_of(work, struct fault, work); struct fault *fault = container_of(work, struct fault, work);
@ -516,8 +532,8 @@ static void do_fault(struct work_struct *work)
goto out; goto out;
} }
if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE))) { /* Check if we have the right permissions on the vma */
/* handle_mm_fault would BUG_ON() */ if (access_error(vma, fault)) {
up_read(&mm->mmap_sem); up_read(&mm->mmap_sem);
handle_fault_error(fault); handle_fault_error(fault);
goto out; goto out;

View File

@ -2159,7 +2159,7 @@ static int __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
sg_res = aligned_nrpages(sg->offset, sg->length); sg_res = aligned_nrpages(sg->offset, sg->length);
sg->dma_address = ((dma_addr_t)iov_pfn << VTD_PAGE_SHIFT) + sg->offset; sg->dma_address = ((dma_addr_t)iov_pfn << VTD_PAGE_SHIFT) + sg->offset;
sg->dma_length = sg->length; sg->dma_length = sg->length;
pteval = (sg_phys(sg) & PAGE_MASK) | prot; pteval = page_to_phys(sg_page(sg)) | prot;
phys_pfn = pteval >> VTD_PAGE_SHIFT; phys_pfn = pteval >> VTD_PAGE_SHIFT;
} }
@ -3704,7 +3704,7 @@ static int intel_nontranslate_map_sg(struct device *hddev,
for_each_sg(sglist, sg, nelems, i) { for_each_sg(sglist, sg, nelems, i) {
BUG_ON(!sg_page(sg)); BUG_ON(!sg_page(sg));
sg->dma_address = sg_phys(sg); sg->dma_address = page_to_phys(sg_page(sg)) + sg->offset;
sg->dma_length = sg->length; sg->dma_length = sg->length;
} }
return nelems; return nelems;

View File

@ -484,6 +484,23 @@ struct page_req_dsc {
}; };
#define PRQ_RING_MASK ((0x1000 << PRQ_ORDER) - 0x10) #define PRQ_RING_MASK ((0x1000 << PRQ_ORDER) - 0x10)
static bool access_error(struct vm_area_struct *vma, struct page_req_dsc *req)
{
unsigned long requested = 0;
if (req->exe_req)
requested |= VM_EXEC;
if (req->rd_req)
requested |= VM_READ;
if (req->wr_req)
requested |= VM_WRITE;
return (requested & ~vma->vm_flags) != 0;
}
static irqreturn_t prq_event_thread(int irq, void *d) static irqreturn_t prq_event_thread(int irq, void *d)
{ {
struct intel_iommu *iommu = d; struct intel_iommu *iommu = d;
@ -539,6 +556,9 @@ static irqreturn_t prq_event_thread(int irq, void *d)
if (!vma || address < vma->vm_start) if (!vma || address < vma->vm_start)
goto invalid; goto invalid;
if (access_error(vma, req))
goto invalid;
ret = handle_mm_fault(svm->mm, vma, address, ret = handle_mm_fault(svm->mm, vma, address,
req->wr_req ? FAULT_FLAG_WRITE : 0); req->wr_req ? FAULT_FLAG_WRITE : 0);
if (ret & VM_FAULT_ERROR) if (ret & VM_FAULT_ERROR)

View File

@ -1430,7 +1430,7 @@ size_t default_iommu_map_sg(struct iommu_domain *domain, unsigned long iova,
min_pagesz = 1 << __ffs(domain->ops->pgsize_bitmap); min_pagesz = 1 << __ffs(domain->ops->pgsize_bitmap);
for_each_sg(sg, s, nents, i) { for_each_sg(sg, s, nents, i) {
phys_addr_t phys = sg_phys(s); phys_addr_t phys = page_to_phys(sg_page(s)) + s->offset;
/* /*
* We are mapping on IOMMU page boundaries, so offset within * We are mapping on IOMMU page boundaries, so offset within

View File

@ -67,8 +67,7 @@ static int write_modem(struct cardstate *cs)
struct sk_buff *skb = bcs->tx_skb; struct sk_buff *skb = bcs->tx_skb;
int sent = -EOPNOTSUPP; int sent = -EOPNOTSUPP;
if (!tty || !tty->driver || !skb) WARN_ON(!tty || !tty->ops || !skb);
return -EINVAL;
if (!skb->len) { if (!skb->len) {
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
@ -109,8 +108,7 @@ static int send_cb(struct cardstate *cs)
unsigned long flags; unsigned long flags;
int sent = 0; int sent = 0;
if (!tty || !tty->driver) WARN_ON(!tty || !tty->ops);
return -EFAULT;
cb = cs->cmdbuf; cb = cs->cmdbuf;
if (!cb) if (!cb)
@ -370,19 +368,18 @@ static void gigaset_freecshw(struct cardstate *cs)
tasklet_kill(&cs->write_tasklet); tasklet_kill(&cs->write_tasklet);
if (!cs->hw.ser) if (!cs->hw.ser)
return; return;
dev_set_drvdata(&cs->hw.ser->dev.dev, NULL);
platform_device_unregister(&cs->hw.ser->dev); platform_device_unregister(&cs->hw.ser->dev);
kfree(cs->hw.ser);
cs->hw.ser = NULL;
} }
static void gigaset_device_release(struct device *dev) static void gigaset_device_release(struct device *dev)
{ {
struct platform_device *pdev = to_platform_device(dev); struct cardstate *cs = dev_get_drvdata(dev);
/* adapted from platform_device_release() in drivers/base/platform.c */ if (!cs)
kfree(dev->platform_data); return;
kfree(pdev->resource); dev_set_drvdata(dev, NULL);
kfree(cs->hw.ser);
cs->hw.ser = NULL;
} }
/* /*
@ -432,7 +429,9 @@ static int gigaset_set_modem_ctrl(struct cardstate *cs, unsigned old_state,
struct tty_struct *tty = cs->hw.ser->tty; struct tty_struct *tty = cs->hw.ser->tty;
unsigned int set, clear; unsigned int set, clear;
if (!tty || !tty->driver || !tty->ops->tiocmset) WARN_ON(!tty || !tty->ops);
/* tiocmset is an optional tty driver method */
if (!tty->ops->tiocmset)
return -EINVAL; return -EINVAL;
set = new_state & ~old_state; set = new_state & ~old_state;
clear = old_state & ~new_state; clear = old_state & ~new_state;

View File

@ -1170,7 +1170,7 @@ mISDNipac_irq(struct ipac_hw *ipac, int maxloop)
if (ipac->type & IPAC_TYPE_IPACX) { if (ipac->type & IPAC_TYPE_IPACX) {
ista = ReadIPAC(ipac, ISACX_ISTA); ista = ReadIPAC(ipac, ISACX_ISTA);
while (ista && cnt--) { while (ista && --cnt) {
pr_debug("%s: ISTA %02x\n", ipac->name, ista); pr_debug("%s: ISTA %02x\n", ipac->name, ista);
if (ista & IPACX__ICA) if (ista & IPACX__ICA)
ipac_irq(&ipac->hscx[0], ista); ipac_irq(&ipac->hscx[0], ista);
@ -1182,7 +1182,7 @@ mISDNipac_irq(struct ipac_hw *ipac, int maxloop)
} }
} else if (ipac->type & IPAC_TYPE_IPAC) { } else if (ipac->type & IPAC_TYPE_IPAC) {
ista = ReadIPAC(ipac, IPAC_ISTA); ista = ReadIPAC(ipac, IPAC_ISTA);
while (ista && cnt--) { while (ista && --cnt) {
pr_debug("%s: ISTA %02x\n", ipac->name, ista); pr_debug("%s: ISTA %02x\n", ipac->name, ista);
if (ista & (IPAC__ICD | IPAC__EXD)) { if (ista & (IPAC__ICD | IPAC__EXD)) {
istad = ReadISAC(isac, ISAC_ISTA); istad = ReadISAC(isac, ISAC_ISTA);
@ -1200,7 +1200,7 @@ mISDNipac_irq(struct ipac_hw *ipac, int maxloop)
ista = ReadIPAC(ipac, IPAC_ISTA); ista = ReadIPAC(ipac, IPAC_ISTA);
} }
} else if (ipac->type & IPAC_TYPE_HSCX) { } else if (ipac->type & IPAC_TYPE_HSCX) {
while (cnt) { while (--cnt) {
ista = ReadIPAC(ipac, IPAC_ISTAB + ipac->hscx[1].off); ista = ReadIPAC(ipac, IPAC_ISTAB + ipac->hscx[1].off);
pr_debug("%s: B2 ISTA %02x\n", ipac->name, ista); pr_debug("%s: B2 ISTA %02x\n", ipac->name, ista);
if (ista) if (ista)
@ -1211,7 +1211,6 @@ mISDNipac_irq(struct ipac_hw *ipac, int maxloop)
mISDNisac_irq(isac, istad); mISDNisac_irq(isac, istad);
if (0 == (ista | istad)) if (0 == (ista | istad))
break; break;
cnt--;
} }
} }
if (cnt > maxloop) /* only for ISAC/HSCX without PCI IRQ test */ if (cnt > maxloop) /* only for ISAC/HSCX without PCI IRQ test */

View File

@ -314,8 +314,8 @@ static blk_qc_t md_make_request(struct request_queue *q, struct bio *bio)
*/ */
void mddev_suspend(struct mddev *mddev) void mddev_suspend(struct mddev *mddev)
{ {
BUG_ON(mddev->suspended); if (mddev->suspended++)
mddev->suspended = 1; return;
synchronize_rcu(); synchronize_rcu();
wait_event(mddev->sb_wait, atomic_read(&mddev->active_io) == 0); wait_event(mddev->sb_wait, atomic_read(&mddev->active_io) == 0);
mddev->pers->quiesce(mddev, 1); mddev->pers->quiesce(mddev, 1);
@ -326,7 +326,8 @@ EXPORT_SYMBOL_GPL(mddev_suspend);
void mddev_resume(struct mddev *mddev) void mddev_resume(struct mddev *mddev)
{ {
mddev->suspended = 0; if (--mddev->suspended)
return;
wake_up(&mddev->sb_wait); wake_up(&mddev->sb_wait);
mddev->pers->quiesce(mddev, 0); mddev->pers->quiesce(mddev, 0);
@ -1652,7 +1653,7 @@ static int super_1_validate(struct mddev *mddev, struct md_rdev *rdev)
rdev->journal_tail = le64_to_cpu(sb->journal_tail); rdev->journal_tail = le64_to_cpu(sb->journal_tail);
if (mddev->recovery_cp == MaxSector) if (mddev->recovery_cp == MaxSector)
set_bit(MD_JOURNAL_CLEAN, &mddev->flags); set_bit(MD_JOURNAL_CLEAN, &mddev->flags);
rdev->raid_disk = mddev->raid_disks; rdev->raid_disk = 0;
break; break;
default: default:
rdev->saved_raid_disk = role; rdev->saved_raid_disk = role;
@ -2773,6 +2774,7 @@ slot_store(struct md_rdev *rdev, const char *buf, size_t len)
/* Activating a spare .. or possibly reactivating /* Activating a spare .. or possibly reactivating
* if we ever get bitmaps working here. * if we ever get bitmaps working here.
*/ */
int err;
if (rdev->raid_disk != -1) if (rdev->raid_disk != -1)
return -EBUSY; return -EBUSY;
@ -2794,9 +2796,15 @@ slot_store(struct md_rdev *rdev, const char *buf, size_t len)
rdev->saved_raid_disk = -1; rdev->saved_raid_disk = -1;
clear_bit(In_sync, &rdev->flags); clear_bit(In_sync, &rdev->flags);
clear_bit(Bitmap_sync, &rdev->flags); clear_bit(Bitmap_sync, &rdev->flags);
remove_and_add_spares(rdev->mddev, rdev); err = rdev->mddev->pers->
if (rdev->raid_disk == -1) hot_add_disk(rdev->mddev, rdev);
return -EBUSY; if (err) {
rdev->raid_disk = -1;
return err;
} else
sysfs_notify_dirent_safe(rdev->sysfs_state);
if (sysfs_link_rdev(rdev->mddev, rdev))
/* failure here is OK */;
/* don't wakeup anyone, leave that to userspace. */ /* don't wakeup anyone, leave that to userspace. */
} else { } else {
if (slot >= rdev->mddev->raid_disks && if (slot >= rdev->mddev->raid_disks &&

View File

@ -566,7 +566,9 @@ static inline char * mdname (struct mddev * mddev)
static inline int sysfs_link_rdev(struct mddev *mddev, struct md_rdev *rdev) static inline int sysfs_link_rdev(struct mddev *mddev, struct md_rdev *rdev)
{ {
char nm[20]; char nm[20];
if (!test_bit(Replacement, &rdev->flags) && mddev->kobj.sd) { if (!test_bit(Replacement, &rdev->flags) &&
!test_bit(Journal, &rdev->flags) &&
mddev->kobj.sd) {
sprintf(nm, "rd%d", rdev->raid_disk); sprintf(nm, "rd%d", rdev->raid_disk);
return sysfs_create_link(&mddev->kobj, &rdev->kobj, nm); return sysfs_create_link(&mddev->kobj, &rdev->kobj, nm);
} else } else
@ -576,7 +578,9 @@ static inline int sysfs_link_rdev(struct mddev *mddev, struct md_rdev *rdev)
static inline void sysfs_unlink_rdev(struct mddev *mddev, struct md_rdev *rdev) static inline void sysfs_unlink_rdev(struct mddev *mddev, struct md_rdev *rdev)
{ {
char nm[20]; char nm[20];
if (!test_bit(Replacement, &rdev->flags) && mddev->kobj.sd) { if (!test_bit(Replacement, &rdev->flags) &&
!test_bit(Journal, &rdev->flags) &&
mddev->kobj.sd) {
sprintf(nm, "rd%d", rdev->raid_disk); sprintf(nm, "rd%d", rdev->raid_disk);
sysfs_remove_link(&mddev->kobj, nm); sysfs_remove_link(&mddev->kobj, nm);
} }

View File

@ -1946,6 +1946,8 @@ static void sync_request_write(struct mddev *mddev, struct r10bio *r10_bio)
first = i; first = i;
fbio = r10_bio->devs[i].bio; fbio = r10_bio->devs[i].bio;
fbio->bi_iter.bi_size = r10_bio->sectors << 9;
fbio->bi_iter.bi_idx = 0;
vcnt = (r10_bio->sectors + (PAGE_SIZE >> 9) - 1) >> (PAGE_SHIFT - 9); vcnt = (r10_bio->sectors + (PAGE_SIZE >> 9) - 1) >> (PAGE_SHIFT - 9);
/* now find blocks with errors */ /* now find blocks with errors */
@ -1989,7 +1991,7 @@ static void sync_request_write(struct mddev *mddev, struct r10bio *r10_bio)
bio_reset(tbio); bio_reset(tbio);
tbio->bi_vcnt = vcnt; tbio->bi_vcnt = vcnt;
tbio->bi_iter.bi_size = r10_bio->sectors << 9; tbio->bi_iter.bi_size = fbio->bi_iter.bi_size;
tbio->bi_rw = WRITE; tbio->bi_rw = WRITE;
tbio->bi_private = r10_bio; tbio->bi_private = r10_bio;
tbio->bi_iter.bi_sector = r10_bio->devs[i].addr; tbio->bi_iter.bi_sector = r10_bio->devs[i].addr;

View File

@ -805,11 +805,11 @@ static void ivtv_init_struct2(struct ivtv *itv)
{ {
int i; int i;
for (i = 0; i < IVTV_CARD_MAX_VIDEO_INPUTS - 1; i++) for (i = 0; i < IVTV_CARD_MAX_VIDEO_INPUTS; i++)
if (itv->card->video_inputs[i].video_type == 0) if (itv->card->video_inputs[i].video_type == 0)
break; break;
itv->nof_inputs = i; itv->nof_inputs = i;
for (i = 0; i < IVTV_CARD_MAX_AUDIO_INPUTS - 1; i++) for (i = 0; i < IVTV_CARD_MAX_AUDIO_INPUTS; i++)
if (itv->card->audio_inputs[i].audio_type == 0) if (itv->card->audio_inputs[i].audio_type == 0)
break; break;
itv->nof_audio_inputs = i; itv->nof_audio_inputs = i;

View File

@ -134,7 +134,7 @@ struct airspy {
int urbs_submitted; int urbs_submitted;
/* USB control message buffer */ /* USB control message buffer */
#define BUF_SIZE 24 #define BUF_SIZE 128
u8 buf[BUF_SIZE]; u8 buf[BUF_SIZE];
/* Current configuration */ /* Current configuration */

View File

@ -24,6 +24,15 @@
#include <media/videobuf2-v4l2.h> #include <media/videobuf2-v4l2.h>
#include <media/videobuf2-vmalloc.h> #include <media/videobuf2-vmalloc.h>
/*
* Used Avago MGA-81563 RF amplifier could be destroyed pretty easily with too
* strong signal or transmitting to bad antenna.
* Set RF gain control to 'grabbed' state by default for sure.
*/
static bool hackrf_enable_rf_gain_ctrl;
module_param_named(enable_rf_gain_ctrl, hackrf_enable_rf_gain_ctrl, bool, 0644);
MODULE_PARM_DESC(enable_rf_gain_ctrl, "enable RX/TX RF amplifier control (warn: could damage amplifier)");
/* HackRF USB API commands (from HackRF Library) */ /* HackRF USB API commands (from HackRF Library) */
enum { enum {
CMD_SET_TRANSCEIVER_MODE = 0x01, CMD_SET_TRANSCEIVER_MODE = 0x01,
@ -1451,6 +1460,7 @@ static int hackrf_probe(struct usb_interface *intf,
dev_err(dev->dev, "Could not initialize controls\n"); dev_err(dev->dev, "Could not initialize controls\n");
goto err_v4l2_ctrl_handler_free_rx; goto err_v4l2_ctrl_handler_free_rx;
} }
v4l2_ctrl_grab(dev->rx_rf_gain, !hackrf_enable_rf_gain_ctrl);
v4l2_ctrl_handler_setup(&dev->rx_ctrl_handler); v4l2_ctrl_handler_setup(&dev->rx_ctrl_handler);
/* Register controls for transmitter */ /* Register controls for transmitter */
@ -1471,6 +1481,7 @@ static int hackrf_probe(struct usb_interface *intf,
dev_err(dev->dev, "Could not initialize controls\n"); dev_err(dev->dev, "Could not initialize controls\n");
goto err_v4l2_ctrl_handler_free_tx; goto err_v4l2_ctrl_handler_free_tx;
} }
v4l2_ctrl_grab(dev->tx_rf_gain, !hackrf_enable_rf_gain_ctrl);
v4l2_ctrl_handler_setup(&dev->tx_ctrl_handler); v4l2_ctrl_handler_setup(&dev->tx_ctrl_handler);
/* Register the v4l2_device structure */ /* Register the v4l2_device structure */
@ -1530,7 +1541,7 @@ err_v4l2_ctrl_handler_free_rx:
err_kfree: err_kfree:
kfree(dev); kfree(dev);
err: err:
dev_dbg(dev->dev, "failed=%d\n", ret); dev_dbg(&intf->dev, "failed=%d\n", ret);
return ret; return ret;
} }

View File

@ -46,10 +46,18 @@ static int parse_ofpart_partitions(struct mtd_info *master,
ofpart_node = of_get_child_by_name(mtd_node, "partitions"); ofpart_node = of_get_child_by_name(mtd_node, "partitions");
if (!ofpart_node) { if (!ofpart_node) {
pr_warn("%s: 'partitions' subnode not found on %s. Trying to parse direct subnodes as partitions.\n", /*
master->name, mtd_node->full_name); * We might get here even when ofpart isn't used at all (e.g.,
* when using another parser), so don't be louder than
* KERN_DEBUG
*/
pr_debug("%s: 'partitions' subnode not found on %s. Trying to parse direct subnodes as partitions.\n",
master->name, mtd_node->full_name);
ofpart_node = mtd_node; ofpart_node = mtd_node;
dedicated = false; dedicated = false;
} else if (!of_device_is_compatible(ofpart_node, "fixed-partitions")) {
/* The 'partitions' subnode might be used by another parser */
return 0;
} }
/* First count the subnodes */ /* First count the subnodes */

View File

@ -1849,7 +1849,7 @@ static int xgbe_exit(struct xgbe_prv_data *pdata)
usleep_range(10, 15); usleep_range(10, 15);
/* Poll Until Poll Condition */ /* Poll Until Poll Condition */
while (count-- && XGMAC_IOREAD_BITS(pdata, DMA_MR, SWR)) while (--count && XGMAC_IOREAD_BITS(pdata, DMA_MR, SWR))
usleep_range(500, 600); usleep_range(500, 600);
if (!count) if (!count)
@ -1873,7 +1873,7 @@ static int xgbe_flush_tx_queues(struct xgbe_prv_data *pdata)
/* Poll Until Poll Condition */ /* Poll Until Poll Condition */
for (i = 0; i < pdata->tx_q_count; i++) { for (i = 0; i < pdata->tx_q_count; i++) {
count = 2000; count = 2000;
while (count-- && XGMAC_MTL_IOREAD_BITS(pdata, i, while (--count && XGMAC_MTL_IOREAD_BITS(pdata, i,
MTL_Q_TQOMR, FTQ)) MTL_Q_TQOMR, FTQ))
usleep_range(500, 600); usleep_range(500, 600);

View File

@ -289,6 +289,7 @@ static int xgene_enet_setup_tx_desc(struct xgene_enet_desc_ring *tx_ring,
struct sk_buff *skb) struct sk_buff *skb)
{ {
struct device *dev = ndev_to_dev(tx_ring->ndev); struct device *dev = ndev_to_dev(tx_ring->ndev);
struct xgene_enet_pdata *pdata = netdev_priv(tx_ring->ndev);
struct xgene_enet_raw_desc *raw_desc; struct xgene_enet_raw_desc *raw_desc;
__le64 *exp_desc = NULL, *exp_bufs = NULL; __le64 *exp_desc = NULL, *exp_bufs = NULL;
dma_addr_t dma_addr, pbuf_addr, *frag_dma_addr; dma_addr_t dma_addr, pbuf_addr, *frag_dma_addr;
@ -419,6 +420,7 @@ out:
raw_desc->m0 = cpu_to_le64(SET_VAL(LL, ll) | SET_VAL(NV, nv) | raw_desc->m0 = cpu_to_le64(SET_VAL(LL, ll) | SET_VAL(NV, nv) |
SET_VAL(USERINFO, tx_ring->tail)); SET_VAL(USERINFO, tx_ring->tail));
tx_ring->cp_ring->cp_skb[tx_ring->tail] = skb; tx_ring->cp_ring->cp_skb[tx_ring->tail] = skb;
pdata->tx_level += count;
tx_ring->tail = tail; tx_ring->tail = tail;
return count; return count;
@ -429,14 +431,13 @@ static netdev_tx_t xgene_enet_start_xmit(struct sk_buff *skb,
{ {
struct xgene_enet_pdata *pdata = netdev_priv(ndev); struct xgene_enet_pdata *pdata = netdev_priv(ndev);
struct xgene_enet_desc_ring *tx_ring = pdata->tx_ring; struct xgene_enet_desc_ring *tx_ring = pdata->tx_ring;
struct xgene_enet_desc_ring *cp_ring = tx_ring->cp_ring; u32 tx_level = pdata->tx_level;
u32 tx_level, cq_level;
int count; int count;
tx_level = pdata->ring_ops->len(tx_ring); if (tx_level < pdata->txc_level)
cq_level = pdata->ring_ops->len(cp_ring); tx_level += ((typeof(pdata->tx_level))~0U);
if (unlikely(tx_level > pdata->tx_qcnt_hi ||
cq_level > pdata->cp_qcnt_hi)) { if ((tx_level - pdata->txc_level) > pdata->tx_qcnt_hi) {
netif_stop_queue(ndev); netif_stop_queue(ndev);
return NETDEV_TX_BUSY; return NETDEV_TX_BUSY;
} }
@ -539,10 +540,13 @@ static int xgene_enet_process_ring(struct xgene_enet_desc_ring *ring,
struct xgene_enet_raw_desc *raw_desc, *exp_desc; struct xgene_enet_raw_desc *raw_desc, *exp_desc;
u16 head = ring->head; u16 head = ring->head;
u16 slots = ring->slots - 1; u16 slots = ring->slots - 1;
int ret, count = 0, processed = 0; int ret, desc_count, count = 0, processed = 0;
bool is_completion;
do { do {
raw_desc = &ring->raw_desc[head]; raw_desc = &ring->raw_desc[head];
desc_count = 0;
is_completion = false;
exp_desc = NULL; exp_desc = NULL;
if (unlikely(xgene_enet_is_desc_slot_empty(raw_desc))) if (unlikely(xgene_enet_is_desc_slot_empty(raw_desc)))
break; break;
@ -559,18 +563,24 @@ static int xgene_enet_process_ring(struct xgene_enet_desc_ring *ring,
} }
dma_rmb(); dma_rmb();
count++; count++;
desc_count++;
} }
if (is_rx_desc(raw_desc)) if (is_rx_desc(raw_desc)) {
ret = xgene_enet_rx_frame(ring, raw_desc); ret = xgene_enet_rx_frame(ring, raw_desc);
else } else {
ret = xgene_enet_tx_completion(ring, raw_desc); ret = xgene_enet_tx_completion(ring, raw_desc);
is_completion = true;
}
xgene_enet_mark_desc_slot_empty(raw_desc); xgene_enet_mark_desc_slot_empty(raw_desc);
if (exp_desc) if (exp_desc)
xgene_enet_mark_desc_slot_empty(exp_desc); xgene_enet_mark_desc_slot_empty(exp_desc);
head = (head + 1) & slots; head = (head + 1) & slots;
count++; count++;
desc_count++;
processed++; processed++;
if (is_completion)
pdata->txc_level += desc_count;
if (ret) if (ret)
break; break;
@ -580,10 +590,8 @@ static int xgene_enet_process_ring(struct xgene_enet_desc_ring *ring,
pdata->ring_ops->wr_cmd(ring, -count); pdata->ring_ops->wr_cmd(ring, -count);
ring->head = head; ring->head = head;
if (netif_queue_stopped(ring->ndev)) { if (netif_queue_stopped(ring->ndev))
if (pdata->ring_ops->len(ring) < pdata->cp_qcnt_low) netif_start_queue(ring->ndev);
netif_wake_queue(ring->ndev);
}
} }
return processed; return processed;
@ -1033,9 +1041,7 @@ static int xgene_enet_create_desc_rings(struct net_device *ndev)
pdata->tx_ring->cp_ring = cp_ring; pdata->tx_ring->cp_ring = cp_ring;
pdata->tx_ring->dst_ring_num = xgene_enet_dst_ring_num(cp_ring); pdata->tx_ring->dst_ring_num = xgene_enet_dst_ring_num(cp_ring);
pdata->tx_qcnt_hi = pdata->tx_ring->slots / 2; pdata->tx_qcnt_hi = pdata->tx_ring->slots - 128;
pdata->cp_qcnt_hi = pdata->rx_ring->slots / 2;
pdata->cp_qcnt_low = pdata->cp_qcnt_hi / 2;
return 0; return 0;

View File

@ -155,11 +155,11 @@ struct xgene_enet_pdata {
enum xgene_enet_id enet_id; enum xgene_enet_id enet_id;
struct xgene_enet_desc_ring *tx_ring; struct xgene_enet_desc_ring *tx_ring;
struct xgene_enet_desc_ring *rx_ring; struct xgene_enet_desc_ring *rx_ring;
u16 tx_level;
u16 txc_level;
char *dev_name; char *dev_name;
u32 rx_buff_cnt; u32 rx_buff_cnt;
u32 tx_qcnt_hi; u32 tx_qcnt_hi;
u32 cp_qcnt_hi;
u32 cp_qcnt_low;
u32 rx_irq; u32 rx_irq;
u32 txc_irq; u32 txc_irq;
u8 cq_cnt; u8 cq_cnt;

View File

@ -1016,13 +1016,12 @@ static int atl1c_setup_ring_resources(struct atl1c_adapter *adapter)
sizeof(struct atl1c_recv_ret_status) * rx_desc_count + sizeof(struct atl1c_recv_ret_status) * rx_desc_count +
8 * 4; 8 * 4;
ring_header->desc = pci_alloc_consistent(pdev, ring_header->size, ring_header->desc = dma_zalloc_coherent(&pdev->dev, ring_header->size,
&ring_header->dma); &ring_header->dma, GFP_KERNEL);
if (unlikely(!ring_header->desc)) { if (unlikely(!ring_header->desc)) {
dev_err(&pdev->dev, "pci_alloc_consistend failed\n"); dev_err(&pdev->dev, "could not get memory for DMA buffer\n");
goto err_nomem; goto err_nomem;
} }
memset(ring_header->desc, 0, ring_header->size);
/* init TPD ring */ /* init TPD ring */
tpd_ring[0].dma = roundup(ring_header->dma, 8); tpd_ring[0].dma = roundup(ring_header->dma, 8);

View File

@ -13,6 +13,7 @@ if NET_VENDOR_AURORA
config AURORA_NB8800 config AURORA_NB8800
tristate "Aurora AU-NB8800 support" tristate "Aurora AU-NB8800 support"
depends on HAS_DMA
select PHYLIB select PHYLIB
help help
Support for the AU-NB8800 gigabit Ethernet controller. Support for the AU-NB8800 gigabit Ethernet controller.

View File

@ -2693,17 +2693,16 @@ static int bnxt_hwrm_func_drv_rgtr(struct bnxt *bp)
req.ver_upd = DRV_VER_UPD; req.ver_upd = DRV_VER_UPD;
if (BNXT_PF(bp)) { if (BNXT_PF(bp)) {
unsigned long vf_req_snif_bmap[4]; DECLARE_BITMAP(vf_req_snif_bmap, 256);
u32 *data = (u32 *)vf_req_snif_bmap; u32 *data = (u32 *)vf_req_snif_bmap;
memset(vf_req_snif_bmap, 0, 32); memset(vf_req_snif_bmap, 0, sizeof(vf_req_snif_bmap));
for (i = 0; i < ARRAY_SIZE(bnxt_vf_req_snif); i++) for (i = 0; i < ARRAY_SIZE(bnxt_vf_req_snif); i++)
__set_bit(bnxt_vf_req_snif[i], vf_req_snif_bmap); __set_bit(bnxt_vf_req_snif[i], vf_req_snif_bmap);
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++)
req.vf_req_fwd[i] = cpu_to_le32(*data); req.vf_req_fwd[i] = cpu_to_le32(data[i]);
data++;
}
req.enables |= req.enables |=
cpu_to_le32(FUNC_DRV_RGTR_REQ_ENABLES_VF_REQ_FWD); cpu_to_le32(FUNC_DRV_RGTR_REQ_ENABLES_VF_REQ_FWD);
} }
@ -4603,7 +4602,7 @@ static int __bnxt_open_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init)
bp->nge_port_cnt = 1; bp->nge_port_cnt = 1;
} }
bp->state = BNXT_STATE_OPEN; set_bit(BNXT_STATE_OPEN, &bp->state);
bnxt_enable_int(bp); bnxt_enable_int(bp);
/* Enable TX queues */ /* Enable TX queues */
bnxt_tx_enable(bp); bnxt_tx_enable(bp);
@ -4679,8 +4678,10 @@ int bnxt_close_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init)
/* Change device state to avoid TX queue wake up's */ /* Change device state to avoid TX queue wake up's */
bnxt_tx_disable(bp); bnxt_tx_disable(bp);
bp->state = BNXT_STATE_CLOSED; clear_bit(BNXT_STATE_OPEN, &bp->state);
cancel_work_sync(&bp->sp_task); smp_mb__after_atomic();
while (test_bit(BNXT_STATE_IN_SP_TASK, &bp->state))
msleep(20);
/* Flush rings before disabling interrupts */ /* Flush rings before disabling interrupts */
bnxt_shutdown_nic(bp, irq_re_init); bnxt_shutdown_nic(bp, irq_re_init);
@ -5030,8 +5031,10 @@ static void bnxt_dbg_dump_states(struct bnxt *bp)
static void bnxt_reset_task(struct bnxt *bp) static void bnxt_reset_task(struct bnxt *bp)
{ {
bnxt_dbg_dump_states(bp); bnxt_dbg_dump_states(bp);
if (netif_running(bp->dev)) if (netif_running(bp->dev)) {
bnxt_tx_disable(bp); /* prevent tx timout again */ bnxt_close_nic(bp, false, false);
bnxt_open_nic(bp, false, false);
}
} }
static void bnxt_tx_timeout(struct net_device *dev) static void bnxt_tx_timeout(struct net_device *dev)
@ -5081,8 +5084,12 @@ static void bnxt_sp_task(struct work_struct *work)
struct bnxt *bp = container_of(work, struct bnxt, sp_task); struct bnxt *bp = container_of(work, struct bnxt, sp_task);
int rc; int rc;
if (bp->state != BNXT_STATE_OPEN) set_bit(BNXT_STATE_IN_SP_TASK, &bp->state);
smp_mb__after_atomic();
if (!test_bit(BNXT_STATE_OPEN, &bp->state)) {
clear_bit(BNXT_STATE_IN_SP_TASK, &bp->state);
return; return;
}
if (test_and_clear_bit(BNXT_RX_MASK_SP_EVENT, &bp->sp_event)) if (test_and_clear_bit(BNXT_RX_MASK_SP_EVENT, &bp->sp_event))
bnxt_cfg_rx_mode(bp); bnxt_cfg_rx_mode(bp);
@ -5106,8 +5113,19 @@ static void bnxt_sp_task(struct work_struct *work)
bnxt_hwrm_tunnel_dst_port_free( bnxt_hwrm_tunnel_dst_port_free(
bp, TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_VXLAN); bp, TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_VXLAN);
} }
if (test_and_clear_bit(BNXT_RESET_TASK_SP_EVENT, &bp->sp_event)) if (test_and_clear_bit(BNXT_RESET_TASK_SP_EVENT, &bp->sp_event)) {
/* bnxt_reset_task() calls bnxt_close_nic() which waits
* for BNXT_STATE_IN_SP_TASK to clear.
*/
clear_bit(BNXT_STATE_IN_SP_TASK, &bp->state);
rtnl_lock();
bnxt_reset_task(bp); bnxt_reset_task(bp);
set_bit(BNXT_STATE_IN_SP_TASK, &bp->state);
rtnl_unlock();
}
smp_mb__before_atomic();
clear_bit(BNXT_STATE_IN_SP_TASK, &bp->state);
} }
static int bnxt_init_board(struct pci_dev *pdev, struct net_device *dev) static int bnxt_init_board(struct pci_dev *pdev, struct net_device *dev)
@ -5186,7 +5204,7 @@ static int bnxt_init_board(struct pci_dev *pdev, struct net_device *dev)
bp->timer.function = bnxt_timer; bp->timer.function = bnxt_timer;
bp->current_interval = BNXT_TIMER_INTERVAL; bp->current_interval = BNXT_TIMER_INTERVAL;
bp->state = BNXT_STATE_CLOSED; clear_bit(BNXT_STATE_OPEN, &bp->state);
return 0; return 0;

View File

@ -925,9 +925,9 @@ struct bnxt {
struct timer_list timer; struct timer_list timer;
int state; unsigned long state;
#define BNXT_STATE_CLOSED 0 #define BNXT_STATE_OPEN 0
#define BNXT_STATE_OPEN 1 #define BNXT_STATE_IN_SP_TASK 1
struct bnxt_irq *irq_tbl; struct bnxt_irq *irq_tbl;
u8 mac_addr[ETH_ALEN]; u8 mac_addr[ETH_ALEN];

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