* [PATCH 3/3] ARM: dts: socfpga: Enable QSPI on the Cyclone5 sockit
From: Graham Moore @ 2016-10-25 15:38 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <c62baad6-2528-a9df-6b09-3dba66785102@opensource.altera.com>
On 10/20/2016 09:12 AM, Dinh Nguyen wrote:
>
>
> On 10/20/2016 02:19 AM, Steffen Trumtrar wrote:
>
>>> + cdns,tslch-ns = <4>;
>>> +
>>> + partition at qspi-boot {
>>> + /* 8MB for raw data. */
>>> + label = "Flash 0 Raw Data";
>>> + reg = <0x0 0x800000>;
>>> + };
>>> +
>>> + partition at qspi-rootfs {
>>> + /* 120MB for jffs2 data. */
>>> + label = "Flash 0 jffs2 Filesystem";
>>> + reg = <0x800000 0x7800000>;
>>> + };
>>> + };
>>> +};
>>> +
>>
>> What is the current preferred way of handling the partitions?
>> This doesn't fit my Sockit configuration for example. So I would always
>> have to patch the devicetree.
>
> I'm not 100% sure on this. Graham, do you have any insight?
>>
Well, strictly speaking, these partitions are only for the socdk, the
Altera dev kit. Our sample designs and file systems expect this layout.
Therefore, these partitions are not required for any other dev kits, and
can probably be left out.
Or, Steffen, if you have a standard layout you'd like to see, then put
that in there.
I think some people will have to patch the layout regardless.
-Graham
^ permalink raw reply
* [PATCH] drivers: iommu: constify iommu_gather_ops structures
From: Bhumika Goyal @ 2016-10-25 15:33 UTC (permalink / raw)
To: linux-arm-kernel
Check for iommu_gather_ops structures that are only stored in the tlb
field of an io_pgtable_cfg structure. The tlb field is of type
const struct iommu_gather_ops *, so iommu_gather_ops structures
having this property can be declared as const.
Done using Coccinelle:
@r1 disable optional_qualifier @
identifier i;
position p;
@@
static struct iommu_gather_ops i at p = {...};
@ok1@
identifier r1.i;
position p;
struct io_pgtable_cfg q;
@@
q.tlb=&i at p;
@bad@
position p!={r1.p,ok1.p};
identifier r1.i;
@@
i at p
@depends on !bad disable optional_qualifier@
identifier r1.i;
@@
static
+const
struct iommu_gather_ops i={...};
@depends on !bad disable optional_qualifier@
identifier r1.i;
@@
+const
struct iommu_gather_ops i;
Signed-off-by: Bhumika Goyal <bhumirks@gmail.com>
---
drivers/iommu/io-pgtable-arm-v7s.c | 2 +-
drivers/iommu/ipmmu-vmsa.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/iommu/io-pgtable-arm-v7s.c b/drivers/iommu/io-pgtable-arm-v7s.c
index f50e51c..1465bbc 100644
--- a/drivers/iommu/io-pgtable-arm-v7s.c
+++ b/drivers/iommu/io-pgtable-arm-v7s.c
@@ -741,7 +741,7 @@ static void dummy_tlb_sync(void *cookie)
WARN_ON(cookie != cfg_cookie);
}
-static struct iommu_gather_ops dummy_tlb_ops = {
+static const struct iommu_gather_ops dummy_tlb_ops = {
.tlb_flush_all = dummy_tlb_flush_all,
.tlb_add_flush = dummy_tlb_add_flush,
.tlb_sync = dummy_tlb_sync,
diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c
index ace331d..b8bcf18 100644
--- a/drivers/iommu/ipmmu-vmsa.c
+++ b/drivers/iommu/ipmmu-vmsa.c
@@ -283,7 +283,7 @@ static void ipmmu_tlb_add_flush(unsigned long iova, size_t size,
/* The hardware doesn't support selective TLB flush. */
}
-static struct iommu_gather_ops ipmmu_gather_ops = {
+static const struct iommu_gather_ops ipmmu_gather_ops = {
.tlb_flush_all = ipmmu_tlb_flush_all,
.tlb_add_flush = ipmmu_tlb_add_flush,
.tlb_sync = ipmmu_tlb_flush_all,
--
1.9.1
^ permalink raw reply related
* [PATCH 4/9] pinctrl: meson: allow gpio to request irq
From: Jerome Brunet @ 2016-10-25 15:31 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <bbc268c8-35c3-206a-46b1-62cebef174b2@arm.com>
On Tue, 2016-10-25 at 15:47 +0100, Marc Zyngier wrote:
>?
> > > But why are those number different? Why don't you use the same
> > > namespace? If gpio == hwirq, all your problems are already
> > > solved. If
> > > you don't find the mapping in the irqdomain, then there is no
> > > irq,
> > > end
> > > of story. What am I missing?
> > >
> >
> > There is a few problems to guarantee that gpio == hwirq.
> > 1. We have 2 instances of pinctrl, to guarantee that the linux gpio
> > number == hwirq, we would have to guarantee the order in which they
> > are
> > probed. At least this my understanding?
>
> Maybe I wasn't clear enough, and my use of gpio is probably wrong. So
> Linux has a gpio number, which is obviously an abstract number (just
> like the Linux irq number). But the pad number, in the context of
> given
> SoC, is constant. So we have:
>
> pad->gpio
> hwirq->irq
>
> Why can't you have pad == hwirq, always? This is already what you
> have
> in the irqchip driver. This would simplify a lot of things.
The meson pinctrl driver is designed so that, the pad numbering (or the
equivalent), is linear within a bank. This makes the code simpler for a
lot of things in the meson-pinctrl driver (like finding the appropriate
register and bit). Because of this, and the fact that some gpio might
not have an irq, pad == hwirq cannot hold.
In addition the pad numbering starts from 0 on each gpiochip.
The solution for that is to have the first and last irq number (which
is actually the mux setting of the controller) in the data of each gpio
bank, as described in the Datasheet.
>
> >
> > 2. Inside each instance, we may have banks that can't have irq. We
> > even
> > have a bank on meson8b which has a mixed state (the last pins don't
> > have irqs, while the first ones do). those banks/pins are still
> > valid
> > gpios with gpio numbers. This introduce a shift between the gpio
> > numbering and the hwirq.
> >
> > The point of this calculation is take the offset given to the
> > 'to_irq'
> > callback, remove the gpio bank base number and add irq base number.
> > There is a few trick added to handled the case in 2.
>
> You seem to assume linear mappings, which is pretty dangerous.
That's the way the meson pinctrl driver works (linear numbering in each
banks) and the HW is described in DS. Why would it be dangerous ?
>
> >
> >
> > In addition, to call 'irq_find_mapping', we would first have to
> > create
> > the mapping, in the probe I suppose. This would call the allocate
> > callback of the domain, in which we can allocate only 8 interrupts.
> >
> > That's why I create the mapping in the .to_irq callback.
>
> Is gpio_to_irq() supposed to allocate an interrupt? Or merely to
> report
> the existence of a mapping?
Linus, please correct me if I'm wrong,
.to_irq gets the linux gpio number and returns the linux virtual irq
numbers, 0 if there is no interrupt.
So could either find or create the mapping.
A. With the hardware at hand, and the limited upstream interrupt
number, i don't see how we could create the mapping beforehand.?
>
> >
> >
> > >
> > > >
> > > >
> > > >
> > > > Even if I implement an another irqdomain at the gpio level, I
> > > > would
> > > > still have to perform this kind of calculation, one way or the
> > > > other.
> > > >
> > > > >
> > > > >
> > > > > >
> > > > > >
> > > > > > Which is problematic since quite a few GPIO drivers now
> > > > > > need to use them.
> > > > > >
> > > > > > I will review his slides, in the meantime I would say:
> > > > > > whatever
> > > > > > Marc ACKs is fine with me. I trust this guy 100%. So I
> > > > > > guess I
> > > > > > could ask that he ACK the entire chain of patches
> > > > > > from GIC->specialchip->GPIO.
> > > >
> > > > Actually this discussion go me thinking about another issue we
> > > > have
> > > > with this hardware.
> > > > We are looking for a way to implement support for
> > > > IRQ_TYPE_EDGE_BOTH
> > > > (needed for things like gpio-keys or mmc card detect).?
> > > > The controller can do each edge but not both at the same time.
> > > > I'm thinking that implementing another irqdomain at the gpio
> > > > level
> > > > would allow to properly check the pad level in the EOI callback
> > > > then
> > > > set the next expected edge type accordingly (using
> > > > 'irq_chip_set_type_parent')
> > > >
> > > > Would it be acceptable ?
> > >
> > > I really don't see what another irqdomain brings to the table.
> > > This
> > > is
> > > not a separate piece of HW, so the hwirq:irq mapping is still the
> > > same.
> > > I fail to see what the benefit is.
> >
> > The separate piece of hw is the gpio itself.?
> > The irq-controller (in irqchip) can't read the gpio state because
> > it is
> > simply another device.
> >
> > The domain I'm thinking about wouldn't do much, I reckon.?
> > It would just register an irqchip which would only implement eoi.
> > For everything else, it would rely the parent controller.
> > From your explanation, I understood this is the purpose of
> > hierarchy
> > domains, For each hw in the chain to handle only what it can, and
> > rely
> > on its parent for the rest.
>
> Right. But that doesn't make it more reliable, see below.
>
> >
> >
> > >
> > >
> > > >
> > > >
> > > > It looks a few other drivers deal with IRQ_TYPE_EDGE_BOTH in a
> > > > similar
> > > > way (gpio/gpio-omap.c, gpio/gpio-dwapb.c)
> > >
> > > Being already done doesn't make it reliable. If the line goes low
> > > between latching the rising edge and reprogramming the trigger,
> > > you've
> > > lost at least *two* interrupts (the falling edge and the
> > > following
> > > rising edge).
> >
> > If a 'usual' controller support IRQ_TYPE_EDGE_BOTH and the line
> > goes
> > low between latching rising edge and handling the interrupt,
> > wouldn't
> > you miss the falling edge anyway ? The signal is just going too
> > fast
> > the HW to handle everything.
>
> That's the role of the HW to ensure that you don't loose any
> interrupt,
> up to the sampling frequency of the controller. Doing it in SW is
> always
> going to be a wonderful case of "it mostly work".
>
> >
> > For the second rising edge, I disagree, it would not be lost, since
> > we
> > would read the pad state, get a low level, and reprogram the
> > controller
> > for another rising edge.
>
> You always have a race between checking your level and switching the
> configuration, which is likely to be slow anyway. In the meantime,
> the
> level has changed and you're dead.
>
> Anyway, I suggest you focus on getting something simple up and
> running,
> and postpone the funky (read broken) stuff for later, once you have
> something that looks vaguely sane (because we're not quite there
> yet).
>
> Thanks,
>
> M.
^ permalink raw reply
* [PATCH 4/4] PM / Domains: Use domain-idle-state compatible
From: Lina Iyer @ 2016-10-25 15:26 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1477409199-52182-1-git-send-email-lina.iyer@linaro.org>
Use the more specific "domain-idle-states" compatible property to read
idle state properties from DT.
Signed-off-by: Lina Iyer <lina.iyer@linaro.org>
---
drivers/base/power/domain.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index aac656a..07ed835 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -2048,7 +2048,7 @@ out:
EXPORT_SYMBOL_GPL(genpd_dev_pm_attach);
static const struct of_device_id idle_state_match[] = {
- { .compatible = "arm,idle-state", },
+ { .compatible = "domain-idle-state", },
{ }
};
--
2.7.4
^ permalink raw reply related
* [PATCH 3/4] dt-bindings: Update domain-idle-state binding to use correct compatibles
From: Lina Iyer @ 2016-10-25 15:26 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1477409199-52182-1-git-send-email-lina.iyer@linaro.org>
Update domain-idle-state binding to use "domain-idle-state" compatible
from Documentation/devicetree/bindings/arm/idle-states.txt.
Cc: <devicetree@vger.kernel.org>
Cc: Rob Herring <robh@kernel.org>
Suggested-by: Sudeep Holla <sudeep.holla@arm.com>
Signed-off-by: Lina Iyer <lina.iyer@linaro.org>
---
Documentation/devicetree/bindings/power/power_domain.txt | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/Documentation/devicetree/bindings/power/power_domain.txt b/Documentation/devicetree/bindings/power/power_domain.txt
index e165036..6fb53a3 100644
--- a/Documentation/devicetree/bindings/power/power_domain.txt
+++ b/Documentation/devicetree/bindings/power/power_domain.txt
@@ -30,8 +30,9 @@ Optional properties:
available in the next section.
- domain-idle-states : A phandle of an idle-state that shall be soaked into a
- generic domain power state. The idle state definitions are
- compatible with arm,idle-state specified in [1].
+ generic domain power state. The idle state definitions must be
+ compatible with "domain-idle-state" as well as
+ "arm,idle-state" as defined in [1].
The domain-idle-state property reflects the idle state of this PM domain and
not the idle states of the devices or sub-domains in the PM domain. Devices
and sub-domains have their own idle-states independent of the parent
@@ -85,7 +86,7 @@ Example 3:
};
DOMAIN_RET: state at 0 {
- compatible = "arm,idle-state";
+ compatible = "domain-idle-state", "arm,idle-state";
reg = <0x0>;
entry-latency-us = <1000>;
exit-latency-us = <2000>;
@@ -93,7 +94,7 @@ Example 3:
};
DOMAIN_PWR_DN: state at 1 {
- compatible = "arm,idle-state";
+ compatible = "domain-idle-state", "arm,idle-state";
reg = <0x1>;
entry-latency-us = <5000>;
exit-latency-us = <8000>;
--
2.7.4
^ permalink raw reply related
* [PATCH 2/4] dt-bindings: add domain-idle-state compatible to arm, idle-state
From: Lina Iyer @ 2016-10-25 15:26 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1477409199-52182-1-git-send-email-lina.iyer@linaro.org>
CPU's idle states are defined by the arm,idle-state compatible flag. PM
domains that can contains devices and other domains also has similar
definition for its idle state. Reuse the definition of arm,idle-state
for PM domains by allowing an addition compatible string
("domain-idle-state") to denote idle states that are specific to PM
Domains.
Cc: <devicetree@vger.kernel.org>
Cc: Rob Herring <robh@kernel.org>
Suggested-by: Sudeep Holla <sudeep.holla@arm.com>
Signed-off-by: Lina Iyer <lina.iyer@linaro.org>
---
Documentation/devicetree/bindings/arm/idle-states.txt | 3 +++
1 file changed, 3 insertions(+)
diff --git a/Documentation/devicetree/bindings/arm/idle-states.txt b/Documentation/devicetree/bindings/arm/idle-states.txt
index b8e41c1..4b0ff59 100644
--- a/Documentation/devicetree/bindings/arm/idle-states.txt
+++ b/Documentation/devicetree/bindings/arm/idle-states.txt
@@ -271,6 +271,9 @@ follows:
Usage: Required
Value type: <stringlist>
Definition: Must be "arm,idle-state".
+ Additionally, nodes that are used to describe a
+ idle-state of PM domain must also define
+ "domain-idle-state" as compatible string.
- local-timer-stop
Usage: See definition
--
2.7.4
^ permalink raw reply related
* [PATCH 1/4] PM / doc: Update device documentation for devices in IRQ safe PM domains
From: Lina Iyer @ 2016-10-25 15:26 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1477409199-52182-1-git-send-email-lina.iyer@linaro.org>
Update documentation to reflect the changes made to support IRQ safe PM
domains.
Signed-off-by: Lina Iyer <lina.iyer@linaro.org>
Signed-off-by: Rafael J. Wysocki <rjw@rjwysocki.net>
---
Documentation/power/devices.txt | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/Documentation/power/devices.txt b/Documentation/power/devices.txt
index 8ba6625..73ddea3 100644
--- a/Documentation/power/devices.txt
+++ b/Documentation/power/devices.txt
@@ -607,7 +607,9 @@ individually. Instead, a set of devices sharing a power resource can be put
into a low-power state together at the same time by turning off the shared
power resource. Of course, they also need to be put into the full-power state
together, by turning the shared power resource on. A set of devices with this
-property is often referred to as a power domain.
+property is often referred to as a power domain. A power domain may also be
+nested inside another power domain. The nested domain is referred to as the
+sub-domain of the parent domain.
Support for power domains is provided through the pm_domain field of struct
device. This field is a pointer to an object of type struct dev_pm_domain,
@@ -629,6 +631,16 @@ support for power domains into subsystem-level callbacks, for example by
modifying the platform bus type. Other platforms need not implement it or take
it into account in any way.
+Devices may be defined as IRQ-safe which indicates to the PM core that their
+runtime PM callbacks may be invoked with disabled interrupts (see
+Documentation/power/runtime_pm.txt for more information). If an IRQ-safe
+device belongs to a PM domain, the runtime PM of the domain will be
+disallowed, unless the domain itself is defined as IRQ-safe. However, it
+makes sense to define a PM domain as IRQ-safe only if all the devices in it
+are IRQ-safe. Moreover, if an IRQ-safe domain has a parent domain, the runtime
+PM of the parent is only allowed if the parent itself is IRQ-safe too with the
+additional restriction that all child domains of an IRQ-safe parent must also
+be IRQ-safe.
Device Low Power (suspend) States
---------------------------------
--
2.7.4
^ permalink raw reply related
* [PATCH 0/4] PM / Domains: DT bindings for domain idle states and doc updates
From: Lina Iyer @ 2016-10-25 15:26 UTC (permalink / raw)
To: linux-arm-kernel
Hi Rafael,
This patchset adds the following on top of the patches [0-7] of v3[1], that you
have already queued up for linux-next.
- New DT compatible for PM Domain idle states.
- Update documentation for PM domain idle state
(Pls. note that this new compatible is yet to be approved by DT reviewers)
- Update device/domain documentation per your suggestion
Thanks,
Lina
[1]. http://www.spinics.net/lists/arm-kernel/msg536181.html
Lina Iyer (4):
PM / doc: Update device documentation for devices in IRQ safe PM
domains
dt-bindings: add domain-idle-state compatible to arm,idle-state
dt-bindings: Update domain-idle-state binding to use correct
compatibles
PM / Domains: Use domain-idle-state compatible
Documentation/devicetree/bindings/arm/idle-states.txt | 3 +++
Documentation/devicetree/bindings/power/power_domain.txt | 9 +++++----
Documentation/power/devices.txt | 14 +++++++++++++-
drivers/base/power/domain.c | 2 +-
4 files changed, 22 insertions(+), 6 deletions(-)
--
2.7.4
^ permalink raw reply
* [PATCH 1/2] iommu/arm-smmu: Don't inadvertently reject multiple SMMUv3s
From: Hanjun Guo @ 2016-10-25 15:25 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <5cf1acbf9c42cc99e5cc0dacb50b7a92c3bd0feb.1476702234.git.robin.murphy@arm.com>
On 2016/10/17 19:06, Robin Murphy wrote:
> We now delay installing our per-bus iommu_ops until we know an SMMU has
> successfully probed, as they don't serve much purpose beforehand, and
> doing so also avoids fights between multiple IOMMU drivers in a single
> kernel. However, the upshot of passing the return value of bus_set_iommu()
> back from our probe function is that if there happens to be more than
> one SMMUv3 device in a system, the second and subsequent probes will
> wind up returning -EBUSY to the driver core and getting torn down again.
>
> There are essentially 3 cases in which bus_set_iommu() returns nonzero:
> 1. The bus already has iommu_ops installed
> 2. One of the add_device callbacks from the initial notifier failed
> 3. Allocating or installing the notifier itself failed
>
> The first two are down to devices other than the SMMU in question, so
> shouldn't abort an otherwise-successful SMMU probe, whilst the third is
> indicative of the kind of catastrophic system failure which isn't going
> to get much further anyway. Consequently, there is little harm in
> ignoring the return value either way.
>
> CC: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> Signed-off-by: Robin Murphy <robin.murphy@arm.com>
Tested-by: Hanjun Guo <hanjun.guo@linaro.org>
Thanks
Hanjun
^ permalink raw reply
* [PATCH v6 00/16] ACPI IORT ARM SMMU support
From: Hanjun Guo @ 2016-10-25 15:24 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161018160414.1228-1-lorenzo.pieralisi@arm.com>
On 2016/10/19 0:03, Lorenzo Pieralisi wrote:
> This patch series is v6 of a previous posting:
>
> https://lkml.org/lkml/2016/9/9/418
>
> v5 -> v6
> - Rebased against v4.9-rc1
> - Changed FWNODE_IOMMU to FWNODE_ACPI_STATIC
> - Moved platform devices creation into IORT code
> - Updated fwnode handling
> - Added default dma masks initialization
>
> v4 -> v5
> - Added SMMUv1/v2 support
> - Rebased against v4.8-rc5 and dependencies series
> - Consolidated IORT platform devices creation
>
[...]
>
> The ACPI IORT table provides information that allows instantiating
> ARM SMMU devices and carrying out id mappings between components on
> ARM based systems (devices, IOMMUs, interrupt controllers).
>
> http://infocenter.arm.com/help/topic/com.arm.doc.den0049b/DEN0049B_IO_Remapping_Table.pdf
>
> Building on basic IORT support, this patchset enables ARM SMMUs support
> on ACPI systems.
>
> Most of the code is aimed at building the required generic ACPI
> infrastructure to create and enable IOMMU components and to bring
> the IOMMU infrastructure for ACPI on par with DT, which is going to
> make future ARM SMMU components easier to integrate.
>
[...]
>
> This patchset is provided for review/testing purposes here:
>
> git://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/linux.git acpi/iort-smmu-v6
>
> Tested on Juno and FVP models for ARM SMMU v1 and v3 probing path.
I rebased my platform MSI, interrupt producer and mbi-gen patch set
on top of yours, and test it on Hisilicon D03 board with SMMv3
enabled, USB and SAS are working properly with configuration
in IORT (yes, I need to add patch from Robin - iommu/arm-smmu: Don't
inadvertently reject multiple SMMUv3s),
Tested-by: Hanjun Guo <hanjun.guo@linaro.org>
Thanks
Hanjun
^ permalink raw reply
* [PATCH v3 14/14] irqchip: mbigen: Add ACPI support
From: Hanjun Guo @ 2016-10-25 15:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1477408169-22217-1-git-send-email-guohanjun@huawei.com>
From: Hanjun Guo <hanjun.guo@linaro.org>
With the preparation of platform msi support and interrupt producer
in DSDT, we can add mbigen ACPI support now.
We are using _PRS methd to indicate number of irq pins instead
of num_pins in DT to avoid _DSD usage in this case.
For mbi-gen,
Device(MBI0) {
Name(_HID, "HISI0152")
Name(_UID, Zero)
Name(_CRS, ResourceTemplate() {
Memory32Fixed(ReadWrite, 0xa0080000, 0x10000)
})
Name (_PRS, ResourceTemplate() {
Interrupt(ResourceProducer,...) {12,14,....}
})
}
For devices,
Device(COM0) {
Name(_HID, "ACPIIDxx")
Name(_UID, Zero)
Name(_CRS, ResourceTemplate() {
Memory32Fixed(ReadWrite, 0xb0030000, 0x10000)
Interrupt(ResourceConsumer,..., "\_SB.MBI0") {12}
})
}
With the helpe of platform msi and interrupt producer, then devices
will get the virq from mbi-gen's irqdomain.
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ma Jun <majun258@huawei.com>
---
drivers/irqchip/irq-mbigen.c | 70 ++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 67 insertions(+), 3 deletions(-)
diff --git a/drivers/irqchip/irq-mbigen.c b/drivers/irqchip/irq-mbigen.c
index 9484ea0..ca6add1 100644
--- a/drivers/irqchip/irq-mbigen.c
+++ b/drivers/irqchip/irq-mbigen.c
@@ -16,6 +16,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <linux/acpi.h>
#include <linux/interrupt.h>
#include <linux/irqchip.h>
#include <linux/module.h>
@@ -180,7 +181,7 @@ static int mbigen_domain_translate(struct irq_domain *d,
unsigned long *hwirq,
unsigned int *type)
{
- if (is_of_node(fwspec->fwnode)) {
+ if (is_of_node(fwspec->fwnode) || is_acpi_device_node(fwspec->fwnode)) {
if (fwspec->param_count != 2)
return -EINVAL;
@@ -271,6 +272,54 @@ static int mbigen_of_create_domain(struct platform_device *pdev,
return 0;
}
+#ifdef CONFIG_ACPI
+static acpi_status mbigen_acpi_process_resource(struct acpi_resource *ares,
+ void *context)
+{
+ struct acpi_resource_extended_irq *ext_irq;
+ u32 *num_irqs = context;
+
+ switch (ares->type) {
+ case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
+ ext_irq = &ares->data.extended_irq;
+ *num_irqs += ext_irq->interrupt_count;
+ break;
+ default:
+ break;
+ }
+
+ return AE_OK;
+}
+
+static int mbigen_acpi_create_domain(struct platform_device *pdev,
+ struct mbigen_device *mgn_chip)
+{
+ struct irq_domain *domain;
+ u32 num_msis = 0;
+ acpi_status status;
+
+ status = acpi_walk_resources(ACPI_HANDLE(&pdev->dev), METHOD_NAME__PRS,
+ mbigen_acpi_process_resource, &num_msis);
+ if (ACPI_FAILURE(status) || num_msis == 0)
+ return -EINVAL;
+
+ domain = platform_msi_create_device_domain(&pdev->dev, num_msis,
+ mbigen_write_msg,
+ &mbigen_domain_ops,
+ mgn_chip);
+ if (!domain)
+ return -ENOMEM;
+
+ return 0;
+}
+#else
+static int mbigen_acpi_create_domain(struct platform_device *pdev,
+ struct mbigen_device *mgn_chip)
+{
+ return -ENODEV;
+}
+#endif
+
static int mbigen_device_probe(struct platform_device *pdev)
{
struct mbigen_device *mgn_chip;
@@ -288,9 +337,17 @@ static int mbigen_device_probe(struct platform_device *pdev)
if (IS_ERR(mgn_chip->base))
return PTR_ERR(mgn_chip->base);
- err = mbigen_of_create_domain(pdev, mgn_chip);
- if (err)
+ if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node)
+ err = mbigen_of_create_domain(pdev, mgn_chip);
+ else if (ACPI_COMPANION(&pdev->dev))
+ err = mbigen_acpi_create_domain(pdev, mgn_chip);
+ else
+ err = -EINVAL;
+
+ if (err) {
+ dev_err(&pdev->dev, "Failed to create mbi-gen@%p irqdomain", mgn_chip->base);
return err;
+ }
platform_set_drvdata(pdev, mgn_chip);
return 0;
@@ -302,10 +359,17 @@ static int mbigen_device_probe(struct platform_device *pdev)
};
MODULE_DEVICE_TABLE(of, mbigen_of_match);
+static const struct acpi_device_id mbigen_acpi_match[] = {
+ { "HISI0152", 0 },
+ {}
+};
+MODULE_DEVICE_TABLE(acpi, mbigen_acpi_match);
+
static struct platform_driver mbigen_platform_driver = {
.driver = {
.name = "Hisilicon MBIGEN-V2",
.of_match_table = mbigen_of_match,
+ .acpi_match_table = ACPI_PTR(mbigen_acpi_match),
},
.probe = mbigen_device_probe,
};
--
1.7.12.4
^ permalink raw reply related
* [PATCH v3 13/14] irqchip: mbigen: introduce mbigen_of_create_domain()
From: Hanjun Guo @ 2016-10-25 15:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1477408169-22217-1-git-send-email-guohanjun@huawei.com>
From: Kefeng Wang <wangkefeng.wang@huawei.com>
Introduce mbigen_of_create_domain() to consolidate OF related
code and prepare for ACPI later.
Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ma Jun <majun258@huawei.com>
---
drivers/irqchip/irq-mbigen.c | 42 +++++++++++++++++++++++++++---------------
1 file changed, 27 insertions(+), 15 deletions(-)
diff --git a/drivers/irqchip/irq-mbigen.c b/drivers/irqchip/irq-mbigen.c
index c01ab41..9484ea0 100644
--- a/drivers/irqchip/irq-mbigen.c
+++ b/drivers/irqchip/irq-mbigen.c
@@ -236,27 +236,15 @@ static int mbigen_irq_domain_alloc(struct irq_domain *domain,
.free = irq_domain_free_irqs_common,
};
-static int mbigen_device_probe(struct platform_device *pdev)
+static int mbigen_of_create_domain(struct platform_device *pdev,
+ struct mbigen_device *mgn_chip)
{
- struct mbigen_device *mgn_chip;
+ struct device *parent;
struct platform_device *child;
struct irq_domain *domain;
struct device_node *np;
- struct device *parent;
- struct resource *res;
u32 num_pins;
- mgn_chip = devm_kzalloc(&pdev->dev, sizeof(*mgn_chip), GFP_KERNEL);
- if (!mgn_chip)
- return -ENOMEM;
-
- mgn_chip->pdev = pdev;
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- mgn_chip->base = devm_ioremap_resource(&pdev->dev, res);
- if (IS_ERR(mgn_chip->base))
- return PTR_ERR(mgn_chip->base);
-
for_each_child_of_node(pdev->dev.of_node, np) {
if (!of_property_read_bool(np, "interrupt-controller"))
continue;
@@ -280,6 +268,30 @@ static int mbigen_device_probe(struct platform_device *pdev)
return -ENOMEM;
}
+ return 0;
+}
+
+static int mbigen_device_probe(struct platform_device *pdev)
+{
+ struct mbigen_device *mgn_chip;
+ struct resource *res;
+ int err;
+
+ mgn_chip = devm_kzalloc(&pdev->dev, sizeof(*mgn_chip), GFP_KERNEL);
+ if (!mgn_chip)
+ return -ENOMEM;
+
+ mgn_chip->pdev = pdev;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ mgn_chip->base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(mgn_chip->base))
+ return PTR_ERR(mgn_chip->base);
+
+ err = mbigen_of_create_domain(pdev, mgn_chip);
+ if (err)
+ return err;
+
platform_set_drvdata(pdev, mgn_chip);
return 0;
}
--
1.7.12.4
^ permalink raw reply related
* [PATCH v3 12/14] irqchip: mbigen: drop module owner
From: Hanjun Guo @ 2016-10-25 15:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1477408169-22217-1-git-send-email-guohanjun@huawei.com>
From: Kefeng Wang <wangkefeng.wang@huawei.com>
Module owner will be set by driver core, so drop it.
Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ma Jun <majun258@huawei.com>
---
drivers/irqchip/irq-mbigen.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/drivers/irqchip/irq-mbigen.c b/drivers/irqchip/irq-mbigen.c
index 03b79b0..c01ab41 100644
--- a/drivers/irqchip/irq-mbigen.c
+++ b/drivers/irqchip/irq-mbigen.c
@@ -293,7 +293,6 @@ static int mbigen_device_probe(struct platform_device *pdev)
static struct platform_driver mbigen_platform_driver = {
.driver = {
.name = "Hisilicon MBIGEN-V2",
- .owner = THIS_MODULE,
.of_match_table = mbigen_of_match,
},
.probe = mbigen_device_probe,
--
1.7.12.4
^ permalink raw reply related
* [PATCH v3 11/14] ACPI: irq: introduce interrupt producer
From: Hanjun Guo @ 2016-10-25 15:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1477408169-22217-1-git-send-email-guohanjun@huawei.com>
From: Hanjun Guo <hanjun.guo@linaro.org>
In ACPI 6.1 spec, section 19.6.62, Interrupt Resource Descriptor Macro,
Interrupt (ResourceUsage, EdgeLevel, ActiveLevel, Shared,
ResourceSourceIndex, ResourceSource, DescriptorName)
{ InterruptList } => Buffer
For the arguement ResourceUsage and DescriptorName, which means:
ResourceUsage describes whether the device consumes the specified
interrupt ( ResourceConsumer ) or produces it for use by a child
device ( ResourceProducer ).
If nothing is specified, then ResourceConsumer is assumed.
DescriptorName evaluates to a name string which refers to the
entire resource descriptor.
So it can be used for devices connecting to a specific interrupt
prodcucer instead of the main interrupt controller in MADT. In the
real world, we have irqchip such as mbi-gen which connecting to
a group of wired interrupts and then issue msi to the ITS, devices
connecting to such interrupt controller fit this scope.
For now the irq for ACPI only pointer to the main interrupt
controller's irqdomain, for devices not connecting to those
irqdomains, which need to present its irq parent, we can use
following ASL code to represent it:
Interrupt(ResourceConsumer,..., "\_SB.IRQP") {12,14,....}
then we can parse the interrupt producer with the full
path name "\_SB.IRQP".
In order to do that, we introduce a pointer interrupt_producer
in struct acpi_device, and fill it when scanning irq resources
for acpi device if it specifies the interrupt producer.
But for now when parsing the resources for acpi devices, we don't
pass the acpi device for acpi_walk_resoures() in drivers/acpi/resource.c,
so introduce a adev in struct res_proc_context to pass it as a context
to scan the interrupt resources, then finally pass to acpi_register_gsi()
to find its interrupt producer to get the virq from diffrent domains.
With steps above ready, rework acpi_register_gsi() to get other
interrupt producer if devices not connecting to main interrupt
controller.
Since we often pass NULL to acpi_register_gsi() and there is no interrupt
producer for devices connect to gicd on ARM or io-apic on X86, so it will
use the default irqdomain for those deivces and no functional changes to
those devices.
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
Cc: Rafael J. Wysocki <rjw@rjwysocki.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Agustin Vega-Frias <agustinv@codeaurora.org>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
---
drivers/acpi/gsi.c | 10 ++++--
drivers/acpi/resource.c | 85 ++++++++++++++++++++++++++++++++++---------------
include/acpi/acpi_bus.h | 1 +
3 files changed, 68 insertions(+), 28 deletions(-)
diff --git a/drivers/acpi/gsi.c b/drivers/acpi/gsi.c
index ee9e0f2..29ee547 100644
--- a/drivers/acpi/gsi.c
+++ b/drivers/acpi/gsi.c
@@ -55,13 +55,19 @@ int acpi_register_gsi(struct device *dev, u32 gsi, int trigger,
int polarity)
{
struct irq_fwspec fwspec;
+ struct acpi_device *adev = dev ? to_acpi_device(dev) : NULL;
- if (WARN_ON(!acpi_gsi_domain_id)) {
+ if (adev && &adev->fwnode && adev->interrupt_producer)
+ /* devices in DSDT connecting to spefic interrupt producer */
+ fwspec.fwnode = adev->interrupt_producer;
+ else if (acpi_gsi_domain_id)
+ /* devices connecting to gicd in default */
+ fwspec.fwnode = acpi_gsi_domain_id;
+ else {
pr_warn("GSI: No registered irqchip, giving up\n");
return -EINVAL;
}
- fwspec.fwnode = acpi_gsi_domain_id;
fwspec.param[0] = gsi;
fwspec.param[1] = acpi_dev_get_irq_type(trigger, polarity);
fwspec.param_count = 2;
diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c
index 56241eb..f1371cf 100644
--- a/drivers/acpi/resource.c
+++ b/drivers/acpi/resource.c
@@ -381,7 +381,7 @@ static void acpi_dev_irqresource_disabled(struct resource *res, u32 gsi)
res->flags = IORESOURCE_IRQ | IORESOURCE_DISABLED | IORESOURCE_UNSET;
}
-static void acpi_dev_get_irqresource(struct resource *res, u32 gsi,
+static void acpi_dev_get_irqresource(struct acpi_device *adev, struct resource *res, u32 gsi,
u8 triggering, u8 polarity, u8 shareable,
bool legacy)
{
@@ -415,7 +415,7 @@ static void acpi_dev_get_irqresource(struct resource *res, u32 gsi,
}
res->flags = acpi_dev_irq_flags(triggering, polarity, shareable);
- irq = acpi_register_gsi(NULL, gsi, triggering, polarity);
+ irq = acpi_register_gsi(&adev->dev, gsi, triggering, polarity);
if (irq >= 0) {
res->start = irq;
res->end = irq;
@@ -424,27 +424,9 @@ static void acpi_dev_get_irqresource(struct resource *res, u32 gsi,
}
}
-/**
- * acpi_dev_resource_interrupt - Extract ACPI interrupt resource information.
- * @ares: Input ACPI resource object.
- * @index: Index into the array of GSIs represented by the resource.
- * @res: Output generic resource object.
- *
- * Check if the given ACPI resource object represents an interrupt resource
- * and @index does not exceed the resource's interrupt count (true is returned
- * in that case regardless of the results of the other checks)). If that's the
- * case, register the GSI corresponding to @index from the array of interrupts
- * represented by the resource and populate the generic resource object pointed
- * to by @res accordingly. If the registration of the GSI is not successful,
- * IORESOURCE_DISABLED will be set it that object's flags.
- *
- * Return:
- * 1) false with res->flags setting to zero: not the expected resource type
- * 2) false with IORESOURCE_DISABLED in res->flags: valid unassigned resource
- * 3) true: valid assigned resource
- */
-bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index,
- struct resource *res)
+static bool __acpi_dev_resource_interrupt(struct acpi_device *adev,
+ struct acpi_resource *ares, int index,
+ struct resource *res)
{
struct acpi_resource_irq *irq;
struct acpi_resource_extended_irq *ext_irq;
@@ -460,7 +442,7 @@ bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index,
acpi_dev_irqresource_disabled(res, 0);
return false;
}
- acpi_dev_get_irqresource(res, irq->interrupts[index],
+ acpi_dev_get_irqresource(adev, res, irq->interrupts[index],
irq->triggering, irq->polarity,
irq->sharable, true);
break;
@@ -470,7 +452,31 @@ bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index,
acpi_dev_irqresource_disabled(res, 0);
return false;
}
- acpi_dev_get_irqresource(res, ext_irq->interrupts[index],
+
+ /*
+ * It's a interrupt consumer device and connecting to specfic
+ * interrupt controller. For now, we only support connecting
+ * interrupts to one irq controller for a single device
+ */
+ if (ext_irq->producer_consumer == ACPI_CONSUMER
+ && ext_irq->resource_source.string_length != 0
+ && !adev->interrupt_producer) {
+ acpi_status status;
+ acpi_handle handle;
+ struct acpi_device *device;
+
+ status = acpi_get_handle(NULL, ext_irq->resource_source.string_ptr, &handle);
+ if (ACPI_FAILURE(status))
+ return false;
+
+ device = acpi_bus_get_acpi_device(handle);
+ if (!device)
+ return false;
+
+ adev->interrupt_producer = &device->fwnode;
+ }
+
+ acpi_dev_get_irqresource(adev, res, ext_irq->interrupts[index],
ext_irq->triggering, ext_irq->polarity,
ext_irq->sharable, false);
break;
@@ -481,6 +487,31 @@ bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index,
return true;
}
+
+/**
+ * acpi_dev_resource_interrupt - Extract ACPI interrupt resource information.
+ * @ares: Input ACPI resource object.
+ * @index: Index into the array of GSIs represented by the resource.
+ * @res: Output generic resource object.
+ *
+ * Check if the given ACPI resource object represents an interrupt resource
+ * and @index does not exceed the resource's interrupt count (true is returned
+ * in that case regardless of the results of the other checks)). If that's the
+ * case, register the GSI corresponding to @index from the array of interrupts
+ * represented by the resource and populate the generic resource object pointed
+ * to by @res accordingly. If the registration of the GSI is not successful,
+ * IORESOURCE_DISABLED will be set it that object's flags.
+ *
+ * Return:
+ * 1) false with res->flags setting to zero: not the expected resource type
+ * 2) false with IORESOURCE_DISABLED in res->flags: valid unassigned resource
+ * 3) true: valid assigned resource
+ */
+bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index,
+ struct resource *res)
+{
+ return __acpi_dev_resource_interrupt(NULL, ares, index, res);
+}
EXPORT_SYMBOL_GPL(acpi_dev_resource_interrupt);
/**
@@ -499,6 +530,7 @@ struct res_proc_context {
void *preproc_data;
int count;
int error;
+ struct acpi_device *adev;
};
static acpi_status acpi_dev_new_resource_entry(struct resource_win *win,
@@ -546,7 +578,7 @@ static acpi_status acpi_dev_process_resource(struct acpi_resource *ares,
|| acpi_dev_resource_ext_address_space(ares, &win))
return acpi_dev_new_resource_entry(&win, c);
- for (i = 0; acpi_dev_resource_interrupt(ares, i, res); i++) {
+ for (i = 0; __acpi_dev_resource_interrupt(c->adev, ares, i, res); i++) {
acpi_status status;
status = acpi_dev_new_resource_entry(&win, c);
@@ -599,6 +631,7 @@ int acpi_dev_get_resources(struct acpi_device *adev, struct list_head *list,
c.preproc_data = preproc_data;
c.count = 0;
c.error = 0;
+ c.adev = adev;
status = acpi_walk_resources(adev->handle, METHOD_NAME__CRS,
acpi_dev_process_resource, &c);
if (ACPI_FAILURE(status)) {
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index 4242c31..5410d3b 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -355,6 +355,7 @@ struct acpi_device {
int device_type;
acpi_handle handle; /* no handle for fixed hardware */
struct fwnode_handle fwnode;
+ struct fwnode_handle *interrupt_producer;
struct acpi_device *parent;
struct list_head children;
struct list_head node;
--
1.7.12.4
^ permalink raw reply related
* [PATCH v3 10/14] msi: platform: make platform_msi_create_device_domain() ACPI aware
From: Hanjun Guo @ 2016-10-25 15:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1477408169-22217-1-git-send-email-guohanjun@huawei.com>
From: Hanjun Guo <hanjun.guo@linaro.org>
With the platform msi domain created for ITS, irqchip such as
mbi-gen connecting ITS, which needs ctreate its own irqdomain.
Fortunately with the platform msi support upstreamed by Marc,
we just need to add minor code to make it run properly.
platform_msi_create_device_domain() is almost ready for ACPI use
except of_node_to_fwnode() is for dt only, make it ACPI aware then
things will work in both DTS and ACPI.
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Greg KH <gregkh@linuxfoundation.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Greg KH <gregkh@linuxfoundation.org>
---
drivers/base/platform-msi.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/base/platform-msi.c b/drivers/base/platform-msi.c
index be6a599..035ca3b 100644
--- a/drivers/base/platform-msi.c
+++ b/drivers/base/platform-msi.c
@@ -345,8 +345,7 @@ struct irq_domain *
data->host_data = host_data;
domain = irq_domain_create_hierarchy(dev->msi_domain, 0, nvec,
- of_node_to_fwnode(dev->of_node),
- ops, data);
+ dev->fwnode, ops, data);
if (!domain)
goto free_priv;
--
1.7.12.4
^ permalink raw reply related
* [PATCH v3 09/14] ACPI: platform: setup MSI domain for ACPI based platform device
From: Hanjun Guo @ 2016-10-25 15:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1477408169-22217-1-git-send-email-guohanjun@huawei.com>
From: Hanjun Guo <hanjun.guo@linaro.org>
With the platform msi domain created, we can set up the msi domain
for a platform device when it's probed.
In order to do that, we need to get the domain that the platform
device connecting to, so the iort_get_platform_device_domain() is
introduced to retrieve the domain from iort.
After the domain is retrieved, we need a proper way to set the
domain to paltform device, as some platform devices such as an
irqchip needs the msi irqdomain to be the interrupt parent domain,
we need to get irqdomain before platform device is probed but after
the platform device is allocated, so introduce a callback (pre_add_cb)
in pdevinfo to prepare firmware related information which is needed
for device probe, then set the msi domain in that callback.
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Rafael J. Wysocki <rjw@rjwysocki.net>
Cc: Greg KH <gregkh@linuxfoundation.org>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
---
drivers/acpi/acpi_platform.c | 11 +++++++++++
drivers/acpi/arm64/iort.c | 43 +++++++++++++++++++++++++++++++++++++++++
drivers/base/platform.c | 3 +++
include/linux/acpi_iort.h | 3 +++
include/linux/platform_device.h | 3 +++
5 files changed, 63 insertions(+)
diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c
index b200ae1..13d0bf8 100644
--- a/drivers/acpi/acpi_platform.c
+++ b/drivers/acpi/acpi_platform.c
@@ -12,6 +12,7 @@
*/
#include <linux/acpi.h>
+#include <linux/acpi_iort.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/kernel.h>
@@ -48,6 +49,15 @@ static void acpi_platform_fill_resource(struct acpi_device *adev,
}
/**
+ * acpi_platform_pre_add_cb - callback before platform device is added, to
+ * prepare firmware related information which is needed for device probe
+ */
+static void acpi_platform_pre_add_cb(struct device *dev)
+{
+ acpi_configure_pmsi_domain(dev);
+}
+
+/**
* acpi_create_platform_device - Create platform device for ACPI device node
* @adev: ACPI device node to create a platform device for.
*
@@ -106,6 +116,7 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev)
pdevinfo.res = resources;
pdevinfo.num_res = count;
pdevinfo.fwnode = acpi_fwnode_handle(adev);
+ pdevinfo.pre_add_cb = acpi_platform_pre_add_cb;
if (acpi_dma_supported(adev))
pdevinfo.dma_mask = DMA_BIT_MASK(32);
diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index 2881108..fd6eb65 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -527,6 +527,49 @@ struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_id)
return irq_find_matching_fwnode(handle, DOMAIN_BUS_PCI_MSI);
}
+/**
+ * iort_get_platform_device_domain() - Find MSI domain related to a
+ * platform device
+ * @dev: the dev pointer associated with the platform device
+ *
+ * Returns: the MSI domain for this device, NULL otherwise
+ */
+static struct irq_domain *iort_get_platform_device_domain(struct device *dev)
+{
+ struct acpi_iort_node *node, *msi_parent;
+ struct fwnode_handle *iort_fwnode;
+ struct acpi_iort_its_group *its;
+
+ /* find its associated iort node */
+ node = iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT,
+ iort_match_node_callback, dev);
+ if (!node)
+ return NULL;
+
+ /* then find its msi parent node */
+ msi_parent = iort_node_get_id(node, NULL, IORT_MSI_TYPE, 0);
+ if (!msi_parent)
+ return NULL;
+
+ /* Move to ITS specific data */
+ its = (struct acpi_iort_its_group *)msi_parent->node_data;
+
+ iort_fwnode = iort_find_domain_token(its->identifiers[0]);
+ if (!iort_fwnode)
+ return NULL;
+
+ return irq_find_matching_fwnode(iort_fwnode, DOMAIN_BUS_PLATFORM_MSI);
+}
+
+void acpi_configure_pmsi_domain(struct device *dev)
+{
+ struct irq_domain *msi_domain;
+
+ msi_domain = iort_get_platform_device_domain(dev);
+ if (msi_domain)
+ dev_set_msi_domain(dev, msi_domain);
+}
+
static int __get_pci_rid(struct pci_dev *pdev, u16 alias, void *data)
{
u32 *rid = data;
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index c4af003..3e68f31 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -537,6 +537,9 @@ struct platform_device *platform_device_register_full(
goto err;
}
+ if (pdevinfo->pre_add_cb)
+ pdevinfo->pre_add_cb(&pdev->dev);
+
ret = platform_device_add(pdev);
if (ret) {
err:
diff --git a/include/linux/acpi_iort.h b/include/linux/acpi_iort.h
index 3f717cc..21e33b6 100644
--- a/include/linux/acpi_iort.h
+++ b/include/linux/acpi_iort.h
@@ -37,6 +37,7 @@
struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_id);
/* IOMMU interface */
const struct iommu_ops *iort_iommu_configure(struct device *dev);
+void acpi_configure_pmsi_domain(struct device *dev);
#else
static inline void acpi_iort_init(void) { }
static inline bool iort_node_match(u8 type) { return false; }
@@ -56,6 +57,8 @@ static inline int iort_pmsi_get_dev_id(struct device *dev, u32 *dev_id)
static inline
const struct iommu_ops *iort_iommu_configure(struct device *dev)
{ return NULL; }
+
+static inline void acpi_configure_pmsi_domain(struct device *dev) { }
#endif
#define IORT_ACPI_DECLARE(name, table_id, fn) \
diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
index 98c2a7c..280d366fb 100644
--- a/include/linux/platform_device.h
+++ b/include/linux/platform_device.h
@@ -74,6 +74,9 @@ struct platform_device_info {
u64 dma_mask;
struct property_entry *properties;
+
+ /* preparation callback before the platform device is added */
+ void (*pre_add_cb)(struct device *);
};
extern struct platform_device *platform_device_register_full(
const struct platform_device_info *pdevinfo);
--
1.7.12.4
^ permalink raw reply related
* [PATCH v3 08/14] ACPI: ARM64: IORT: rework iort_node_get_id()
From: Hanjun Guo @ 2016-10-25 15:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1477408169-22217-1-git-send-email-guohanjun@huawei.com>
From: Hanjun Guo <hanjun.guo@linaro.org>
iort_node_get_id() has two output, one is the mapped ids,
the other is the referenced parent node which is returned
from the function.
For now we need a API just return its parent node for
single mapping, so just update this function slightly then
reuse it later.
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Marc Zyngier <marc.zyngier@arm.com>
---
drivers/acpi/arm64/iort.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index 7d543aa..2881108 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -347,7 +347,8 @@ struct acpi_iort_node *iort_node_get_id(struct acpi_iort_node *node,
if (map[index].flags & ACPI_IORT_ID_SINGLE_MAPPING) {
if (node->type == ACPI_IORT_NODE_NAMED_COMPONENT ||
node->type == ACPI_IORT_NODE_PCI_ROOT_COMPLEX) {
- *id_out = map[index].output_base;
+ if (id_out)
+ *id_out = map[index].output_base;
return parent;
}
}
--
1.7.12.4
^ permalink raw reply related
* [PATCH v3 07/14] irqchip: gicv3-its: platform-msi: scan MADT to create platform msi domain
From: Hanjun Guo @ 2016-10-25 15:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1477408169-22217-1-git-send-email-guohanjun@huawei.com>
From: Hanjun Guo <hanjun.guo@linaro.org>
With the introduction of its_pmsi_init_one(), we can add some code
on top for ACPI support of platform MSI.
We are scanning the MADT table to get the ITS entry(ies), then use
the information to create the platform msi domain for devices connect
to it, just like the PCI MSI for ITS did.
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
Tested-by: Sinan Kaya <okaya@codeaurora.org>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Tomasz Nowicki <tn@semihalf.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
---
drivers/irqchip/irq-gic-v3-its-platform-msi.c | 36 +++++++++++++++++++++++++++
1 file changed, 36 insertions(+)
diff --git a/drivers/irqchip/irq-gic-v3-its-platform-msi.c b/drivers/irqchip/irq-gic-v3-its-platform-msi.c
index ff72704..0be0437 100644
--- a/drivers/irqchip/irq-gic-v3-its-platform-msi.c
+++ b/drivers/irqchip/irq-gic-v3-its-platform-msi.c
@@ -105,6 +105,41 @@ static int __init its_pmsi_init_one(struct fwnode_handle *fwnode,
return 0;
}
+#ifdef CONFIG_ACPI
+static int __init
+its_pmsi_parse_madt(struct acpi_subtable_header *header,
+ const unsigned long end)
+{
+ struct acpi_madt_generic_translator *its_entry;
+ struct fwnode_handle *domain_handle;
+ const char *node_name;
+ int err = -ENXIO;
+
+ its_entry = (struct acpi_madt_generic_translator *)header;
+ node_name = kasprintf(GFP_KERNEL, "ITS at 0x%lx",
+ (long)its_entry->base_address);
+ domain_handle = iort_find_domain_token(its_entry->translation_id);
+ if (!domain_handle) {
+ pr_err("%s: Unable to locate ITS domain handle\n", node_name);
+ goto out;
+ }
+
+ err = its_pmsi_init_one(domain_handle, node_name);
+
+out:
+ kfree(node_name);
+ return err;
+}
+
+static void __init its_acpi_pmsi_init(void)
+{
+ acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_TRANSLATOR,
+ its_pmsi_parse_madt, 0);
+}
+#else
+static inline void its_acpi_pmsi_init(void) { }
+#endif
+
static void __init its_pmsi_of_init(void)
{
struct device_node *np;
@@ -121,6 +156,7 @@ static void __init its_pmsi_of_init(void)
static int __init its_pmsi_init(void)
{
its_pmsi_of_init();
+ its_acpi_pmsi_init();
return 0;
}
early_initcall(its_pmsi_init);
--
1.7.12.4
^ permalink raw reply related
* [PATCH v3 06/14] irqchip: gicv3-its: platform-msi: refactor its_pmsi_init() to prepare for ACPI
From: Hanjun Guo @ 2016-10-25 15:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1477408169-22217-1-git-send-email-guohanjun@huawei.com>
From: Hanjun Guo <hanjun.guo@linaro.org>
Introduce its_pmsi_init_one() to refactor the code to isolate
ACPI&DT common code to prepare for ACPI later.
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
Tested-by: Sinan Kaya <okaya@codeaurora.org>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Tomasz Nowicki <tn@semihalf.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
---
drivers/irqchip/irq-gic-v3-its-platform-msi.c | 45 ++++++++++++++++-----------
1 file changed, 27 insertions(+), 18 deletions(-)
diff --git a/drivers/irqchip/irq-gic-v3-its-platform-msi.c b/drivers/irqchip/irq-gic-v3-its-platform-msi.c
index 16587a9..ff72704 100644
--- a/drivers/irqchip/irq-gic-v3-its-platform-msi.c
+++ b/drivers/irqchip/irq-gic-v3-its-platform-msi.c
@@ -84,34 +84,43 @@ static int its_pmsi_prepare(struct irq_domain *domain, struct device *dev,
{},
};
-static int __init its_pmsi_init(void)
+static int __init its_pmsi_init_one(struct fwnode_handle *fwnode,
+ const char *name)
{
- struct device_node *np;
struct irq_domain *parent;
+ parent = irq_find_matching_fwnode(fwnode, DOMAIN_BUS_NEXUS);
+ if (!parent || !msi_get_domain_info(parent)) {
+ pr_err("%s: unable to locate ITS domain\n", name);
+ return -ENXIO;
+ }
+
+ if (!platform_msi_create_irq_domain(fwnode, &its_pmsi_domain_info,
+ parent)) {
+ pr_err("%s: unable to create platform domain\n", name);
+ return -ENXIO;
+ }
+
+ pr_info("Platform MSI: %s domain created\n", name);
+ return 0;
+}
+
+static void __init its_pmsi_of_init(void)
+{
+ struct device_node *np;
+
for (np = of_find_matching_node(NULL, its_device_id); np;
np = of_find_matching_node(np, its_device_id)) {
if (!of_property_read_bool(np, "msi-controller"))
continue;
- parent = irq_find_matching_host(np, DOMAIN_BUS_NEXUS);
- if (!parent || !msi_get_domain_info(parent)) {
- pr_err("%s: unable to locate ITS domain\n",
- np->full_name);
- continue;
- }
-
- if (!platform_msi_create_irq_domain(of_node_to_fwnode(np),
- &its_pmsi_domain_info,
- parent)) {
- pr_err("%s: unable to create platform domain\n",
- np->full_name);
- continue;
- }
-
- pr_info("Platform MSI: %s domain created\n", np->full_name);
+ its_pmsi_init_one(of_node_to_fwnode(np), np->full_name);
}
+}
+static int __init its_pmsi_init(void)
+{
+ its_pmsi_of_init();
return 0;
}
early_initcall(its_pmsi_init);
--
1.7.12.4
^ permalink raw reply related
* [PATCH v3 05/14] ACPI: platform-msi: retrieve dev id from IORT
From: Hanjun Guo @ 2016-10-25 15:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1477408169-22217-1-git-send-email-guohanjun@huawei.com>
From: Hanjun Guo <hanjun.guo@linaro.org>
For devices connecting to ITS, it needs dev id to identify
itself, and this dev id is represented in the IORT table in
named componant node [1] for platform devices, so in this
patch we will scan the IORT to retrieve device's dev id.
Introduce iort_pmsi_get_dev_id() with pointer dev passed
in for that purpose.
[1]: https://static.docs.arm.com/den0049/b/DEN0049B_IO_Remapping_Table.pdf
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
Tested-by: Sinan Kaya <okaya@codeaurora.org>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Tomasz Nowicki <tn@semihalf.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
---
drivers/acpi/arm64/iort.c | 26 ++++++++++++++++++++++++++
drivers/irqchip/irq-gic-v3-its-platform-msi.c | 4 +++-
include/linux/acpi_iort.h | 8 ++++++++
3 files changed, 37 insertions(+), 1 deletion(-)
diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index 03bae2c..7d543aa 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -444,6 +444,32 @@ u32 iort_msi_map_rid(struct device *dev, u32 req_id)
}
/**
+ * iort_pmsi_get_dev_id() - Get the device id for a device
+ * @dev: The device for which the mapping is to be done.
+ * @dev_id: The device ID found.
+ *
+ * Returns: 0 for successful find a dev id, errors otherwise
+ */
+int iort_pmsi_get_dev_id(struct device *dev, u32 *dev_id)
+{
+ struct acpi_iort_node *node;
+
+ if (!iort_table)
+ return -ENODEV;
+
+ node = iort_find_dev_node(dev);
+ if (!node) {
+ dev_err(dev, "can't find related IORT node\n");
+ return -ENODEV;
+ }
+
+ if(!iort_node_get_id(node, dev_id, IORT_MSI_TYPE, 0))
+ return -ENODEV;
+
+ return 0;
+}
+
+/**
* iort_dev_find_its_id() - Find the ITS identifier for a device
* @dev: The device.
* @req_id: Device's Requster ID
diff --git a/drivers/irqchip/irq-gic-v3-its-platform-msi.c b/drivers/irqchip/irq-gic-v3-its-platform-msi.c
index 3c94278..16587a9 100644
--- a/drivers/irqchip/irq-gic-v3-its-platform-msi.c
+++ b/drivers/irqchip/irq-gic-v3-its-platform-msi.c
@@ -15,6 +15,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <linux/acpi_iort.h>
#include <linux/device.h>
#include <linux/msi.h>
#include <linux/of.h>
@@ -56,7 +57,8 @@ static int its_pmsi_prepare(struct irq_domain *domain, struct device *dev,
msi_info = msi_get_domain_info(domain->parent);
- ret = of_pmsi_get_dev_id(domain, dev, &dev_id);
+ ret = dev->of_node ? of_pmsi_get_dev_id(domain, dev, &dev_id) :
+ iort_pmsi_get_dev_id(dev, &dev_id);
if (ret)
return ret;
diff --git a/include/linux/acpi_iort.h b/include/linux/acpi_iort.h
index dcb2b60..3f717cc 100644
--- a/include/linux/acpi_iort.h
+++ b/include/linux/acpi_iort.h
@@ -33,6 +33,7 @@
void acpi_iort_init(void);
bool iort_node_match(u8 type);
u32 iort_msi_map_rid(struct device *dev, u32 req_id);
+int iort_pmsi_get_dev_id(struct device *dev, u32 *dev_id);
struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_id);
/* IOMMU interface */
const struct iommu_ops *iort_iommu_configure(struct device *dev);
@@ -41,9 +42,16 @@ static inline void acpi_iort_init(void) { }
static inline bool iort_node_match(u8 type) { return false; }
static inline u32 iort_msi_map_rid(struct device *dev, u32 req_id)
{ return req_id; }
+
static inline struct irq_domain *iort_get_device_domain(struct device *dev,
u32 req_id)
{ return NULL; }
+
+static inline int iort_pmsi_get_dev_id(struct device *dev, u32 *dev_id)
+{
+ return -ENODEV;
+}
+
/* IOMMU interface */
static inline
const struct iommu_ops *iort_iommu_configure(struct device *dev)
--
1.7.12.4
^ permalink raw reply related
* [PATCH v3 04/14] irqchip: gicv3-its: platform-msi: refactor its_pmsi_prepare()
From: Hanjun Guo @ 2016-10-25 15:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1477408169-22217-1-git-send-email-guohanjun@huawei.com>
From: Hanjun Guo <hanjun.guo@linaro.org>
Adding ACPI support for platform MSI, we need to retrieve the
dev id in ACPI way instead of device tree, we already have
a well formed function its_pmsi_prepare() to get the dev id
but it's OF dependent, so collect OF related code and put them
into a single function to make its_pmsi_prepare() more friendly
to ACPI later.
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
Tested-by: Sinan Kaya <okaya@codeaurora.org>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Tomasz Nowicki <tn@semihalf.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
---
drivers/irqchip/irq-gic-v3-its-platform-msi.c | 23 ++++++++++++++++-------
1 file changed, 16 insertions(+), 7 deletions(-)
diff --git a/drivers/irqchip/irq-gic-v3-its-platform-msi.c b/drivers/irqchip/irq-gic-v3-its-platform-msi.c
index 470b4aa..3c94278 100644
--- a/drivers/irqchip/irq-gic-v3-its-platform-msi.c
+++ b/drivers/irqchip/irq-gic-v3-its-platform-msi.c
@@ -24,15 +24,11 @@
.name = "ITS-pMSI",
};
-static int its_pmsi_prepare(struct irq_domain *domain, struct device *dev,
- int nvec, msi_alloc_info_t *info)
+static int of_pmsi_get_dev_id(struct irq_domain *domain, struct device *dev,
+ u32 *dev_id)
{
- struct msi_domain_info *msi_info;
- u32 dev_id;
int ret, index = 0;
- msi_info = msi_get_domain_info(domain->parent);
-
/* Suck the DeviceID out of the msi-parent property */
do {
struct of_phandle_args args;
@@ -43,11 +39,24 @@ static int its_pmsi_prepare(struct irq_domain *domain, struct device *dev,
if (args.np == irq_domain_get_of_node(domain)) {
if (WARN_ON(args.args_count != 1))
return -EINVAL;
- dev_id = args.args[0];
+ *dev_id = args.args[0];
break;
}
} while (!ret);
+ return ret;
+}
+
+static int its_pmsi_prepare(struct irq_domain *domain, struct device *dev,
+ int nvec, msi_alloc_info_t *info)
+{
+ struct msi_domain_info *msi_info;
+ u32 dev_id;
+ int ret;
+
+ msi_info = msi_get_domain_info(domain->parent);
+
+ ret = of_pmsi_get_dev_id(domain, dev, &dev_id);
if (ret)
return ret;
--
1.7.12.4
^ permalink raw reply related
* [PATCH v3 03/14] ACPI: ARM64: IORT: add missing comment for iort_dev_find_its_id()
From: Hanjun Guo @ 2016-10-25 15:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1477408169-22217-1-git-send-email-guohanjun@huawei.com>
From: Hanjun Guo <hanjun.guo@linaro.org>
We are missing req_id's comment for iort_dev_find_its_id(),
add it back.
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Tomasz Nowicki <tn@semihalf.com>
---
drivers/acpi/arm64/iort.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index ee68cfc..03bae2c 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -446,6 +446,7 @@ u32 iort_msi_map_rid(struct device *dev, u32 req_id)
/**
* iort_dev_find_its_id() - Find the ITS identifier for a device
* @dev: The device.
+ * @req_id: Device's Requster ID
* @idx: Index of the ITS identifier list.
* @its_id: ITS identifier.
*
--
1.7.12.4
^ permalink raw reply related
* [PATCH v3 02/14] irqchip: gic-v3-its: keep the head file include in alphabetic order
From: Hanjun Guo @ 2016-10-25 15:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1477408169-22217-1-git-send-email-guohanjun@huawei.com>
From: Hanjun Guo <hanjun.guo@linaro.org>
The head file is strictly in alphabetic order now, so let's
be the rule breaker. As acpi_iort.h includes acpi.h so remove
the duplidate acpi.h inclusion as well.
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Tomasz Nowicki <tn@semihalf.com>
---
drivers/irqchip/irq-gic-v3-its.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index c5dee30..1508bf4 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -15,14 +15,13 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <linux/acpi.h>
+#include <linux/acpi_iort.h>
#include <linux/bitmap.h>
#include <linux/cpu.h>
#include <linux/delay.h>
#include <linux/dma-iommu.h>
#include <linux/interrupt.h>
#include <linux/irqdomain.h>
-#include <linux/acpi_iort.h>
#include <linux/log2.h>
#include <linux/mm.h>
#include <linux/msi.h>
--
1.7.12.4
^ permalink raw reply related
* [PATCH v3 01/14] ACPI: ARM64: IORT: minor cleanup for iort_match_node_callback()
From: Hanjun Guo @ 2016-10-25 15:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1477408169-22217-1-git-send-email-guohanjun@huawei.com>
From: Hanjun Guo <hanjun.guo@linaro.org>
Cleanup iort_match_node_callback() a little bit to reduce
some lines of code, aslo fix the indentation in iort_scan_node().
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Tomasz Nowicki <tn@semihalf.com>
---
drivers/acpi/arm64/iort.c | 10 +++-------
1 file changed, 3 insertions(+), 7 deletions(-)
diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index 5741bfd..ee68cfc 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -225,7 +225,7 @@ static struct acpi_iort_node *iort_scan_node(enum acpi_iort_node_type type,
if (iort_node->type == type &&
ACPI_SUCCESS(callback(iort_node, context)))
- return iort_node;
+ return iort_node;
iort_node = ACPI_ADD_PTR(struct acpi_iort_node, iort_node,
iort_node->length);
@@ -253,17 +253,15 @@ static acpi_status iort_match_node_callback(struct acpi_iort_node *node,
void *context)
{
struct device *dev = context;
- acpi_status status;
+ acpi_status status = AE_NOT_FOUND;
if (node->type == ACPI_IORT_NODE_NAMED_COMPONENT) {
struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER, NULL };
struct acpi_device *adev = to_acpi_device_node(dev->fwnode);
struct acpi_iort_named_component *ncomp;
- if (!adev) {
- status = AE_NOT_FOUND;
+ if (!adev)
goto out;
- }
status = acpi_get_name(adev->handle, ACPI_FULL_PATHNAME, &buf);
if (ACPI_FAILURE(status)) {
@@ -289,8 +287,6 @@ static acpi_status iort_match_node_callback(struct acpi_iort_node *node,
*/
status = pci_rc->pci_segment_number == pci_domain_nr(bus) ?
AE_OK : AE_NOT_FOUND;
- } else {
- status = AE_NOT_FOUND;
}
out:
return status;
--
1.7.12.4
^ permalink raw reply related
* [PATCH v3 00/14] ACPI platform MSI, interrupt producer/consumer and its example mbi-gen
From: Hanjun Guo @ 2016-10-25 15:09 UTC (permalink / raw)
To: linux-arm-kernel
From: Hanjun Guo <hanjun.guo@linaro.org>
This patch series is v3 of a previous posting,
https://lkml.org/lkml/2016/9/14/510
v2 -> v3:
- Drop RFC tag
- Rebase against v4.9-rc2 and Lorenzo's v6 of ACPI IORT ARM SMMU support [1]
- Add 3 cleanup patches (patch 1, 2, 3)
- Drop arch_init call patch from last version
- Introduce a callback for platform device to set msi domain
- Introduce a new API to get paltform device's domain instead of
reusing the PCI one in previous version
- Add a patch to rework iort_node_get_id()
[1]: http://www.mail-archive.com/linux-kernel at vger.kernel.org/msg1251993.html
v2 -> v1:
- Fix the bug of if multi Interrupt() resoures in single _PRS,
we need to calculate all the irq numbers (I missed it in previous
version);
- Rebased on Marc's irq/irqchip-4.9 branch and Lorenzo's v5
SMMU patches (also Robin's SMMu patches)
- Add patch irqchip: mbigen: promote mbigen init.
With platform msi support landed in the kernel, and the introduction
of IORT for GICv3 ITS (PCI MSI) [1], the framework for platform msi
is ready, this patch set add few patches to enable the ACPI platform
msi support.
For platform device connecting to ITS on arm platform, we have IORT
table with the named componant node to describe the mappings of paltform
device and ITS, so we can retrieve the dev id and find its parent
irqdomain (ITS) from IORT table (simlar with the ACPI ITS support).
With acpi platform msi supported, we add the ACPI support for irqchip
mbi-gen, which use this framework to form its stacked irqdomain, below
is the mbi-gen's topology in the system:
| ---------------| |------------------|
| | MSI | | wired interrupt(s)
| ITS |<-----------------| MBI-GEN |<----------------------------- IO device(s)
| | | |<----------------------------- IO device(s)
------------------ -------------------
So with ACPI platform MSI support, we can build the stacked domain for
mbi-gen which represented its mappings with the named componant in IORT,
but we still missing the connectings of devices to mbi-gen as in ACPI
world devices connect to main interrupt controller in MADT in default.
In ACPI 6.1, section 19.6.62, Interrupt Resource Descriptor Macro,
Interrupt (ResourceUsage, EdgeLevel, ActiveLevel, Shared,
ResourceSourceIndex, ResourceSource, DescriptorName)
{ InterruptList } => Buffer
For the arguement ResourceUsage and DescriptorName, which means:
ResourceUsage describes whether the device consumes the specified
interrupt ( ResourceConsumer ) or produces it for use by a child
device ( ResourceProducer ).
If nothing is specified, then ResourceConsumer is assumed.
DescriptorName evaluates to a name string which refers to the
entire resource descriptor.
So it can be used for devices connecting to a specific interrupt
prodcucer instead of the main interrupt controller in MADT, we can
define:
Interrupt(ResourceConsumer,..., "\_SB.IRQP") {12,14,....},
then get the interrupt producer with the full path name "\_SB.IRQP".
Thanks
Hanjun
Hanjun Guo (12):
ACPI: ARM64: IORT: minor cleanup for iort_match_node_callback()
irqchip: gic-v3-its: keep the head file include in alphabetic order
ACPI: ARM64: IORT: add missing comment for iort_dev_find_its_id()
irqchip: gicv3-its: platform-msi: refactor its_pmsi_prepare()
ACPI: platform-msi: retrieve dev id from IORT
irqchip: gicv3-its: platform-msi: refactor its_pmsi_init() to prepare
for ACPI
irqchip: gicv3-its: platform-msi: scan MADT to create platform msi
domain
ACPI: ARM64: IORT: rework iort_node_get_id()
ACPI: platform: setup MSI domain for ACPI based platform device
msi: platform: make platform_msi_create_device_domain() ACPI aware
ACPI: irq: introduce interrupt producer
irqchip: mbigen: Add ACPI support
Kefeng Wang (2):
irqchip: mbigen: drop module owner
irqchip: mbigen: introduce mbigen_of_create_domain()
drivers/acpi/acpi_platform.c | 11 +++
drivers/acpi/arm64/iort.c | 83 ++++++++++++++++++--
drivers/acpi/gsi.c | 10 ++-
drivers/acpi/resource.c | 85 ++++++++++++++------
drivers/base/platform-msi.c | 3 +-
drivers/base/platform.c | 3 +
drivers/irqchip/irq-gic-v3-its-platform-msi.c | 106 +++++++++++++++++++------
drivers/irqchip/irq-gic-v3-its.c | 3 +-
drivers/irqchip/irq-mbigen.c | 109 ++++++++++++++++++++++----
include/acpi/acpi_bus.h | 1 +
include/linux/acpi_iort.h | 11 +++
include/linux/platform_device.h | 3 +
12 files changed, 346 insertions(+), 82 deletions(-)
--
1.7.12.4
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox