base-files: define yes/no as valid boolean options
[openwrt.git] / target / linux / mvebu / patches-3.10 / 0072-PCI-Introduce-new-MSI-chip-infrastructure.patch
1 From 9c6ddccbbfaf789beccc6a1d87abe9bc60dc570f Mon Sep 17 00:00:00 2001
2 From: Thierry Reding <thierry.reding@avionic-design.de>
3 Date: Thu, 6 Jun 2013 18:20:29 +0200
4 Subject: [PATCH 072/203] PCI: Introduce new MSI chip infrastructure
5
6 The new struct msi_chip is used to associated an MSI controller with a
7 PCI bus. It is automatically handed down from the root to its children
8 during bus enumeration.
9
10 This patch provides default (weak) implementations for the architecture-
11 specific MSI functions (arch_setup_msi_irq(), arch_teardown_msi_irq()
12 and arch_msi_check_device()) which check if a PCI device's bus has an
13 attached MSI chip and forward the call appropriately.
14
15 Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
16 Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
17 Acked-by: Bjorn Helgaas <bhelgaas@google.com>
18 Tested-by: Daniel Price <daniel.price@gmail.com>
19 Tested-by: Thierry Reding <thierry.reding@gmail.com>
20 ---
21  drivers/pci/msi.c   | 27 +++++++++++++++++++++++++--
22  drivers/pci/probe.c |  1 +
23  include/linux/msi.h | 11 +++++++++++
24  include/linux/pci.h |  1 +
25  4 files changed, 38 insertions(+), 2 deletions(-)
26
27 --- a/drivers/pci/msi.c
28 +++ b/drivers/pci/msi.c
29 @@ -32,16 +32,39 @@ static int pci_msi_enable = 1;
30  
31  int __weak arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
32  {
33 -       return -EINVAL;
34 +       struct msi_chip *chip = dev->bus->msi;
35 +       int err;
36 +
37 +       if (!chip || !chip->setup_irq)
38 +               return -EINVAL;
39 +
40 +       err = chip->setup_irq(chip, dev, desc);
41 +       if (err < 0)
42 +               return err;
43 +
44 +       irq_set_chip_data(desc->irq, chip);
45 +
46 +       return 0;
47  }
48  
49  void __weak arch_teardown_msi_irq(unsigned int irq)
50  {
51 +       struct msi_chip *chip = irq_get_chip_data(irq);
52 +
53 +       if (!chip || !chip->teardown_irq)
54 +               return;
55 +
56 +       chip->teardown_irq(chip, irq);
57  }
58  
59  int __weak arch_msi_check_device(struct pci_dev *dev, int nvec, int type)
60  {
61 -       return 0;
62 +       struct msi_chip *chip = dev->bus->msi;
63 +
64 +       if (!chip || !chip->check_device)
65 +               return 0;
66 +
67 +       return chip->check_device(chip, dev, nvec, type);
68  }
69  
70  int __weak arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
71 --- a/drivers/pci/probe.c
72 +++ b/drivers/pci/probe.c
73 @@ -634,6 +634,7 @@ static struct pci_bus *pci_alloc_child_b
74  
75         child->parent = parent;
76         child->ops = parent->ops;
77 +       child->msi = parent->msi;
78         child->sysdata = parent->sysdata;
79         child->bus_flags = parent->bus_flags;
80  
81 --- a/include/linux/msi.h
82 +++ b/include/linux/msi.h
83 @@ -64,4 +64,15 @@ void arch_restore_msi_irqs(struct pci_de
84  void default_teardown_msi_irqs(struct pci_dev *dev);
85  void default_restore_msi_irqs(struct pci_dev *dev, int irq);
86  
87 +struct msi_chip {
88 +       struct module *owner;
89 +       struct device *dev;
90 +
91 +       int (*setup_irq)(struct msi_chip *chip, struct pci_dev *dev,
92 +                        struct msi_desc *desc);
93 +       void (*teardown_irq)(struct msi_chip *chip, unsigned int irq);
94 +       int (*check_device)(struct msi_chip *chip, struct pci_dev *dev,
95 +                           int nvec, int type);
96 +};
97 +
98  #endif /* LINUX_MSI_H */
99 --- a/include/linux/pci.h
100 +++ b/include/linux/pci.h
101 @@ -432,6 +432,7 @@ struct pci_bus {
102         struct resource busn_res;       /* bus numbers routed to this bus */
103  
104         struct pci_ops  *ops;           /* configuration access functions */
105 +       struct msi_chip *msi;           /* MSI controller */
106         void            *sysdata;       /* hook for sys-specific extension */
107         struct proc_dir_entry *procdir; /* directory entry in /proc/bus/pci */
108