Commit 9199c4ca authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'pci-v3.13-fixes-2' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci

Pull PCI updates from Bjorn Helgaas:
 "PCI device hotplug
    - Move device_del() from pci_stop_dev() to pci_destroy_dev() (Rafael
      Wysocki)

  Host bridge drivers
    - Update maintainers for DesignWare, i.MX6, Armada, R-Car (Bjorn
      Helgaas)
    - mvebu: Return 'unsupported' for Interrupt Line and Interrupt Pin
      (Jason Gunthorpe)

  Miscellaneous
    - Avoid unnecessary CPU switch when calling .probe() (Alexander
      Duyck)
    - Revert "workqueue: allow work_on_cpu() to be called recursively"
      (Bjorn Helgaas)
    - Disable Bus Master only on kexec reboot (Khalid Aziz)
    - Omit PCI ID macro strings to shorten quirk names for LTO (Michal
      Marek)"

* tag 'pci-v3.13-fixes-2' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci:
  MAINTAINERS: Add DesignWare, i.MX6, Armada, R-Car PCI host maintainers
  PCI: Disable Bus Master only on kexec reboot
  PCI: mvebu: Return 'unsupported' for Interrupt Line and Interrupt Pin
  PCI: Omit PCI ID macro strings to shorten quirk names
  PCI: Move device_del() from pci_stop_dev() to pci_destroy_dev()
  Revert "workqueue: allow work_on_cpu() to be called recursively"
  PCI: Avoid unnecessary CPU switch when calling driver .probe() method
parents b5745c59 f0b75693
...@@ -6465,19 +6465,52 @@ F: drivers/pci/ ...@@ -6465,19 +6465,52 @@ F: drivers/pci/
F: include/linux/pci* F: include/linux/pci*
F: arch/x86/pci/ F: arch/x86/pci/
PCI DRIVER FOR IMX6
M: Richard Zhu <r65037@freescale.com>
M: Shawn Guo <shawn.guo@linaro.org>
L: linux-pci@vger.kernel.org
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
F: drivers/pci/host/*imx6*
PCI DRIVER FOR MVEBU (Marvell Armada 370 and Armada XP SOC support)
M: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
M: Jason Cooper <jason@lakedaemon.net>
L: linux-pci@vger.kernel.org
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
F: drivers/pci/host/*mvebu*
PCI DRIVER FOR NVIDIA TEGRA PCI DRIVER FOR NVIDIA TEGRA
M: Thierry Reding <thierry.reding@gmail.com> M: Thierry Reding <thierry.reding@gmail.com>
L: linux-tegra@vger.kernel.org L: linux-tegra@vger.kernel.org
L: linux-pci@vger.kernel.org
S: Supported S: Supported
F: Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt F: Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
F: drivers/pci/host/pci-tegra.c F: drivers/pci/host/pci-tegra.c
PCI DRIVER FOR RENESAS R-CAR
M: Simon Horman <horms@verge.net.au>
L: linux-pci@vger.kernel.org
L: linux-sh@vger.kernel.org
S: Maintained
F: drivers/pci/host/*rcar*
PCI DRIVER FOR SAMSUNG EXYNOS PCI DRIVER FOR SAMSUNG EXYNOS
M: Jingoo Han <jg1.han@samsung.com> M: Jingoo Han <jg1.han@samsung.com>
L: linux-pci@vger.kernel.org L: linux-pci@vger.kernel.org
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
L: linux-samsung-soc@vger.kernel.org (moderated for non-subscribers)
S: Maintained S: Maintained
F: drivers/pci/host/pci-exynos.c F: drivers/pci/host/pci-exynos.c
PCI DRIVER FOR SYNOPSIS DESIGNWARE
M: Mohit Kumar <mohit.kumar@st.com>
M: Jingoo Han <jg1.han@samsung.com>
L: linux-pci@vger.kernel.org
S: Maintained
F: drivers/pci/host/*designware*
PCMCIA SUBSYSTEM PCMCIA SUBSYSTEM
P: Linux PCMCIA Team P: Linux PCMCIA Team
L: linux-pcmcia@lists.infradead.org L: linux-pcmcia@lists.infradead.org
......
...@@ -447,6 +447,11 @@ static int mvebu_sw_pci_bridge_read(struct mvebu_pcie_port *port, ...@@ -447,6 +447,11 @@ static int mvebu_sw_pci_bridge_read(struct mvebu_pcie_port *port,
*value = 0; *value = 0;
break; break;
case PCI_INTERRUPT_LINE:
/* LINE PIN MIN_GNT MAX_LAT */
*value = 0;
break;
default: default:
*value = 0xffffffff; *value = 0xffffffff;
return PCIBIOS_BAD_REGISTER_NUMBER; return PCIBIOS_BAD_REGISTER_NUMBER;
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <linux/cpu.h> #include <linux/cpu.h>
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
#include <linux/suspend.h> #include <linux/suspend.h>
#include <linux/kexec.h>
#include "pci.h" #include "pci.h"
struct pci_dynid { struct pci_dynid {
...@@ -288,12 +289,27 @@ static int pci_call_probe(struct pci_driver *drv, struct pci_dev *dev, ...@@ -288,12 +289,27 @@ static int pci_call_probe(struct pci_driver *drv, struct pci_dev *dev,
int error, node; int error, node;
struct drv_dev_and_id ddi = { drv, dev, id }; struct drv_dev_and_id ddi = { drv, dev, id };
/* Execute driver initialization on node where the device's /*
bus is attached to. This way the driver likely allocates * Execute driver initialization on node where the device is
its local memory on the right node without any need to * attached. This way the driver likely allocates its local memory
change it. */ * on the right node.
*/
node = dev_to_node(&dev->dev); node = dev_to_node(&dev->dev);
if (node >= 0) {
/*
* On NUMA systems, we are likely to call a PF probe function using
* work_on_cpu(). If that probe calls pci_enable_sriov() (which
* adds the VF devices via pci_bus_add_device()), we may re-enter
* this function to call the VF probe function. Calling
* work_on_cpu() again will cause a lockdep warning. Since VFs are
* always on the same node as the PF, we can work around this by
* avoiding work_on_cpu() when we're already on the correct node.
*
* Preemption is enabled, so it's theoretically unsafe to use
* numa_node_id(), but even if we run the probe function on the
* wrong node, it should be functionally correct.
*/
if (node >= 0 && node != numa_node_id()) {
int cpu; int cpu;
get_online_cpus(); get_online_cpus();
...@@ -305,6 +321,7 @@ static int pci_call_probe(struct pci_driver *drv, struct pci_dev *dev, ...@@ -305,6 +321,7 @@ static int pci_call_probe(struct pci_driver *drv, struct pci_dev *dev,
put_online_cpus(); put_online_cpus();
} else } else
error = local_pci_probe(&ddi); error = local_pci_probe(&ddi);
return error; return error;
} }
...@@ -399,12 +416,17 @@ static void pci_device_shutdown(struct device *dev) ...@@ -399,12 +416,17 @@ static void pci_device_shutdown(struct device *dev)
pci_msi_shutdown(pci_dev); pci_msi_shutdown(pci_dev);
pci_msix_shutdown(pci_dev); pci_msix_shutdown(pci_dev);
#ifdef CONFIG_KEXEC
/* /*
* Turn off Bus Master bit on the device to tell it to not * If this is a kexec reboot, turn off Bus Master bit on the
* continue to do DMA. Don't touch devices in D3cold or unknown states. * device to tell it to not continue to do DMA. Don't touch
* devices in D3cold or unknown states.
* If it is not a kexec reboot, firmware will hit the PCI
* devices with big hammer and stop their DMA any way.
*/ */
if (pci_dev->current_state <= PCI_D3hot) if (kexec_in_progress && (pci_dev->current_state <= PCI_D3hot))
pci_clear_master(pci_dev); pci_clear_master(pci_dev);
#endif
} }
#ifdef CONFIG_PM #ifdef CONFIG_PM
......
...@@ -24,7 +24,7 @@ static void pci_stop_dev(struct pci_dev *dev) ...@@ -24,7 +24,7 @@ static void pci_stop_dev(struct pci_dev *dev)
if (dev->is_added) { if (dev->is_added) {
pci_proc_detach_device(dev); pci_proc_detach_device(dev);
pci_remove_sysfs_dev_files(dev); pci_remove_sysfs_dev_files(dev);
device_del(&dev->dev); device_release_driver(&dev->dev);
dev->is_added = 0; dev->is_added = 0;
} }
...@@ -34,6 +34,8 @@ static void pci_stop_dev(struct pci_dev *dev) ...@@ -34,6 +34,8 @@ static void pci_stop_dev(struct pci_dev *dev)
static void pci_destroy_dev(struct pci_dev *dev) static void pci_destroy_dev(struct pci_dev *dev)
{ {
device_del(&dev->dev);
down_write(&pci_bus_sem); down_write(&pci_bus_sem);
list_del(&dev->bus_list); list_del(&dev->bus_list);
up_write(&pci_bus_sem); up_write(&pci_bus_sem);
......
...@@ -198,6 +198,9 @@ extern u32 vmcoreinfo_note[VMCOREINFO_NOTE_SIZE/4]; ...@@ -198,6 +198,9 @@ extern u32 vmcoreinfo_note[VMCOREINFO_NOTE_SIZE/4];
extern size_t vmcoreinfo_size; extern size_t vmcoreinfo_size;
extern size_t vmcoreinfo_max_size; extern size_t vmcoreinfo_max_size;
/* flag to track if kexec reboot is in progress */
extern bool kexec_in_progress;
int __init parse_crashkernel(char *cmdline, unsigned long long system_ram, int __init parse_crashkernel(char *cmdline, unsigned long long system_ram,
unsigned long long *crash_size, unsigned long long *crash_base); unsigned long long *crash_size, unsigned long long *crash_base);
int parse_crashkernel_high(char *cmdline, unsigned long long system_ram, int parse_crashkernel_high(char *cmdline, unsigned long long system_ram,
......
...@@ -1567,65 +1567,65 @@ enum pci_fixup_pass { ...@@ -1567,65 +1567,65 @@ enum pci_fixup_pass {
/* Anonymous variables would be nice... */ /* Anonymous variables would be nice... */
#define DECLARE_PCI_FIXUP_SECTION(section, name, vendor, device, class, \ #define DECLARE_PCI_FIXUP_SECTION(section, name, vendor, device, class, \
class_shift, hook) \ class_shift, hook) \
static const struct pci_fixup __pci_fixup_##name __used \ static const struct pci_fixup __PASTE(__pci_fixup_##name,__LINE__) __used \
__attribute__((__section__(#section), aligned((sizeof(void *))))) \ __attribute__((__section__(#section), aligned((sizeof(void *))))) \
= { vendor, device, class, class_shift, hook }; = { vendor, device, class, class_shift, hook };
#define DECLARE_PCI_FIXUP_CLASS_EARLY(vendor, device, class, \ #define DECLARE_PCI_FIXUP_CLASS_EARLY(vendor, device, class, \
class_shift, hook) \ class_shift, hook) \
DECLARE_PCI_FIXUP_SECTION(.pci_fixup_early, \ DECLARE_PCI_FIXUP_SECTION(.pci_fixup_early, \
vendor##device##hook, vendor, device, class, class_shift, hook) hook, vendor, device, class, class_shift, hook)
#define DECLARE_PCI_FIXUP_CLASS_HEADER(vendor, device, class, \ #define DECLARE_PCI_FIXUP_CLASS_HEADER(vendor, device, class, \
class_shift, hook) \ class_shift, hook) \
DECLARE_PCI_FIXUP_SECTION(.pci_fixup_header, \ DECLARE_PCI_FIXUP_SECTION(.pci_fixup_header, \
vendor##device##hook, vendor, device, class, class_shift, hook) hook, vendor, device, class, class_shift, hook)
#define DECLARE_PCI_FIXUP_CLASS_FINAL(vendor, device, class, \ #define DECLARE_PCI_FIXUP_CLASS_FINAL(vendor, device, class, \
class_shift, hook) \ class_shift, hook) \
DECLARE_PCI_FIXUP_SECTION(.pci_fixup_final, \ DECLARE_PCI_FIXUP_SECTION(.pci_fixup_final, \
vendor##device##hook, vendor, device, class, class_shift, hook) hook, vendor, device, class, class_shift, hook)
#define DECLARE_PCI_FIXUP_CLASS_ENABLE(vendor, device, class, \ #define DECLARE_PCI_FIXUP_CLASS_ENABLE(vendor, device, class, \
class_shift, hook) \ class_shift, hook) \
DECLARE_PCI_FIXUP_SECTION(.pci_fixup_enable, \ DECLARE_PCI_FIXUP_SECTION(.pci_fixup_enable, \
vendor##device##hook, vendor, device, class, class_shift, hook) hook, vendor, device, class, class_shift, hook)
#define DECLARE_PCI_FIXUP_CLASS_RESUME(vendor, device, class, \ #define DECLARE_PCI_FIXUP_CLASS_RESUME(vendor, device, class, \
class_shift, hook) \ class_shift, hook) \
DECLARE_PCI_FIXUP_SECTION(.pci_fixup_resume, \ DECLARE_PCI_FIXUP_SECTION(.pci_fixup_resume, \
resume##vendor##device##hook, vendor, device, class, \ resume##hook, vendor, device, class, \
class_shift, hook) class_shift, hook)
#define DECLARE_PCI_FIXUP_CLASS_RESUME_EARLY(vendor, device, class, \ #define DECLARE_PCI_FIXUP_CLASS_RESUME_EARLY(vendor, device, class, \
class_shift, hook) \ class_shift, hook) \
DECLARE_PCI_FIXUP_SECTION(.pci_fixup_resume_early, \ DECLARE_PCI_FIXUP_SECTION(.pci_fixup_resume_early, \
resume_early##vendor##device##hook, vendor, device, \ resume_early##hook, vendor, device, \
class, class_shift, hook) class, class_shift, hook)
#define DECLARE_PCI_FIXUP_CLASS_SUSPEND(vendor, device, class, \ #define DECLARE_PCI_FIXUP_CLASS_SUSPEND(vendor, device, class, \
class_shift, hook) \ class_shift, hook) \
DECLARE_PCI_FIXUP_SECTION(.pci_fixup_suspend, \ DECLARE_PCI_FIXUP_SECTION(.pci_fixup_suspend, \
suspend##vendor##device##hook, vendor, device, class, \ suspend##hook, vendor, device, class, \
class_shift, hook) class_shift, hook)
#define DECLARE_PCI_FIXUP_EARLY(vendor, device, hook) \ #define DECLARE_PCI_FIXUP_EARLY(vendor, device, hook) \
DECLARE_PCI_FIXUP_SECTION(.pci_fixup_early, \ DECLARE_PCI_FIXUP_SECTION(.pci_fixup_early, \
vendor##device##hook, vendor, device, PCI_ANY_ID, 0, hook) hook, vendor, device, PCI_ANY_ID, 0, hook)
#define DECLARE_PCI_FIXUP_HEADER(vendor, device, hook) \ #define DECLARE_PCI_FIXUP_HEADER(vendor, device, hook) \
DECLARE_PCI_FIXUP_SECTION(.pci_fixup_header, \ DECLARE_PCI_FIXUP_SECTION(.pci_fixup_header, \
vendor##device##hook, vendor, device, PCI_ANY_ID, 0, hook) hook, vendor, device, PCI_ANY_ID, 0, hook)
#define DECLARE_PCI_FIXUP_FINAL(vendor, device, hook) \ #define DECLARE_PCI_FIXUP_FINAL(vendor, device, hook) \
DECLARE_PCI_FIXUP_SECTION(.pci_fixup_final, \ DECLARE_PCI_FIXUP_SECTION(.pci_fixup_final, \
vendor##device##hook, vendor, device, PCI_ANY_ID, 0, hook) hook, vendor, device, PCI_ANY_ID, 0, hook)
#define DECLARE_PCI_FIXUP_ENABLE(vendor, device, hook) \ #define DECLARE_PCI_FIXUP_ENABLE(vendor, device, hook) \
DECLARE_PCI_FIXUP_SECTION(.pci_fixup_enable, \ DECLARE_PCI_FIXUP_SECTION(.pci_fixup_enable, \
vendor##device##hook, vendor, device, PCI_ANY_ID, 0, hook) hook, vendor, device, PCI_ANY_ID, 0, hook)
#define DECLARE_PCI_FIXUP_RESUME(vendor, device, hook) \ #define DECLARE_PCI_FIXUP_RESUME(vendor, device, hook) \
DECLARE_PCI_FIXUP_SECTION(.pci_fixup_resume, \ DECLARE_PCI_FIXUP_SECTION(.pci_fixup_resume, \
resume##vendor##device##hook, vendor, device, \ resume##hook, vendor, device, \
PCI_ANY_ID, 0, hook) PCI_ANY_ID, 0, hook)
#define DECLARE_PCI_FIXUP_RESUME_EARLY(vendor, device, hook) \ #define DECLARE_PCI_FIXUP_RESUME_EARLY(vendor, device, hook) \
DECLARE_PCI_FIXUP_SECTION(.pci_fixup_resume_early, \ DECLARE_PCI_FIXUP_SECTION(.pci_fixup_resume_early, \
resume_early##vendor##device##hook, vendor, device, \ resume_early##hook, vendor, device, \
PCI_ANY_ID, 0, hook) PCI_ANY_ID, 0, hook)
#define DECLARE_PCI_FIXUP_SUSPEND(vendor, device, hook) \ #define DECLARE_PCI_FIXUP_SUSPEND(vendor, device, hook) \
DECLARE_PCI_FIXUP_SECTION(.pci_fixup_suspend, \ DECLARE_PCI_FIXUP_SECTION(.pci_fixup_suspend, \
suspend##vendor##device##hook, vendor, device, \ suspend##hook, vendor, device, \
PCI_ANY_ID, 0, hook) PCI_ANY_ID, 0, hook)
#ifdef CONFIG_PCI_QUIRKS #ifdef CONFIG_PCI_QUIRKS
......
...@@ -47,6 +47,9 @@ u32 vmcoreinfo_note[VMCOREINFO_NOTE_SIZE/4]; ...@@ -47,6 +47,9 @@ u32 vmcoreinfo_note[VMCOREINFO_NOTE_SIZE/4];
size_t vmcoreinfo_size; size_t vmcoreinfo_size;
size_t vmcoreinfo_max_size = sizeof(vmcoreinfo_data); size_t vmcoreinfo_max_size = sizeof(vmcoreinfo_data);
/* Flag to indicate we are going to kexec a new kernel */
bool kexec_in_progress = false;
/* Location of the reserved area for the crash kernel */ /* Location of the reserved area for the crash kernel */
struct resource crashk_res = { struct resource crashk_res = {
.name = "Crash kernel", .name = "Crash kernel",
...@@ -1675,6 +1678,7 @@ int kernel_kexec(void) ...@@ -1675,6 +1678,7 @@ int kernel_kexec(void)
} else } else
#endif #endif
{ {
kexec_in_progress = true;
kernel_restart_prepare(NULL); kernel_restart_prepare(NULL);
printk(KERN_EMERG "Starting new kernel\n"); printk(KERN_EMERG "Starting new kernel\n");
machine_shutdown(); machine_shutdown();
......
...@@ -2851,19 +2851,6 @@ static bool start_flush_work(struct work_struct *work, struct wq_barrier *barr) ...@@ -2851,19 +2851,6 @@ static bool start_flush_work(struct work_struct *work, struct wq_barrier *barr)
return false; return false;
} }
static bool __flush_work(struct work_struct *work)
{
struct wq_barrier barr;
if (start_flush_work(work, &barr)) {
wait_for_completion(&barr.done);
destroy_work_on_stack(&barr.work);
return true;
} else {
return false;
}
}
/** /**
* flush_work - wait for a work to finish executing the last queueing instance * flush_work - wait for a work to finish executing the last queueing instance
* @work: the work to flush * @work: the work to flush
...@@ -2877,10 +2864,18 @@ static bool __flush_work(struct work_struct *work) ...@@ -2877,10 +2864,18 @@ static bool __flush_work(struct work_struct *work)
*/ */
bool flush_work(struct work_struct *work) bool flush_work(struct work_struct *work)
{ {
struct wq_barrier barr;
lock_map_acquire(&work->lockdep_map); lock_map_acquire(&work->lockdep_map);
lock_map_release(&work->lockdep_map); lock_map_release(&work->lockdep_map);
return __flush_work(work); if (start_flush_work(work, &barr)) {
wait_for_completion(&barr.done);
destroy_work_on_stack(&barr.work);
return true;
} else {
return false;
}
} }
EXPORT_SYMBOL_GPL(flush_work); EXPORT_SYMBOL_GPL(flush_work);
...@@ -4832,14 +4827,7 @@ long work_on_cpu(int cpu, long (*fn)(void *), void *arg) ...@@ -4832,14 +4827,7 @@ long work_on_cpu(int cpu, long (*fn)(void *), void *arg)
INIT_WORK_ONSTACK(&wfc.work, work_for_cpu_fn); INIT_WORK_ONSTACK(&wfc.work, work_for_cpu_fn);
schedule_work_on(cpu, &wfc.work); schedule_work_on(cpu, &wfc.work);
flush_work(&wfc.work);
/*
* The work item is on-stack and can't lead to deadlock through
* flushing. Use __flush_work() to avoid spurious lockdep warnings
* when work_on_cpu()s are nested.
*/
__flush_work(&wfc.work);
return wfc.ret; return wfc.ret;
} }
EXPORT_SYMBOL_GPL(work_on_cpu); EXPORT_SYMBOL_GPL(work_on_cpu);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment