diff options
37 files changed, 355 insertions, 161 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 2651b1da1c56..136f263ed47b 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1087,6 +1087,20 @@ if !MMU source "arch/arm/Kconfig-nommu" endif +config PJ4B_ERRATA_4742 + bool "PJ4B Errata 4742: IDLE Wake Up Commands can Cause the CPU Core to Cease Operation" + depends on CPU_PJ4B && MACH_ARMADA_370 + default y + help + When coming out of either a Wait for Interrupt (WFI) or a Wait for + Event (WFE) IDLE states, a specific timing sensitivity exists between + the retiring WFI/WFE instructions and the newly issued subsequent + instructions. This sensitivity can result in a CPU hang scenario. + Workaround: + The software must insert either a Data Synchronization Barrier (DSB) + or Data Memory Barrier (DMB) command immediately after the WFI/WFE + instruction + config ARM_ERRATA_326103 bool "ARM errata: FSR write bit incorrect on a SWP to read-only memory" depends on CPU_V6 diff --git a/arch/arm/include/asm/cputype.h b/arch/arm/include/asm/cputype.h index 7652712d1d14..dba62cb1ad08 100644 --- a/arch/arm/include/asm/cputype.h +++ b/arch/arm/include/asm/cputype.h @@ -32,6 +32,8 @@ #define MPIDR_HWID_BITMASK 0xFFFFFF +#define MPIDR_INVALID (~MPIDR_HWID_BITMASK) + #define MPIDR_LEVEL_BITS 8 #define MPIDR_LEVEL_MASK ((1 << MPIDR_LEVEL_BITS) - 1) diff --git a/arch/arm/include/asm/glue-proc.h b/arch/arm/include/asm/glue-proc.h index ac1dd54724b6..8017e94acc5e 100644 --- a/arch/arm/include/asm/glue-proc.h +++ b/arch/arm/include/asm/glue-proc.h @@ -230,6 +230,15 @@ # endif #endif +#ifdef CONFIG_CPU_PJ4B +# ifdef CPU_NAME +# undef MULTI_CPU +# define MULTI_CPU +# else +# define CPU_NAME cpu_pj4b +# endif +#endif + #ifndef MULTI_CPU #define cpu_proc_init __glue(CPU_NAME,_proc_init) #define cpu_proc_fin __glue(CPU_NAME,_proc_fin) diff --git a/arch/arm/include/asm/smp_plat.h b/arch/arm/include/asm/smp_plat.h index aaa61b6f50ff..e78983202737 100644 --- a/arch/arm/include/asm/smp_plat.h +++ b/arch/arm/include/asm/smp_plat.h @@ -49,7 +49,7 @@ static inline int cache_ops_need_broadcast(void) /* * Logical CPU mapping. */ -extern int __cpu_logical_map[]; +extern u32 __cpu_logical_map[]; #define cpu_logical_map(cpu) __cpu_logical_map[cpu] /* * Retrieve logical cpu index corresponding to a given MPIDR[23:0] diff --git a/arch/arm/kernel/devtree.c b/arch/arm/kernel/devtree.c index 5af04f6daa33..0905502bee15 100644 --- a/arch/arm/kernel/devtree.c +++ b/arch/arm/kernel/devtree.c @@ -82,7 +82,7 @@ void __init arm_dt_init_cpu_maps(void) u32 i, j, cpuidx = 1; u32 mpidr = is_smp() ? read_cpuid_mpidr() & MPIDR_HWID_BITMASK : 0; - u32 tmp_map[NR_CPUS] = { [0 ... NR_CPUS-1] = UINT_MAX }; + u32 tmp_map[NR_CPUS] = { [0 ... NR_CPUS-1] = MPIDR_INVALID }; bool bootcpu_valid = false; cpus = of_find_node_by_path("/cpus"); @@ -92,6 +92,9 @@ void __init arm_dt_init_cpu_maps(void) for_each_child_of_node(cpus, cpu) { u32 hwid; + if (of_node_cmp(cpu->type, "cpu")) + continue; + pr_debug(" * %s...\n", cpu->full_name); /* * A device tree containing CPU nodes with missing "reg" diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 1522c7ae31b0..b4b1d397592b 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -444,7 +444,7 @@ void notrace cpu_init(void) : "r14"); } -int __cpu_logical_map[NR_CPUS]; +u32 __cpu_logical_map[NR_CPUS] = { [0 ... NR_CPUS-1] = MPIDR_INVALID }; void __init smp_setup_processor_id(void) { diff --git a/arch/arm/mm/nommu.c b/arch/arm/mm/nommu.c index d51225f90ae2..eb5293a69a84 100644 --- a/arch/arm/mm/nommu.c +++ b/arch/arm/mm/nommu.c @@ -57,6 +57,12 @@ void flush_dcache_page(struct page *page) } EXPORT_SYMBOL(flush_dcache_page); +void flush_kernel_dcache_page(struct page *page) +{ + __cpuc_flush_dcache_area(page_address(page), PAGE_SIZE); +} +EXPORT_SYMBOL(flush_kernel_dcache_page); + void copy_to_user_page(struct vm_area_struct *vma, struct page *page, unsigned long uaddr, void *dst, const void *src, unsigned long len) diff --git a/arch/arm/mm/proc-fa526.S b/arch/arm/mm/proc-fa526.S index d217e9795d74..aaeb6c127c7a 100644 --- a/arch/arm/mm/proc-fa526.S +++ b/arch/arm/mm/proc-fa526.S @@ -81,7 +81,6 @@ ENDPROC(cpu_fa526_reset) */ .align 4 ENTRY(cpu_fa526_do_idle) - mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt mov pc, lr diff --git a/arch/arm/mm/proc-macros.S b/arch/arm/mm/proc-macros.S index f9a0aa725ea9..e3c48a3fe063 100644 --- a/arch/arm/mm/proc-macros.S +++ b/arch/arm/mm/proc-macros.S @@ -333,3 +333,8 @@ ENTRY(\name\()_tlb_fns) .endif .size \name\()_tlb_fns, . - \name\()_tlb_fns .endm + +.macro globl_equ x, y + .globl \x + .equ \x, \y +.endm diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S index 4c8c9c10a388..e35fec34453e 100644 --- a/arch/arm/mm/proc-v7.S +++ b/arch/arm/mm/proc-v7.S @@ -140,6 +140,29 @@ ENTRY(cpu_v7_do_resume) ENDPROC(cpu_v7_do_resume) #endif +#ifdef CONFIG_CPU_PJ4B + globl_equ cpu_pj4b_switch_mm, cpu_v7_switch_mm + globl_equ cpu_pj4b_set_pte_ext, cpu_v7_set_pte_ext + globl_equ cpu_pj4b_proc_init, cpu_v7_proc_init + globl_equ cpu_pj4b_proc_fin, cpu_v7_proc_fin + globl_equ cpu_pj4b_reset, cpu_v7_reset +#ifdef CONFIG_PJ4B_ERRATA_4742 +ENTRY(cpu_pj4b_do_idle) + dsb @ WFI may enter a low-power mode + wfi + dsb @barrier + mov pc, lr +ENDPROC(cpu_pj4b_do_idle) +#else + globl_equ cpu_pj4b_do_idle, cpu_v7_do_idle +#endif + globl_equ cpu_pj4b_dcache_clean_area, cpu_v7_dcache_clean_area + globl_equ cpu_pj4b_do_suspend, cpu_v7_do_suspend + globl_equ cpu_pj4b_do_resume, cpu_v7_do_resume + globl_equ cpu_pj4b_suspend_size, cpu_v7_suspend_size + +#endif + __CPUINIT /* @@ -350,6 +373,9 @@ __v7_setup_stack: @ define struct processor (see <asm/proc-fns.h> and proc-macros.S) define_processor_functions v7, dabort=v7_early_abort, pabort=v7_pabort, suspend=1 +#ifdef CONFIG_CPU_PJ4B + define_processor_functions pj4b, dabort=v7_early_abort, pabort=v7_pabort, suspend=1 +#endif .section ".rodata" @@ -362,7 +388,7 @@ __v7_setup_stack: /* * Standard v7 proc info content */ -.macro __v7_proc initfunc, mm_mmuflags = 0, io_mmuflags = 0, hwcaps = 0 +.macro __v7_proc initfunc, mm_mmuflags = 0, io_mmuflags = 0, hwcaps = 0, proc_fns = v7_processor_functions ALT_SMP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | \ PMD_SECT_AF | PMD_FLAGS_SMP | \mm_mmuflags) ALT_UP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | \ @@ -375,7 +401,7 @@ __v7_setup_stack: .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB | HWCAP_FAST_MULT | \ HWCAP_EDSP | HWCAP_TLS | \hwcaps .long cpu_v7_name - .long v7_processor_functions + .long \proc_fns .long v7wbi_tlb_fns .long v6_user_fns .long v7_cache_fns @@ -407,12 +433,14 @@ __v7_ca9mp_proc_info: /* * Marvell PJ4B processor. */ +#ifdef CONFIG_CPU_PJ4B .type __v7_pj4b_proc_info, #object __v7_pj4b_proc_info: .long 0x560f5800 .long 0xff0fff00 - __v7_proc __v7_pj4b_setup + __v7_proc __v7_pj4b_setup, proc_fns = pj4b_processor_functions .size __v7_pj4b_proc_info, . - __v7_pj4b_proc_info +#endif /* * ARM Ltd. Cortex A7 processor. diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c index 028ac1f71b51..46ac1ddea683 100644 --- a/arch/powerpc/sysdev/fsl_pci.c +++ b/arch/powerpc/sysdev/fsl_pci.c @@ -97,22 +97,14 @@ static int fsl_indirect_read_config(struct pci_bus *bus, unsigned int devfn, return indirect_read_config(bus, devfn, offset, len, val); } -static struct pci_ops fsl_indirect_pci_ops = +#if defined(CONFIG_FSL_SOC_BOOKE) || defined(CONFIG_PPC_86xx) + +static struct pci_ops fsl_indirect_pcie_ops = { .read = fsl_indirect_read_config, .write = indirect_write_config, }; -static void __init fsl_setup_indirect_pci(struct pci_controller* hose, - resource_size_t cfg_addr, - resource_size_t cfg_data, u32 flags) -{ - setup_indirect_pci(hose, cfg_addr, cfg_data, flags); - hose->ops = &fsl_indirect_pci_ops; -} - -#if defined(CONFIG_FSL_SOC_BOOKE) || defined(CONFIG_PPC_86xx) - #define MAX_PHYS_ADDR_BITS 40 static u64 pci64_dma_offset = 1ull << MAX_PHYS_ADDR_BITS; @@ -504,13 +496,15 @@ int __init fsl_add_bridge(struct platform_device *pdev, int is_primary) if (!hose->private_data) goto no_bridge; - fsl_setup_indirect_pci(hose, rsrc.start, rsrc.start + 0x4, - PPC_INDIRECT_TYPE_BIG_ENDIAN); + setup_indirect_pci(hose, rsrc.start, rsrc.start + 0x4, + PPC_INDIRECT_TYPE_BIG_ENDIAN); if (in_be32(&pci->block_rev1) < PCIE_IP_REV_3_0) hose->indirect_type |= PPC_INDIRECT_TYPE_FSL_CFG_REG_LINK; if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) { + /* use fsl_indirect_read_config for PCIe */ + hose->ops = &fsl_indirect_pcie_ops; /* For PCIE read HEADER_TYPE to identify controler mode */ early_read_config_byte(hose, 0, 0, PCI_HEADER_TYPE, &hdr_type); if ((hdr_type & 0x7f) != PCI_HEADER_TYPE_BRIDGE) @@ -814,8 +808,8 @@ int __init mpc83xx_add_bridge(struct device_node *dev) if (ret) goto err0; } else { - fsl_setup_indirect_pci(hose, rsrc_cfg.start, - rsrc_cfg.start + 4, 0); + setup_indirect_pci(hose, rsrc_cfg.start, + rsrc_cfg.start + 4, 0); } printk(KERN_INFO "Found FSL PCI host bridge at 0x%016llx. " diff --git a/arch/s390/include/asm/dma-mapping.h b/arch/s390/include/asm/dma-mapping.h index 886ac7d4937a..2f8c1abeb086 100644 --- a/arch/s390/include/asm/dma-mapping.h +++ b/arch/s390/include/asm/dma-mapping.h @@ -50,9 +50,10 @@ static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) { struct dma_map_ops *dma_ops = get_dma_ops(dev); + debug_dma_mapping_error(dev, dma_addr); if (dma_ops->mapping_error) return dma_ops->mapping_error(dev, dma_addr); - return (dma_addr == 0UL); + return (dma_addr == DMA_ERROR_CODE); } static inline void *dma_alloc_coherent(struct device *dev, size_t size, diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c index d8a6a385d048..feb719d3c851 100644 --- a/arch/s390/kernel/ipl.c +++ b/arch/s390/kernel/ipl.c @@ -754,9 +754,9 @@ static struct bin_attribute sys_reipl_fcp_scp_data_attr = { .write = reipl_fcp_scpdata_write, }; -DEFINE_IPL_ATTR_RW(reipl_fcp, wwpn, "0x%016llx\n", "%016llx\n", +DEFINE_IPL_ATTR_RW(reipl_fcp, wwpn, "0x%016llx\n", "%llx\n", reipl_block_fcp->ipl_info.fcp.wwpn); -DEFINE_IPL_ATTR_RW(reipl_fcp, lun, "0x%016llx\n", "%016llx\n", +DEFINE_IPL_ATTR_RW(reipl_fcp, lun, "0x%016llx\n", "%llx\n", reipl_block_fcp->ipl_info.fcp.lun); DEFINE_IPL_ATTR_RW(reipl_fcp, bootprog, "%lld\n", "%lld\n", reipl_block_fcp->ipl_info.fcp.bootprog); @@ -1323,9 +1323,9 @@ static struct shutdown_action __refdata reipl_action = { /* FCP dump device attributes */ -DEFINE_IPL_ATTR_RW(dump_fcp, wwpn, "0x%016llx\n", "%016llx\n", +DEFINE_IPL_ATTR_RW(dump_fcp, wwpn, "0x%016llx\n", "%llx\n", dump_block_fcp->ipl_info.fcp.wwpn); -DEFINE_IPL_ATTR_RW(dump_fcp, lun, "0x%016llx\n", "%016llx\n", +DEFINE_IPL_ATTR_RW(dump_fcp, lun, "0x%016llx\n", "%llx\n", dump_block_fcp->ipl_info.fcp.lun); DEFINE_IPL_ATTR_RW(dump_fcp, bootprog, "%lld\n", "%lld\n", dump_block_fcp->ipl_info.fcp.bootprog); diff --git a/arch/s390/kernel/irq.c b/arch/s390/kernel/irq.c index 408e866ae548..dd3c1994b8bd 100644 --- a/arch/s390/kernel/irq.c +++ b/arch/s390/kernel/irq.c @@ -312,6 +312,7 @@ void measurement_alert_subclass_unregister(void) } EXPORT_SYMBOL(measurement_alert_subclass_unregister); +#ifdef CONFIG_SMP void synchronize_irq(unsigned int irq) { /* @@ -320,6 +321,7 @@ void synchronize_irq(unsigned int irq) */ } EXPORT_SYMBOL_GPL(synchronize_irq); +#endif #ifndef CONFIG_PCI diff --git a/arch/s390/mm/mem_detect.c b/arch/s390/mm/mem_detect.c index 3cbd3b8bf311..cca388253a39 100644 --- a/arch/s390/mm/mem_detect.c +++ b/arch/s390/mm/mem_detect.c @@ -123,7 +123,8 @@ void create_mem_hole(struct mem_chunk mem_chunk[], unsigned long addr, continue; } else if ((addr <= chunk->addr) && (addr + size >= chunk->addr + chunk->size)) { - memset(chunk, 0 , sizeof(*chunk)); + memmove(chunk, chunk + 1, (MEMORY_CHUNKS-i-1) * sizeof(*chunk)); + memset(&mem_chunk[MEMORY_CHUNKS-1], 0, sizeof(*chunk)); } else if (addr + size < chunk->addr + chunk->size) { chunk->size = chunk->addr + chunk->size - addr - size; chunk->addr = addr + size; diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c index 9895a9a41380..211bce445522 100644 --- a/arch/x86/kernel/kprobes/core.c +++ b/arch/x86/kernel/kprobes/core.c @@ -365,10 +365,14 @@ int __kprobes __copy_instruction(u8 *dest, u8 *src) return insn.length; } -static void __kprobes arch_copy_kprobe(struct kprobe *p) +static int __kprobes arch_copy_kprobe(struct kprobe *p) { + int ret; + /* Copy an instruction with recovering if other optprobe modifies it.*/ - __copy_instruction(p->ainsn.insn, p->addr); + ret = __copy_instruction(p->ainsn.insn, p->addr); + if (!ret) + return -EINVAL; /* * __copy_instruction can modify the displacement of the instruction, @@ -384,6 +388,8 @@ static void __kprobes arch_copy_kprobe(struct kprobe *p) /* Also, displacement change doesn't affect the first byte */ p->opcode = p->ainsn.insn[0]; + + return 0; } int __kprobes arch_prepare_kprobe(struct kprobe *p) @@ -397,8 +403,8 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p) p->ainsn.insn = get_insn_slot(); if (!p->ainsn.insn) return -ENOMEM; - arch_copy_kprobe(p); - return 0; + + return arch_copy_kprobe(p); } void __kprobes arch_arm_kprobe(struct kprobe *p) diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index ec117c6c996c..14de9f46972e 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c @@ -66,20 +66,21 @@ struct dock_station { spinlock_t dd_lock; struct mutex hp_lock; struct list_head dependent_devices; - struct list_head hotplug_devices; struct list_head sibling; struct platform_device *dock_device; }; static LIST_HEAD(dock_stations); static int dock_station_count; +static DEFINE_MUTEX(hotplug_lock); struct dock_dependent_device { struct list_head list; - struct list_head hotplug_list; acpi_handle handle; - const struct acpi_dock_ops *ops; - void *context; + const struct acpi_dock_ops *hp_ops; + void *hp_context; + unsigned int hp_refcount; + void (*hp_release)(void *); }; #define DOCK_DOCKING 0x00000001 @@ -111,7 +112,6 @@ add_dock_dependent_device(struct dock_station *ds, acpi_handle handle) dd->handle = handle; INIT_LIST_HEAD(&dd->list); - INIT_LIST_HEAD(&dd->hotplug_list); spin_lock(&ds->dd_lock); list_add_tail(&dd->list, &ds->dependent_devices); @@ -121,35 +121,90 @@ add_dock_dependent_device(struct dock_station *ds, acpi_handle handle) } /** - * dock_add_hotplug_device - associate a hotplug handler with the dock station - * @ds: The dock station - * @dd: The dependent device struct - * - * Add the dependent device to the dock's hotplug device list + * dock_init_hotplug - Initialize a hotplug device on a docking station. + * @dd: Dock-dependent device. + * @ops: Dock operations to attach to the dependent device. + * @context: Data to pass to the @ops callbacks and @release. + * @init: Optional initialization routine to run after setting up context. + * @release: Optional release routine to run on removal. */ -static void -dock_add_hotplug_device(struct dock_station *ds, - struct dock_dependent_device *dd) +static int dock_init_hotplug(struct dock_dependent_device *dd, + const struct acpi_dock_ops *ops, void *context, + void (*init)(void *), void (*release)(void *)) { - mutex_lock(&ds->hp_lock); - list_add_tail(&dd->hotplug_list, &ds->hotplug_devices); - mutex_unlock(&ds->hp_lock); + int ret = 0; + + mutex_lock(&hotplug_lock); + + if (dd->hp_context) { + ret = -EEXIST; + } else { + dd->hp_refcount = 1; + dd->hp_ops = ops; + dd->hp_context = context; + dd->hp_release = release; + } + + if (!WARN_ON(ret) && init) + init(context); + + mutex_unlock(&hotplug_lock); + return ret; } /** - * dock_del_hotplug_device - remove a hotplug handler from the dock station - * @ds: The dock station - * @dd: the dependent device struct + * dock_release_hotplug - Decrement hotplug reference counter of dock device. + * @dd: Dock-dependent device. * - * Delete the dependent device from the dock's hotplug device list + * Decrement the reference counter of @dd and if 0, detach its hotplug + * operations from it, reset its context pointer and run the optional release + * routine if present. */ -static void -dock_del_hotplug_device(struct dock_station *ds, - struct dock_dependent_device *dd) +static void dock_release_hotplug(struct dock_dependent_device *dd) { - mutex_lock(&ds->hp_lock); - list_del(&dd->hotplug_list); - mutex_unlock(&ds->hp_lock); + void (*release)(void *) = NULL; + void *context = NULL; + + mutex_lock(&hotplug_lock); + + if (dd->hp_context && !--dd->hp_refcount) { + dd->hp_ops = NULL; + context = dd->hp_context; + dd->hp_context = NULL; + release = dd->hp_release; + dd->hp_release = NULL; + } + + if (release && context) + release(context); + + mutex_unlock(&hotplug_lock); +} + +static void dock_hotplug_event(struct dock_dependent_device *dd, u32 event, + bool uevent) +{ + acpi_notify_handler cb = NULL; + bool run = false; + + mutex_lock(&hotplug_lock); + + if (dd->hp_context) { + run = true; + dd->hp_refcount++; + if (dd->hp_ops) + cb = uevent ? dd->hp_ops->uevent : dd->hp_ops->handler; + } + + mutex_unlock(&hotplug_lock); + + if (!run) + return; + + if (cb) + cb(dd->handle, event, dd->hp_context); + + dock_release_hotplug(dd); } /** @@ -360,9 +415,8 @@ static void hotplug_dock_devices(struct dock_station *ds, u32 event) /* * First call driver specific hotplug functions */ - list_for_each_entry(dd, &ds->hotplug_devices, hotplug_list) - if (dd->ops && dd->ops->handler) - dd->ops->handler(dd->handle, event, dd->context); + list_for_each_entry(dd, &ds->dependent_devices, list) + dock_hotplug_event(dd, event, false); /* * Now make sure that an acpi_device is created for each @@ -398,9 +452,8 @@ static void dock_event(struct dock_station *ds, u32 event, int num) if (num == DOCK_EVENT) kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp); - list_for_each_entry(dd, &ds->hotplug_devices, hotplug_list) - if (dd->ops && dd->ops->uevent) - dd->ops->uevent(dd->handle, event, dd->context); + list_for_each_entry(dd, &ds->dependent_devices, list) + dock_hotplug_event(dd, event, true); if (num != DOCK_EVENT) kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp); @@ -570,19 +623,24 @@ EXPORT_SYMBOL_GPL(unregister_dock_notifier); * @handle: the handle of the device * @ops: handlers to call after docking * @context: device specific data + * @init: Optional initialization routine to run after registration + * @release: Optional release routine to run on unregistration * * If a driver would like to perform a hotplug operation after a dock * event, they can register an acpi_notifiy_handler to be called by * the dock driver after _DCK is executed. */ -int -register_hotplug_dock_device(acpi_handle handle, const struct acpi_dock_ops *ops, - void *context) +int register_hotplug_dock_device(acpi_handle handle, + const struct acpi_dock_ops *ops, void *context, + void (*init)(void *), void (*release)(void *)) { struct dock_dependent_device *dd; struct dock_station *dock_station; int ret = -EINVAL; + if (WARN_ON(!context)) + return -EINVAL; + if (!dock_station_count) return -ENODEV; @@ -597,12 +655,8 @@ register_hotplug_dock_device(acpi_handle handle, const struct acpi_dock_ops *ops * ops */ dd = find_dock_dependent_device(dock_station, handle); - if (dd) { - dd->ops = ops; - dd->context = context; - dock_add_hotplug_device(dock_station, dd); + if (dd && !dock_init_hotplug(dd, ops, context, init, release)) ret = 0; - } } return ret; @@ -624,7 +678,7 @@ void unregister_hotplug_dock_device(acpi_handle handle) list_for_each_entry(dock_station, &dock_stations, sibling) { dd = find_dock_dependent_device(dock_station, handle); if (dd) - dock_del_hotplug_device(dock_station, dd); + dock_release_hotplug(dd); } } EXPORT_SYMBOL_GPL(unregister_hotplug_dock_device); @@ -953,7 +1007,6 @@ static int __init dock_add(acpi_handle handle) mutex_init(&dock_station->hp_lock); spin_lock_init(&dock_station->dd_lock); INIT_LIST_HEAD(&dock_station->sibling); - INIT_LIST_HEAD(&dock_station->hotplug_devices); ATOMIC_INIT_NOTIFIER_HEAD(&dock_notifier_list); INIT_LIST_HEAD(&dock_station->dependent_devices); @@ -994,30 +1047,6 @@ err_unregister: } /** - * dock_remove - free up resources related to the dock station - */ -static int dock_remove(struct dock_station *ds) -{ - struct dock_dependent_device *dd, *tmp; - struct platform_device *dock_device = ds->dock_device; - - if (!dock_station_count) - return 0; - - /* remove dependent devices */ - list_for_each_entry_safe(dd, tmp, &ds->dependent_devices, list) - kfree(dd); - - list_del(&ds->sibling); - - /* cleanup sysfs */ - sysfs_remove_group(&dock_device->dev.kobj, &dock_attribute_group); - platform_device_unregister(dock_device); - - return 0; -} - -/** * find_dock_and_bay - look for dock stations and bays * @handle: acpi handle of a device * @lvl: unused @@ -1035,7 +1064,7 @@ find_dock_and_bay(acpi_handle handle, u32 lvl, void *context, void **rv) return AE_OK; } -static int __init dock_init(void) +int __init acpi_dock_init(void) { if (acpi_disabled) return 0; @@ -1054,19 +1083,3 @@ static int __init dock_init(void) ACPI_DOCK_DRIVER_DESCRIPTION, dock_station_count); return 0; } - -static void __exit dock_exit(void) -{ - struct dock_station *tmp, *dock_station; - - unregister_acpi_bus_notifier(&dock_acpi_notifier); - list_for_each_entry_safe(dock_station, tmp, &dock_stations, sibling) - dock_remove(dock_station); -} - -/* - * Must be called before drivers of devices in dock, otherwise we can't know - * which devices are in a dock - */ -subsys_initcall(dock_init); -module_exit(dock_exit); diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index 297cbf456f86..c610a76d92c4 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h @@ -40,6 +40,11 @@ void acpi_container_init(void); #else static inline void acpi_container_init(void) {} #endif +#ifdef CONFIG_ACPI_DOCK +void acpi_dock_init(void); +#else +static inline void acpi_dock_init(void) {} +#endif #ifdef CONFIG_ACPI_HOTPLUG_MEMORY void acpi_memory_hotplug_init(void); #else diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index b14ac46948c9..27da63061e11 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -2042,6 +2042,7 @@ int __init acpi_scan_init(void) acpi_lpss_init(); acpi_container_init(); acpi_memory_hotplug_init(); + acpi_dock_init(); mutex_lock(&acpi_scan_lock); /* diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index 87f2f395d79a..cf4e7020adac 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c @@ -156,8 +156,10 @@ static void ata_acpi_handle_hotplug(struct ata_port *ap, struct ata_device *dev, spin_unlock_irqrestore(ap->lock, flags); - if (wait) + if (wait) { ata_port_wait_eh(ap); + flush_work(&ap->hotplug_task.work); + } } static void ata_acpi_dev_notify_dock(acpi_handle handle, u32 event, void *data) @@ -214,6 +216,39 @@ static const struct acpi_dock_ops ata_acpi_ap_dock_ops = { .uevent = ata_acpi_ap_uevent, }; +void ata_acpi_hotplug_init(struct ata_host *host) +{ + int i; + + for (i = 0; i < host->n_ports; i++) { + struct ata_port *ap = host->ports[i]; + acpi_handle handle; + struct ata_device *dev; + + if (!ap) + continue; + + handle = ata_ap_acpi_handle(ap); + if (handle) { + /* we might be on a docking station */ + register_hotplug_dock_device(handle, + &ata_acpi_ap_dock_ops, ap, + NULL, NULL); + } + + ata_for_each_dev(dev, &ap->link, ALL) { + handle = ata_dev_acpi_handle(dev); + if (!handle) + continue; + + /* we might be on a docking station */ + register_hotplug_dock_device(handle, + &ata_acpi_dev_dock_ops, + dev, NULL, NULL); + } + } +} + /** * ata_acpi_dissociate - dissociate ATA host from ACPI objects * @host: target ATA host diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index f2184276539d..adf002a3c584 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -6148,6 +6148,8 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht) if (rc) goto err_tadd; + ata_acpi_hotplug_init(host); + /* set cable, sata_spd_limit and report */ for (i = 0; i < host->n_ports; i++) { struct ata_port *ap = host->ports[i]; diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index c949dd311b2e..577d902bc4de 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h @@ -122,6 +122,7 @@ extern int ata_acpi_register(void); extern void ata_acpi_unregister(void); extern void ata_acpi_bind(struct ata_device *dev); extern void ata_acpi_unbind(struct ata_device *dev); +extern void ata_acpi_hotplug_init(struct ata_host *host); #else static inline void ata_acpi_dissociate(struct ata_host *host) { } static inline int ata_acpi_on_suspend(struct ata_port *ap) { return 0; } @@ -134,6 +135,7 @@ static inline int ata_acpi_register(void) { return 0; } static inline void ata_acpi_unregister(void) { } static inline void ata_acpi_bind(struct ata_device *dev) { } static inline void ata_acpi_unbind(struct ata_device *dev) { } +static inline void ata_acpi_hotplug_init(struct ata_host *host) {} #endif /* libata-scsi.c */ diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index 49394e3f31bc..247bf3099731 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c @@ -4243,6 +4243,10 @@ static int rbd_dev_v2_header_info(struct rbd_device *rbd_dev) down_write(&rbd_dev->header_rwsem); + ret = rbd_dev_v2_image_size(rbd_dev); + if (ret) + goto out; + if (first_time) { ret = rbd_dev_v2_header_onetime(rbd_dev); if (ret) @@ -4276,10 +4280,6 @@ static int rbd_dev_v2_header_info(struct rbd_device *rbd_dev) "is EXPERIMENTAL!"); } - ret = rbd_dev_v2_image_size(rbd_dev); - if (ret) - goto out; - if (rbd_dev->spec->snap_id == CEPH_NOSNAP) if (rbd_dev->mapping.size != rbd_dev->header.image_size) rbd_dev->mapping.size = rbd_dev->header.image_size; diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c index 4b9bb5def6f1..93eb5cbcc1f6 100644 --- a/drivers/cpufreq/cpufreq_ondemand.c +++ b/drivers/cpufreq/cpufreq_ondemand.c @@ -47,6 +47,8 @@ static struct od_ops od_ops; static struct cpufreq_governor cpufreq_gov_ondemand; #endif +static unsigned int default_powersave_bias; + static void ondemand_powersave_bias_init_cpu(int cpu) { struct od_cpu_dbs_info_s *dbs_info = &per_cpu(od_cpu_dbs_info, cpu); @@ -543,7 +545,7 @@ static int od_init(struct dbs_data *dbs_data) tuners->sampling_down_factor = DEF_SAMPLING_DOWN_FACTOR; tuners->ignore_nice = 0; - tuners->powersave_bias = 0; + tuners->powersave_bias = default_powersave_bias; tuners->io_is_busy = should_io_be_busy(); dbs_data->tuners = tuners; @@ -585,6 +587,7 @@ static void od_set_powersave_bias(unsigned int powersave_bias) unsigned int cpu; cpumask_t done; + default_powersave_bias = powersave_bias; cpumask_clear(&done); get_online_cpus(); @@ -593,11 +596,17 @@ static void od_set_powersave_bias(unsigned int powersave_bias) continue; policy = per_cpu(od_cpu_dbs_info, cpu).cdbs.cur_policy; - dbs_data = policy->governor_data; - od_tuners = dbs_data->tuners; - od_tuners->powersave_bias = powersave_bias; + if (!policy) + continue; cpumask_or(&done, &done, policy->cpus); + + if (policy->governor != &cpufreq_gov_ondemand) + continue; + + dbs_data = policy->governor_data; + od_tuners = dbs_data->tuners; + od_tuners->powersave_bias = default_powersave_bias; } put_online_cpus(); } diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index d3f7d2db870f..4a430360af5a 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -1094,6 +1094,9 @@ static int omap_gpio_probe(struct platform_device *pdev) const struct omap_gpio_platform_data *pdata; struct resource *res; struct gpio_bank *bank; +#ifdef CONFIG_ARCH_OMAP1 + int irq_base; +#endif match = of_match_device(of_match_ptr(omap_gpio_match), dev); @@ -1135,11 +1138,28 @@ static int omap_gpio_probe(struct platform_device *pdev) pdata->get_context_loss_count; } +#ifdef CONFIG_ARCH_OMAP1 + /* + * REVISIT: Once we have OMAP1 supporting SPARSE_IRQ, we can drop + * irq_alloc_descs() and irq_domain_add_legacy() and just use a + * linear IRQ domain mapping for all OMAP platforms. + */ + irq_base = irq_alloc_descs(-1, 0, bank->width, 0); + if (irq_base < 0) { + dev_err(dev, "Couldn't allocate IRQ numbers\n"); + return -ENODEV; + } + bank->domain = irq_domain_add_legacy(node, bank->width, irq_base, + 0, &irq_domain_simple_ops, NULL); +#else bank->domain = irq_domain_add_linear(node, bank->width, &irq_domain_simple_ops, NULL); - if (!bank->domain) +#endif + if (!bank->domain) { + dev_err(dev, "Couldn't register an IRQ domain\n"); return -ENODEV; + } if (bank->regs->set_dataout && bank->regs->clr_dataout) bank->set_dataout = _set_gpio_dataout_reg; diff --git a/drivers/mfd/tps6586x.c b/drivers/mfd/tps6586x.c index 721b9186a5d1..4b93ed4d5cd6 100644 --- a/drivers/mfd/tps6586x.c +++ b/drivers/mfd/tps6586x.c @@ -107,7 +107,7 @@ static struct mfd_cell tps6586x_cell[] = { .name = "tps6586x-gpio", }, { - .name = "tps6586x-pmic", + .name = "tps6586x-regulator", }, { .name = "tps6586x-rtc", diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index 716aa93fff76..59df8575a48c 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c @@ -61,6 +61,7 @@ static DEFINE_MUTEX(bridge_mutex); static void handle_hotplug_event_bridge (acpi_handle, u32, void *); static void acpiphp_sanitize_bus(struct pci_bus *bus); static void acpiphp_set_hpp_values(struct pci_bus *bus); +static void hotplug_event_func(acpi_handle handle, u32 type, void *context); static void handle_hotplug_event_func(acpi_handle handle, u32 type, void *context); static void free_bridge(struct kref *kref); @@ -147,7 +148,7 @@ static int post_dock_fixups(struct notifier_block *nb, unsigned long val, static const struct acpi_dock_ops acpiphp_dock_ops = { - .handler = handle_hotplug_event_func, + .handler = hotplug_event_func, }; /* Check whether the PCI device is managed by native PCIe hotplug driver */ @@ -179,6 +180,20 @@ static bool device_is_managed_by_native_pciehp(struct pci_dev *pdev) return true; } +static void acpiphp_dock_init(void *data) +{ + struct acpiphp_func *func = data; + + get_bridge(func->slot->bridge); +} + +static void acpiphp_dock_release(void *data) +{ + struct acpiphp_func *func = data; + + put_bridge(func->slot->bridge); +} + /* callback routine to register each ACPI PCI slot object */ static acpi_status register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) @@ -298,7 +313,8 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) */ newfunc->flags &= ~FUNC_HAS_EJ0; if (register_hotplug_dock_device(handle, - &acpiphp_dock_ops, newfunc)) + &acpiphp_dock_ops, newfunc, + acpiphp_dock_init, acpiphp_dock_release)) dbg("failed to register dock device\n"); /* we need to be notified when dock events happen @@ -670,6 +686,7 @@ static int __ref enable_device(struct acpiphp_slot *slot) struct pci_bus *bus = slot->bridge->pci_bus; struct acpiphp_func *func; int num, max, pass; + LIST_HEAD(add_list); if (slot->flags & SLOT_ENABLED) goto err_exit; @@ -694,13 +711,15 @@ static int __ref enable_device(struct acpiphp_slot *slot) max = pci_scan_bridge(bus, dev, max, pass); if (pass && dev->subordinate) { check_hotplug_bridge(slot, dev); - pci_bus_size_bridges(dev->subordinate); + pcibios_resource_survey_bus(dev->subordinate); + __pci_bus_size_bridges(dev->subordinate, + &add_list); } } } } - pci_bus_assign_resources(bus); + __pci_bus_assign_resources(bus, &add_list, NULL); acpiphp_sanitize_bus(bus); acpiphp_set_hpp_values(bus); acpiphp_set_acpi_region(slot); @@ -1065,22 +1084,12 @@ static void handle_hotplug_event_bridge(acpi_handle handle, u32 type, alloc_acpi_hp_work(handle, type, context, _handle_hotplug_event_bridge); } -static void _handle_hotplug_event_func(struct work_struct *work) +static void hotplug_event_func(acpi_handle handle, u32 type, void *context) { - struct acpiphp_func *func; + struct acpiphp_func *func = context; char objname[64]; struct acpi_buffer buffer = { .length = sizeof(objname), .pointer = objname }; - struct acpi_hp_work *hp_work; - acpi_handle handle; - u32 type; - - hp_work = container_of(work, struct acpi_hp_work, work); - handle = hp_work->handle; - type = hp_work->type; - func = (struct acpiphp_func *)hp_work->context; - - acpi_scan_lock_acquire(); acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); @@ -1113,6 +1122,18 @@ static void _handle_hotplug_event_func(struct work_struct *work) warn("notify_handler: unknown event type 0x%x for %s\n", type, objname); break; } +} + +static void _handle_hotplug_event_func(struct work_struct *work) +{ + struct acpi_hp_work *hp_work; + struct acpiphp_func *func; + + hp_work = container_of(work, struct acpi_hp_work, work); + func = hp_work->context; + acpi_scan_lock_acquire(); + + hotplug_event_func(hp_work->handle, hp_work->type, func); acpi_scan_lock_release(); kfree(hp_work); /* allocated in handle_hotplug_event_func */ diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 68678ed76b0d..d1182c4a754e 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -202,6 +202,11 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, struct resource *res, unsigned int reg); int pci_resource_bar(struct pci_dev *dev, int resno, enum pci_bar_type *type); void pci_configure_ari(struct pci_dev *dev); +void __ref __pci_bus_size_bridges(struct pci_bus *bus, + struct list_head *realloc_head); +void __ref __pci_bus_assign_resources(const struct pci_bus *bus, + struct list_head *realloc_head, + struct list_head *fail_head); /** * pci_ari_enabled - query ARI forwarding status diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 16abaaa1f83c..d254e2379533 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -1044,7 +1044,7 @@ handle_done: ; } -static void __ref __pci_bus_size_bridges(struct pci_bus *bus, +void __ref __pci_bus_size_bridges(struct pci_bus *bus, struct list_head *realloc_head) { struct pci_dev *dev; @@ -1115,9 +1115,9 @@ void __ref pci_bus_size_bridges(struct pci_bus *bus) } EXPORT_SYMBOL(pci_bus_size_bridges); -static void __ref __pci_bus_assign_resources(const struct pci_bus *bus, - struct list_head *realloc_head, - struct list_head *fail_head) +void __ref __pci_bus_assign_resources(const struct pci_bus *bus, + struct list_head *realloc_head, + struct list_head *fail_head) { struct pci_bus *b; struct pci_dev *dev; diff --git a/drivers/regulator/tps6586x-regulator.c b/drivers/regulator/tps6586x-regulator.c index d8fa37d5c734..2c9155b66f09 100644 --- a/drivers/regulator/tps6586x-regulator.c +++ b/drivers/regulator/tps6586x-regulator.c @@ -439,7 +439,7 @@ static int tps6586x_regulator_remove(struct platform_device *pdev) static struct platform_driver tps6586x_regulator_driver = { .driver = { - .name = "tps6586x-pmic", + .name = "tps6586x-regulator", .owner = THIS_MODULE, }, .probe = tps6586x_regulator_probe, diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index 292b24f9bf93..32ae6c67ea3a 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c @@ -1656,9 +1656,12 @@ static int fcoe_xmit(struct fc_lport *lport, struct fc_frame *fp) if (fcoe->netdev->priv_flags & IFF_802_1Q_VLAN && fcoe->realdev->features & NETIF_F_HW_VLAN_CTAG_TX) { - skb->vlan_tci = VLAN_TAG_PRESENT | - vlan_dev_vlan_id(fcoe->netdev); + /* must set skb->dev before calling vlan_put_tag */ skb->dev = fcoe->realdev; + skb = __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), + vlan_dev_vlan_id(fcoe->netdev)); + if (!skb) + return -ENOMEM; } else skb->dev = fcoe->netdev; diff --git a/drivers/spi/spi-pxa2xx-dma.c b/drivers/spi/spi-pxa2xx-dma.c index c735c5a008a2..6427600b5bbe 100644 --- a/drivers/spi/spi-pxa2xx-dma.c +++ b/drivers/spi/spi-pxa2xx-dma.c @@ -59,7 +59,7 @@ static int pxa2xx_spi_map_dma_buffer(struct driver_data *drv_data, int ret; sg_free_table(sgt); - ret = sg_alloc_table(sgt, nents, GFP_KERNEL); + ret = sg_alloc_table(sgt, nents, GFP_ATOMIC); if (ret) return ret; } diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c index f5d84d6f8222..48b396fced0a 100644 --- a/drivers/spi/spi-pxa2xx.c +++ b/drivers/spi/spi-pxa2xx.c @@ -1075,7 +1075,7 @@ pxa2xx_spi_acpi_get_pdata(struct platform_device *pdev) acpi_bus_get_device(ACPI_HANDLE(&pdev->dev), &adev)) return NULL; - pdata = devm_kzalloc(&pdev->dev, sizeof(*ssp), GFP_KERNEL); + pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) { dev_err(&pdev->dev, "failed to allocate memory for platform data\n"); diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c index 5000586cb98d..71cc3e6ef47c 100644 --- a/drivers/spi/spi-s3c64xx.c +++ b/drivers/spi/spi-s3c64xx.c @@ -444,7 +444,7 @@ static int s3c64xx_spi_prepare_transfer(struct spi_master *spi) } ret = pm_runtime_get_sync(&sdd->pdev->dev); - if (ret != 0) { + if (ret < 0) { dev_err(dev, "Failed to enable device: %d\n", ret); goto out_tx; } diff --git a/fs/fuse/file.c b/fs/fuse/file.c index e570081f9f76..35f281033142 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -2470,13 +2470,16 @@ static long fuse_file_fallocate(struct file *file, int mode, loff_t offset, .mode = mode }; int err; + bool lock_inode = !(mode & FALLOC_FL_KEEP_SIZE) || + (mode & FALLOC_FL_PUNCH_HOLE); if (fc->no_fallocate) return -EOPNOTSUPP; - if (mode & FALLOC_FL_PUNCH_HOLE) { + if (lock_inode) { mutex_lock(&inode->i_mutex); - fuse_set_nowrite(inode); + if (mode & FALLOC_FL_PUNCH_HOLE) + fuse_set_nowrite(inode); } req = fuse_get_req_nopages(fc); @@ -2511,8 +2514,9 @@ static long fuse_file_fallocate(struct file *file, int mode, loff_t offset, fuse_invalidate_attr(inode); out: - if (mode & FALLOC_FL_PUNCH_HOLE) { - fuse_release_nowrite(inode); + if (lock_inode) { + if (mode & FALLOC_FL_PUNCH_HOLE) + fuse_release_nowrite(inode); mutex_unlock(&inode->i_mutex); } diff --git a/include/acpi/acpi_drivers.h b/include/acpi/acpi_drivers.h index e6168a24b9f0..b420939f5eb5 100644 --- a/include/acpi/acpi_drivers.h +++ b/include/acpi/acpi_drivers.h @@ -123,7 +123,9 @@ extern int register_dock_notifier(struct notifier_block *nb); extern void unregister_dock_notifier(struct notifier_block *nb); extern int register_hotplug_dock_device(acpi_handle handle, const struct acpi_dock_ops *ops, - void *context); + void *context, + void (*init)(void *), + void (*release)(void *)); extern void unregister_hotplug_dock_device(acpi_handle handle); #else static inline int is_dock_device(acpi_handle handle) @@ -139,7 +141,9 @@ static inline void unregister_dock_notifier(struct notifier_block *nb) } static inline int register_hotplug_dock_device(acpi_handle handle, const struct acpi_dock_ops *ops, - void *context) + void *context, + void (*init)(void *), + void (*release)(void *)) { return -ENODEV; } diff --git a/kernel/events/hw_breakpoint.c b/kernel/events/hw_breakpoint.c index a64f8aeb5c1f..20185ea64aa6 100644 --- a/kernel/events/hw_breakpoint.c +++ b/kernel/events/hw_breakpoint.c @@ -120,7 +120,7 @@ static int task_bp_pinned(int cpu, struct perf_event *bp, enum bp_type_idx type) list_for_each_entry(iter, &bp_task_head, hw.bp_list) { if (iter->hw.bp_target == tsk && find_slot_idx(iter) == type && - cpu == iter->cpu) + (iter->cpu < 0 || cpu == iter->cpu)) count += hw_breakpoint_weight(iter); } @@ -149,7 +149,7 @@ fetch_bp_busy_slots(struct bp_busy_slots *slots, struct perf_event *bp, return; } - for_each_online_cpu(cpu) { + for_each_possible_cpu(cpu) { unsigned int nr; nr = per_cpu(nr_cpu_bp_pinned[type], cpu); @@ -235,7 +235,7 @@ toggle_bp_slot(struct perf_event *bp, bool enable, enum bp_type_idx type, if (cpu >= 0) { toggle_bp_task_slot(bp, cpu, enable, type, weight); } else { - for_each_online_cpu(cpu) + for_each_possible_cpu(cpu) toggle_bp_task_slot(bp, cpu, enable, type, weight); } |