Re: [PATCH 0/2] arm64: cpuidle: make arm_cpuidle_suspend() more efficient

2016-03-24 Thread Lorenzo Pieralisi
On Thu, Mar 24, 2016 at 09:18:53PM +0800, Jisheng Zhang wrote:
> Hi Will,
> 
> On Thu, 24 Mar 2016 11:15:07 + Will Deacon wrote:
> 
> > On Thu, Mar 24, 2016 at 01:08:48PM +0800, Jisheng Zhang wrote:
> > > This series is to improve the arm_cpuidle_suspend() a bit by 
> > > removing/moving
> > > out checks from this hot path.
> > > 
> > > Jisheng Zhang (2):
> > >   arm64: cpuidle: remove cpu_ops check from arm_cpuidle_suspend()
> > >   arm64: cpuidle: make arm_cpuidle_suspend() a bit more efficient
> > > 
> > >  arch/arm64/kernel/cpuidle.c | 9 ++---
> > >  1 file changed, 2 insertions(+), 7 deletions(-)  
> > 
> > These look fine to me, but do you have any rough numbers showing what
> > sort of improvement we get from this change?
> 
> Good question. Here it is:
> 
> I measured the 4096 * time from arm_cpuidle_suspend entry point to the
> cpu_psci_cpu_suspend entry point. HW platform is Marvell BG4CT STB board.
> 
> 1. only one shell, no other process, hot-unplug secondary cpus, execute the
> following cmd
> 
> while true
> do
>   sleep 0.2
> done
> 
> before the patch: 1581220ns
> 
> after the patch: 1579630ns
> 
> reduced by 0.1%
> 
> 2. only one shell, no other process, hot-unplug secondary cpus, execute the
> following cmd
> 
> while true
> do
>   md5sum /tmp/testfile
>   sleep 0.2
> done
> 
> NOTE the testfile size should be larger than L1+L2 cache size
> 
> before the patch: 1961960ns
> after the patch: 1912500ns
> 
> reduced by 2.5%
> 
> So the more complex the system load, the bigger the improvement.

So between arm_cpuidle_suspend() and psci_cpu_suspend_enter() the
checks that you are removing are almost the *only* code that is
currently executed and this patch saves us best case 12ns per idle state
entry (which is noise compared to CPU PM notifiers/FW execution time)
if I am not mistaken, I can't wait to use that energy for something more
useful :)

Anyway, as a clean-up your patches are fine it is sloppy to check those
pointers on every idle state entry (do you really need two patches ?), so:

Acked-by: Lorenzo Pieralisi <lorenzo.pieral...@arm.com>


Re: [PATCH] cpuidle: arm: make enter idle operation a bit more efficient

2016-03-24 Thread Lorenzo Pieralisi
On Thu, Mar 24, 2016 at 01:07:18PM +0800, Jisheng Zhang wrote:
> Currently, entering idle need to check the idx every time to choose the
> real entering idle routine. But this check could be avoided by pointing
> the idle enter function pointer of each idle states to the routines
> suitable for each states directly.
> 
> Signed-off-by: Jisheng Zhang 
> ---
>  drivers/cpuidle/cpuidle-arm.c | 14 --
>  1 file changed, 8 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/cpuidle/cpuidle-arm.c b/drivers/cpuidle/cpuidle-arm.c
> index 545069d..48a620f 100644
> --- a/drivers/cpuidle/cpuidle-arm.c
> +++ b/drivers/cpuidle/cpuidle-arm.c
> @@ -23,6 +23,13 @@
>  
>  #include "dt_idle_states.h"
>  
> +static int arm_enter_wfi_state(struct cpuidle_device *dev,
> +struct cpuidle_driver *drv, int idx)
> +{
> + cpu_do_idle();
> + return 0;
> +}
> +
>  /*
>   * arm_enter_idle_state - Programs CPU to enter the specified state
>   *
> @@ -38,11 +45,6 @@ static int arm_enter_idle_state(struct cpuidle_device *dev,
>  {
>   int ret;
>  
> - if (!idx) {
> - cpu_do_idle();
> - return idx;
> - }

Mmm...if I wanted to paint your bikeshed I would say idx is in a
register and you are removing a simple comparison to exchange it
with a function that adds to code footprint and may even make
performance worse instead of improving anything.

I am not sure this patch makes anything more efficient, happy to be
proven wrong, with significant data.

Thanks,
Lorenzo

> -
>   ret = cpu_pm_enter();
>   if (!ret) {
>   /*
> @@ -69,7 +71,7 @@ static struct cpuidle_driver arm_idle_driver = {
>* handler for idle state index 0.
>*/
>   .states[0] = {
> - .enter  = arm_enter_idle_state,
> + .enter  = arm_enter_wfi_state,
>   .exit_latency   = 1,
>   .target_residency   = 1,
>   .power_usage= UINT_MAX,
> -- 
> 2.8.0.rc3
> 


Re: Question about PCI I/O space in ARM64

2016-03-24 Thread Lorenzo Pieralisi
[+ Jean]

On Thu, Mar 24, 2016 at 11:14:50AM +0800, Kefeng Wang wrote:

[...]

> >> You need a PCI host controller driver (e.g.
> >> drivers/pci/host/pci-host-generic.c) and corresponding bindings in DT or
> >> ACPI.
> 
> In our inner test, there are some board without pcie host driver(even
> without pci host controller).

So I guess those drivers are for devices that are attached to an LPC
controller that is not part of a PCI host controller, right ?

BTW, what happened to this (not that I particularly like this patchset) ?

https://lkml.org/lkml/2015/12/29/154

> > I think getting an Oops is not the best behavior though, it would be
> > nice if that could be improved in some way.
> > 
> > Ideally, each driver that accesses PCI I/O space would call request_region()
> > before doing so, and it would be good if that call could be made to
> > return an error when asked about an address that has not been mapped.
> > 
> > I see that ioport_resource gets initialized to the {0, IO_SPACE_LIMIT}
> > range. If we could change it so that pci_remap_iospace() hooks up
> > to ioport_resource and extends it whenever something gets mapped
> > there up to IO_SPACE_LIMIT, we can change the default range to
> > {0,0}, which would fail for any request_region call before the
> > first pci_remap_iospace.
> > 
> > This won't help for the specific f71805f driver example, because that
> > does not call request_region(), but we can treat that as a driver bug
> > and fix it.
> 
> Yes, we met same error with several modules(at least 8+), so it's
> better to find a good way to avoid it, change modules one by one maybe
> not a good choice.

But that's the right thing to do :)

The problem with those drivers is that IIUC they use ISA IO port space to
detect if the devices they manage are actually present, it does not
look that correct to me, at least not on !X86 (IA64 ?) systems.

Those drivers can't be built on PPC for a reason (?), I found these threads
which might be telling:

http://www.spinics.net/lists/lm-sensors/msg43868.html
http://comments.gmane.org/gmane.linux.drivers.sensors/17290

I agree with Arnd on this and we need to patch the eg f71805f driver too
(or we just do not build on ARM) to make it request the IO port region it
needs to actually probe the device, it is not correct to assume IO space
is available and mapped, I think that's a driver bug rather than anything
else, Jean can certainly shed some light here.

> Define some arch in/out func instead of generic ops? when in/out vals, check
> whether or not the pci_iobase is mapped.

I do not think the problem should be solved in the IO accessors
implementation, see above.

Lorenzo


[PATCH v3] PCI: ACPI: IA64: fix IO port generic range check

2016-03-21 Thread Lorenzo Pieralisi
The [0 - 64k] ACPI PCI IO port resource boundary check in:

acpi_dev_ioresource_flags()

is currently applied blindly in the ACPI resource parsing to all
architectures, but only x86 suffers from that IO space limitation.

On arches (ie IA64 and ARM64) where IO space is memory mapped,
the PCI root bridges IO resource windows are firstly initialized from
the _CRS (in acpi_decode_space()) and contain the CPU physical address
at which a root bridge decodes IO space in the CPU physical address
space with the offset value representing the offset required to translate
the PCI bus address into the CPU physical address.

The IO resource windows are then parsed and updated in arch code
before creating and enumerating PCI buses (eg IA64 add_io_space())
to map in an arch specific way the obtained CPU physical address range
to a slice of virtual address space reserved to map PCI IO space,
ending up with PCI bridges resource windows containing IO
resources like the following on a working IA64 configuration:

PCI host bridge to bus :00
pci_bus :00: root bus resource [io  0x100-0x100 window] (bus
address [0x-0x])
pci_bus :00: root bus resource [mem 0x000a-0x000f window]
pci_bus :00: root bus resource [mem 0x8000-0x8fff window]
pci_bus :00: root bus resource [mem 0x8000400-0x800 window]
pci_bus :00: root bus resource [bus 00]

This implies that the [0 - 64K] check in acpi_dev_ioresource_flags()
leaves platforms with memory mapped IO space (ie IA64) broken (ie kernel
can't claim IO resources since the host bridge IO resource is disabled
and discarded by ACPI core code, see log on IA64 with missing root bridge
IO resource, silently filtered by current [0 - 64k] check in
acpi_dev_ioresource_flags()):

PCI host bridge to bus :00
pci_bus :00: root bus resource [mem 0x000a-0x000f window]
pci_bus :00: root bus resource [mem 0x8000-0x8fff window]
pci_bus :00: root bus resource [mem 0x8000400-0x800 window]
pci_bus :00: root bus resource [bus 00]

[...]

pci :00:03.0: [1002:515e] type 00 class 0x03
pci :00:03.0: reg 0x10: [mem 0x8000-0x87ff pref]
pci :00:03.0: reg 0x14: [io  0x1000-0x10ff]
pci :00:03.0: reg 0x18: [mem 0x8802-0x8802]
pci :00:03.0: reg 0x30: [mem 0x8800-0x8801 pref]
pci :00:03.0: supports D1 D2
pci :00:03.0: can't claim BAR 1 [io  0x1000-0x10ff]: no compatible
bridge window

For this reason, the IO port resources boundaries check in generic ACPI
parsing code should be guarded with a CONFIG_X86 guard so that more arches
(ie ARM64) can benefit from the generic ACPI resources parsing interface
without incurring in unexpected resource filtering, fixing at the same
time current breakage on IA64.

This patch factors out IO ports boundary [0 - 64k] check in generic ACPI
code and makes the IO space check X86 specific to make sure that IO
space resources are usable on other arches too.

Fixes: 3772aea7d6f3 ("ia64/PCI/ACPI: Use common ACPI resource parsing
interface for host bridge")
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieral...@arm.com>
Cc: Bjorn Helgaas <bhelg...@google.com>
Cc: Hanjun Guo <hanjun@linaro.org>
Cc: Jiang Liu <jiang@linux.intel.com>
Cc: Tony Luck <tony.l...@intel.com>
Cc: Tomasz Nowicki <t...@semihalf.com>
Cc: Mark Salter <msal...@redhat.com>
Cc: "Rafael J. Wysocki" <r...@rjwysocki.net>
---
v2 -> v3

- Moved IO resource check to generic ACPI resource code
- Dropped Tested-by tags
- Rebased against v4.5

v2: https://marc.info/?l=linux-acpi=145521271330332=2

v1 -> v2

- Updated commit log to report missing IO resources
- Fixed function ioport_valid() comment 16k/64k typo

v1: https://marc.info/?l=linux-acpi=145432228025354=2

 drivers/acpi/resource.c | 14 +-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c
index d02fd53..56241eb 100644
--- a/drivers/acpi/resource.c
+++ b/drivers/acpi/resource.c
@@ -27,8 +27,20 @@
 
 #ifdef CONFIG_X86
 #define valid_IRQ(i) (((i) != 0) && ((i) != 2))
+static inline bool acpi_iospace_resource_valid(struct resource *res)
+{
+   /* On X86 IO space is limited to the [0 - 64K] IO port range */
+   return res->end < 0x10003;
+}
 #else
 #define valid_IRQ(i) (true)
+/*
+ * ACPI IO descriptors on arches other than X86 contain MMIO CPU physical
+ * addresses mapping IO space in CPU physical address space, IO space
+ * resources can be placed anywhere in the 64-bit physical address space.
+ */
+static inline bool
+acpi_iospace_resource_valid(struct resource *res) { return true; }
 #endif
 
 static bool acpi_dev_resource_len_valid(u64 start, u64 end, u64 len, bool io)
@@ -127,7 +139,7 @@ static void acpi_dev_ioresource_flags(struct resource *res, 
u64 len,
if (!acpi_dev_resource_len_valid(res->start, res->end, len, true)

Re: [PATCH] drivers: firmware: psci: make two helper functions static

2016-03-23 Thread Lorenzo Pieralisi
On Tue, Mar 22, 2016 at 10:31:45PM +0800, Jisheng Zhang wrote:
> psci_power_state_loses_context() and psci_power_state_is_valid are only
> used internally now, so make them static.
> 
> Signed-off-by: Jisheng Zhang 
> ---
>  drivers/firmware/psci.c | 4 ++--
>  include/linux/psci.h| 2 --
>  2 files changed, 2 insertions(+), 4 deletions(-)

Thanks, I will apply it and send it for next cycle.

Lorenzo

> diff --git a/drivers/firmware/psci.c b/drivers/firmware/psci.c
> index 11bfee8..6d86881 100644
> --- a/drivers/firmware/psci.c
> +++ b/drivers/firmware/psci.c
> @@ -91,7 +91,7 @@ static inline bool psci_has_ext_power_state(void)
>   PSCI_1_0_FEATURES_CPU_SUSPEND_PF_MASK;
>  }
>  
> -bool psci_power_state_loses_context(u32 state)
> +static bool psci_power_state_loses_context(u32 state)
>  {
>   const u32 mask = psci_has_ext_power_state() ?
>   PSCI_1_0_EXT_POWER_STATE_TYPE_MASK :
> @@ -100,7 +100,7 @@ bool psci_power_state_loses_context(u32 state)
>   return state & mask;
>  }
>  
> -bool psci_power_state_is_valid(u32 state)
> +static bool psci_power_state_is_valid(u32 state)
>  {
>   const u32 valid_mask = psci_has_ext_power_state() ?
>  PSCI_1_0_EXT_POWER_STATE_MASK :
> diff --git a/include/linux/psci.h b/include/linux/psci.h
> index 393efe2..bdea1cb 100644
> --- a/include/linux/psci.h
> +++ b/include/linux/psci.h
> @@ -21,8 +21,6 @@
>  #define PSCI_POWER_STATE_TYPE_POWER_DOWN 1
>  
>  bool psci_tos_resident_on(int cpu);
> -bool psci_power_state_loses_context(u32 state);
> -bool psci_power_state_is_valid(u32 state);
>  
>  int psci_cpu_init_idle(unsigned int cpu);
>  int psci_cpu_suspend_enter(unsigned long index);
> -- 
> 2.8.0.rc3
> 


Re: [PATCH] Fix NULL ptr dereference in pci_bus_assign_domain_nr() on ARM

2016-03-08 Thread Lorenzo Pieralisi
On Mon, Mar 07, 2016 at 10:24:27PM -0600, Bjorn Helgaas wrote:

[...]

> > > Actually, I did find one problem report:
> > > http://forum.doozan.com/read.php?2,17868,22070,quote=1 from last May,
> > > but apparently it got lost in a forum and never found its way
> > > upstream.
> > > 
> > > I reworked the changelog because this problem will affect *any* arch
> > > that enables CONFIG_PCI_DOMAINS_GENERIC and supplies NULL "parent"
> > > pointers -- ia64, mips, mn10300, s390, x86, etc., would be affected if
> > > they enabled CONFIG_PCI_DOMAINS_GENERIC.
> > > 
> > > I also added a "Fixes:" tag for 7c674700098c, since that's the commit
> > > that added the generic code we're fixing.  Backports of 7c674700098c
> > > should also backport this change.
> > 
> > That's really unfortunate, when I moved code from arm64 to generic I
> > did not spot this issue in the original code and carried it over, you
> > summarized the reasons in the commit log so without any further ado (and
> > with my apologies):
> > 
> > Acked-by: Lorenzo Pieralisi <lorenzo.pieral...@arm.com>
> 
> No worries, it just goes with the territory.  What surprises me is
> that it took us so long to notice.  v4.0 was released almost a year
> ago (April 12, 2015), so I can't figure out how nobody noticed until
> now.
> 
> And I don't know what happened with the problem report in the forum.
> That's a case where somebody *did* notice, but I guess they just gave
> up on v4.0 and went back to v3.18.  What a shame :)  I don't know if
> people just have low expectations of Linux, or they feel like it's too
> hard to report bugs, or we don't make it easy enough, or we're not
> approachable enough, or what.  I notice that many times somebody finds
> a workaround, and people seem satisfied with that, and we don't get a
> chance to fix the real problem.

I agree it is a pity the problem was not reported upstream which would
have solved the issue (that I should have spotted anyway while moving
the code) a long time ago, unfortunately I think it has to do with
how often developers/distros upgrade their kernels on these boards/socs
and how they interact with upstream, which is a discussion worth having.

Thank you !
Lorenzo


Re: [PATCH] Fix NULL ptr dereference in pci_bus_assign_domain_nr() on ARM

2016-03-07 Thread Lorenzo Pieralisi
On Mon, Mar 07, 2016 at 04:33:11PM -0600, Bjorn Helgaas wrote:
> [+cc Lorenzo]
> 
> On Tue, Mar 01, 2016 at 07:07:18AM +0100, Krzysztof Ha??asa wrote:
> > Many ARM platforms use a wrapper:
> > /*
> >  * Compatibility wrapper for older platforms that do not care about
> >  * passing the parent device.
> >  */
> > static inline void pci_common_init(struct hw_pci *hw)
> > {
> > pci_common_init_dev(NULL, hw);
> > }
> > 
> > which means that pci_bus_assign_domain_nr() can be called without
> > a parent. This patch fixes the NULL pointer dereference.
> > 
> > Signed-off-by: Krzysztof Ha??asa <khal...@piap.pl>
> > Cc: sta...@vger.kernel.org
> 
> I applied this to for-linus with changelog as below for v4.5, thanks!
> 
> Wow, this is terrible.  All ARM32 systems that use pci_common_init()
> crash at boot.  That includes cns3xxx, dove, footbridge, iopl13xx,
> ip32x, iop33x, ixp4xx, ks8695, mv78xx0, orion5x, pxa, sa1100, etc.
> Apparently they've been crashing since v4.0, when 7c674700098c and
> 8c7d14746abc appeared.  I can hardly believe nobody noticed until now.
> 
> Actually, I did find one problem report:
> http://forum.doozan.com/read.php?2,17868,22070,quote=1 from last May,
> but apparently it got lost in a forum and never found its way
> upstream.
> 
> I reworked the changelog because this problem will affect *any* arch
> that enables CONFIG_PCI_DOMAINS_GENERIC and supplies NULL "parent"
> pointers -- ia64, mips, mn10300, s390, x86, etc., would be affected if
> they enabled CONFIG_PCI_DOMAINS_GENERIC.
> 
> I also added a "Fixes:" tag for 7c674700098c, since that's the commit
> that added the generic code we're fixing.  Backports of 7c674700098c
> should also backport this change.

That's really unfortunate, when I moved code from arm64 to generic I
did not spot this issue in the original code and carried it over, you
summarized the reasons in the commit log so without any further ado (and
with my apologies):

Acked-by: Lorenzo Pieralisi <lorenzo.pieral...@arm.com>

> 
> Bjorn
> 
> 
> 
> commit 71babd2a89fe
> Author: Krzysztof =?utf-8?Q?Ha=C5=82asa?= <khal...@piap.pl>
> Date:   Tue Mar 1 07:07:18 2016 +0100
> 
> PCI: Allow a NULL "parent" pointer in pci_bus_assign_domain_nr()
> 
> pci_create_root_bus() passes a "parent" pointer to
> pci_bus_assign_domain_nr().  When CONFIG_PCI_DOMAINS_GENERIC is defined,
> pci_bus_assign_domain_nr() dereferences that pointer.  Many callers of
> pci_create_root_bus() supply a NULL "parent" pointer, which leads to a 
> NULL
> pointer dereference error.
> 
> 7c674700098c ("PCI: Move domain assignment from arm64 to generic code")
> moved the "parent" dereference from arm64 to generic code.  Only arm64 
> used
> that code (because only arm64 defined CONFIG_PCI_DOMAINS_GENERIC), and it
> always supplied a valid "parent" pointer.  Other arches supplied NULL
> "parent" pointers but didn't defined CONFIG_PCI_DOMAINS_GENERIC, so they
> used a no-op version of pci_bus_assign_domain_nr().
> 
> 8c7d14746abc ("ARM/PCI: Move to generic PCI domains") defined
> CONFIG_PCI_DOMAINS_GENERIC on ARM, and many ARM platforms use
> pci_common_init(), which supplies a NULL "parent" pointer.
> These platforms (cns3xxx, dove, footbridge, iop13xx, etc.) crash
> with a NULL pointer dereference like this while probing PCI:
> 
>   Unable to handle kernel NULL pointer dereference at virtual address 
> 00a4
>   PC is at pci_bus_assign_domain_nr+0x10/0x84
>   LR is at pci_create_root_bus+0x48/0x2e4
>   Kernel panic - not syncing: Attempted to kill init!
> 
> [bhelgaas: changelog, add "Reported:" and "Fixes:" tags]
> Reported: http://forum.doozan.com/read.php?2,17868,22070,quote=1
> Fixes: 8c7d14746abc ("ARM/PCI: Move to generic PCI domains")
> Fixes: 7c674700098c ("PCI: Move domain assignment from arm64 to generic 
> code")
> Signed-off-by: Krzysztof Ha??asa <khal...@piap.pl>
> Signed-off-by: Bjorn Helgaas <bhelg...@google.com>
> CC: sta...@vger.kernel.org# v4.0+
> 
> diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
> index 602eb42..f89db3a 100644
> --- a/drivers/pci/pci.c
> +++ b/drivers/pci/pci.c
> @@ -4772,8 +4772,10 @@ int pci_get_new_domain_nr(void)
>  void pci_bus_assign_domain_nr(struct pci_bus *bus, struct device *parent)
>  {
>   static int use_dt_domains = -1;
> - int domain = of_get_pci_domain_nr(parent->of_node);
> + int domain = -1;
>  
> + if (parent)
> + domain = of_get_pci_domain_nr(parent->of_node);
>   /*
>* Check DT domain and use_dt_domains values.
>*
> 


Re: [PATCH V5 00/15] MMCONFIG refactoring and support for ARM64 PCI hostbridge init based on ACPI

2016-03-04 Thread Lorenzo Pieralisi
On Thu, Mar 03, 2016 at 09:24:56AM -0500, Sinan Kaya wrote:
> On 3/3/2016 6:23 AM, Lorenzo Pieralisi wrote:
> > x86 and IA64 claim PCI resources on boot and live with that (well, minus
> > the gazillions x86 pci= parameters that change the PCI resources assignment
> > one way or another), comments very welcome in particular on the pci=realloc
> > option and its usage.
> 
> I have been working with Linux PCIe over 3 years. I never used
> pci=realloc argument.
> 
> The v5 series minus [PATCH V5 11/15] drivers: pci: add generic code to
> claim bus resources is working just fine and is ready to go upstream
> in my opinion. It passed my internal testing with different types of
> endpoints.
> 
> The inclusion of this patch is now requiring everybody to add
> pci=realloc argument otherwise the resources assigned by the UEFI BIOS
> are not working.
> 
> I think there is still some work to be done in this patch and is too
> early to be included into the series. It is blocking progress of the
> series which is sitting on review over 1 year already.

First off, I think that's specious, patch 11 is not blocking anything,
if you and Tomasz want to drop it go ahead and take responsibility
of the consequences.

I am not saying patch 11 is perfect, it is there to review, if you
spot bugs point them out.

If you are interested and willing to make an effort to understand why I
asked Tomasz to integrate it, a bit of background here:

http://permalink.gmane.org/gmane.linux.kernel.pci/44830

If we want to drop patch 11, we are going to discard whatever FW
set-up at FW/OS hand-off and reassign everything. Want to do it ?
Go ahead.

I wrote it in my previous email, probably it was not clear, so, here we
go again.

If we want to at least consider the FW PCI configuration at FW/OS
handoff, we should read the PCI bridge apertures and claim them, when
that fails reassign the corresponding PCI bus hierarchy (which means
releasing the bridge resources and downstream devices and reassign
them), that's what pci=realloc does.

I think that it is a command line option since it has to be a choice,
ie overriding FW set-up should be an option, not a default.

Patch 11 does what x86 does in arch code arch/x86/pci/i386.c,

pcibios_resource_survey()

and that works for them (of course, minus quirks that do exist).

I could integrate the code implementing pci=realloc in patch 11 so
that we realloc by default all resources claimed that failed (which
means that bridges are resized accordingly and you won't be forced
to use pci=realloc on command line).

> [0.752916] pci :01:00.0: VF(n) BAR2 space: [mem 
> 0x8036080-0x8037fff 64bit pref] (contains BAR2 for 63 VFs)
> [0.771799] pci :00:00.0: PCI bridge to [bus 01-06]
> [0.777054] pci :00:00.0: root [mem 0x8010010-0x8013fff 
> window] res [mem 0x8013ff0-0x8013fff] nr 14
> [0.787846] pci :00:00.0: pci_claim_bridge_resource:714 1: i:14
> [0.794135] pci :00:00.0: root [mem 0x803-0x8037fff 
> window] res [mem 0x8036000-0x8037fff 64bit pref] nr 15
> [0.805881] pci :00:00.0: pci_claim_bridge_resource:714 1: i:15
> [0.812155] pci :01:00.0: root [mem 0x8013ff0-0x8013fff] res 
> [mem 0x8013ff0-0x8013fff 64bit] nr 0
> [0.822773] pci :01:00.0: root [mem 0x8036000-0x8037fff 64bit 
> pref] res [mem 0x8036000-0x803607f 64bit pref] nr 2
> [0.834778] pci :01:00.0: root [mem 0x8036000-0x8037fff 64bit 
> pref] res [mem 0x8037ff0-0x8037fff pref] nr 6
> [0.846265] pci :01:00.0: can't claim BAR 9 [mem 
> 0x8036080-0x8037fff 64bit pref]: address conflict with :01:00.0 
> [mem 0x8037ff0-0x8037fff pref]
> [0.861237] pci :01:00.0: BAR 9: no space for [mem size 0x1f80 
> 64bit pref]
> [0.868811] pci :01:00.0: BAR 9: failed to assign [mem size 0x1f80 
> 64bit pref]
> 
> 
> I keep saying this but the type of CPU is not important when it comes
> to PCIe. Both PCIe and ACPI are governed by specs. If it is working
> for x86 and i64; it needs to work for ARM64 as well.

That's theory. In practice there is massive legacy there and PCI resource
assignment is carried out in an arch specific way (otherwise there would
be no pci claiming/assignment code in arch/* right ?) and the resource
claiming/assignment strictly depends on FW set-up, like it or lump it,
that's the way it *currently* is.

I wrote in my previous email, the status of PCI resources at OS/FW
handoff is not strictly mandated by the PCI standard AFAIK (it is
covered by 3.5 "Device state at Firmware/Operating System Handoff" in
the PCI FW spec revision 3.1), so what I suggest above is the only option
we have (or you just discard FW configuration altogether, that's what
happens if all PCI resour

Re: [PATCH V5 00/15] MMCONFIG refactoring and support for ARM64 PCI hostbridge init based on ACPI

2016-03-03 Thread Lorenzo Pieralisi
[+ Yinghai]

On Mon, Feb 29, 2016 at 02:03:45PM -0500, Sinan Kaya wrote:
> On 2/16/2016 8:53 AM, Tomasz Nowicki wrote:
> > From the functionality point of view this series might be split into the
> > following logic parts:
> > 1. Make MMCONFIG code arch-agnostic which allows all architectures to 
> > collect
> >PCI config regions and used when necessary.
> > 2. Move non-arch specific bits to the core code.
> > 3. Use MMCONFIG code and implement generic ACPI based PCI host controller 
> > driver.
> > 4. Enable above driver on ARM64
> > 
> > Patches has been built on top of 4.5-rc3 and can be found here:
> > g...@github.com:semihalf-nowicki-tomasz/linux.git (pci-acpi-v5)
> > 
> > NOTE, this patch set depends on Lorenzo's fixes:
> > https://patchwork.ozlabs.org/patch/576450/
> > which can be found in pci-acpi-v5 branch.
> > 
> > This has been tested on Cavium ThunderX server, JunoR2, HP RX2660 IA64, x86,
> > Hip05, X-Gene and QEMU-aarch64. Any help in reviewing and testing is very 
> > appreciated.
> > 
> > v4 -> v5
> > - dropped MCFG refactoring group patches 1-6 from series v4 and integrated 
> > Jayachandran's patch
> >   https://patchwork.ozlabs.org/patch/575525/
> > - rewrite PCI legacy IRQs allocation
> > - squashed two patches 11 and 12 from series v4, fixed bisection issue
> > - changelog improvements
> > - rebased to 4.5-rc3
> > 
> > v3 -> v4
> > - dropped Jiang's fix 
> > http://lkml.iu.edu/hypermail/linux/kernel/1601.1/04318.html
> > - added Lorenzo's fix patch 19/24
> > - ACPI PCI bus domain number assigning cleanup
> > - changed resource management, we now claim and reassign resources
> > - improvements for applying quirks
> > - dropped Matthew's http://www.spinics.net/lists/linux-pci/msg45950.html 
> > dependency
> > - rebased to 4.5-rc1
> > 
> 
> Having tested v4 and v5, I'm seeing some resource assignment problems
> and address conflicts.  And problems booting QEMU.

I asked Tomasz to add resource claiming code in v4 to make sure that,
if FW has left resources in a reasonable set-up, we reuse it as-is.

Now, I was and I am aware this could trigger resource allocation
issues (in particular in relation to bridges apertures sizing),
that can be nonetheless solved by forcing the kernel to reallocate
resources (pci=realloc, that's exactly what's there for, release
the bridge apertures, resize the busses downstream and reassign
the respective hierarchy).

I am not entirely aware of how consistently pci=realloc was used on
x86, what I am aware of is the panoply of pci=* command line parameters
defined for x86 and I would certainly avoid that.

The decision on whether we claim resources before reassigning them
is either dictacted by the boot method (ie ACPI->claim resources by
default) or we should control it via a FW option or a command
line option, PCI standard (PCI FW revision 3.1, 3.5 "Device State
at Firmware/Operating System Handoff) IIUC does not stricly mandate
FW configuring the whole PCI hierarchy (and to be 100% compliant
we should check the device IO/MEM enable bits before claiming, as x86 does
- see pcibios_allocate_dev_resources() in arch/x86/pci/i386.c).

x86 and IA64 claim PCI resources on boot and live with that (well, minus
the gazillions x86 pci= parameters that change the PCI resources assignment
one way or another), comments very welcome in particular on the pci=realloc
option and its usage.

What's certain is, if we do not claim resources by default we will *never*
be able to do it, it will certainly trigger regressions.

Lorenzo


Re: [PATCH 3/3] arm64: kasan: clear stale stack poison

2016-03-03 Thread Lorenzo Pieralisi
On Thu, Mar 03, 2016 at 02:14:29PM +, Mark Rutland wrote:
> On Wed, Mar 02, 2016 at 02:26:18PM +, Mark Rutland wrote:
> > Functions which the compiler has instrumented for ASAN place poison on
> > the stack shadow upon entry and remove this poison prior to returning.
> > 
> > In the case of cpuidle, CPUs exit the kernel a number of levels deep
> > in C code. Any instrumented functions on this critical path will leave
> > portions of the stack shadow poisoned.
> > 
> > If CPUs lose context and return to the kernel via a cold path, we
> > restore a prior context saved in __cpu_suspend_enter are forgotten, and
> > we never remove the poison they placed in the stack shadow area by
> > functions calls between this and the actual exit of the kernel.
> > 
> > Thus, (depending on stackframe layout) subsequent calls to instrumented
> > functions may hit this stale poison, resulting in (spurious) KASAN
> > splats to the console.
> > 
> > To avoid this, clear any stale poison from the idle thread for a CPU
> > prior to bringing a CPU online.
> > 
> > Signed-off-by: Mark Rutland <mark.rutl...@arm.com>
> > Cc: Alexander Potapenko <gli...@google.com>
> > Cc: Andrey Ryabinin <aryabi...@virtuozzo.com>
> > Cc: Catalin Marinas <catalin.mari...@arm.com>
> > Cc: Lorenzo Pieralisi <lorenzo.pieral...@arm.com>
> > Cc: Will Deacon <will.dea...@arm.com>
> > ---
> >  arch/arm64/kernel/sleep.S | 4 
> >  1 file changed, 4 insertions(+)
> > 
> > diff --git a/arch/arm64/kernel/sleep.S b/arch/arm64/kernel/sleep.S
> > index e33fe33..fd10eb6 100644
> > --- a/arch/arm64/kernel/sleep.S
> > +++ b/arch/arm64/kernel/sleep.S
> > @@ -145,6 +145,10 @@ ENTRY(cpu_resume_mmu)
> >  ENDPROC(cpu_resume_mmu)
> > .popsection
> >  cpu_resume_after_mmu:
> > +#ifdef CONFIG_KASAN
> > +   mov x0, sp
> > +   bl  kasan_unpoison_remaining_stack
> > +#endif
> 
> Lorenzo, as this was following your suggestion [1], I hope that this
> patch looks ok to you?
> 
> Are you happy to provide an Ack / Reviewed-by?

Yes sure, thanks for putting it together:

Reviewed-by: Lorenzo Pieralisi <lorenzo.pieral...@arm.com>


Re: [PATCH V5 00/15] MMCONFIG refactoring and support for ARM64 PCI hostbridge init based on ACPI

2016-03-04 Thread Lorenzo Pieralisi
On Fri, Mar 04, 2016 at 09:52:17AM -0500, Sinan Kaya wrote:

[...]

> >> I could integrate the code implementing pci=realloc in patch 11 so
> >> that we realloc by default all resources claimed that failed (which
> >> means that bridges are resized accordingly and you won't be forced
> >> to use pci=realloc on command line).
> >>
> > 
> > I agree with Lorenzo. Just because v3 works it does not mean we want to go 
> > this way. Also, I think we should realloc all resources claimed that 
> > failed, w/o need to use pci=realloc on command line.
> > 
> 
> Let's give this a try. I have seen the kernel messages with and
> without realloc option too. I don't want to see any kind of error
> messages if it is actually working.

I agree, claiming resources failures are too noisy, it is a pet-peeve
of mine too. The code to realloc resources is in the kernel already,
it is just a matter of defining how to use it (ie trigger it by default
without command line option - actually the kernel can be already
compiled to enable realloc by default, see CONFIG_PCI_REALLOC_ENABLE_AUTO),
that's why I added Yinghai to the thread, Bjorn and him have more
insights on how this has been used on current systems and I am really keen
on getting their opinion, they have more visibility into this than I do,
writing the patch itself should be simple enough.

Thanks !
Lorenzo


Re: [PATCH V4 17/23] acpi, mcfg: Add default PCI config accessors implementation and initial support for related quirks.

2016-03-02 Thread Lorenzo Pieralisi
On Mon, Feb 29, 2016 at 01:33:41PM +0530, Jayachandran Chandrashekaran Nair 
wrote:
> On Thu, Feb 4, 2016 at 10:58 PM, Tomasz Nowicki  wrote:
> > We use generic accessors from access.c by default. However, we already
> > know platforms that need special handling while accessing to PCI config
> > space. These platforms will need different accessors set matched against
> > platform ID, domain, bus touple. Therefore we are going to add (in future)
> > DECLARE_ACPI_MCFG_FIXUP which will register platform specific custom
> > accessors. For now, we let pci_mcfg_get_ops to take acpi_pci_root structure
> > as an arguments and left some space for quirk matching algorithm.
> >
> > Signed-off-by: Tomasz Nowicki 
> > Tested-by: Duc Dang 
> > Tested-by: Dongdong Liu 
> > Tested-by: Hanjun Guo 
> > Tested-by: Graeme Gregory 
> > Tested-by: Sinan Kaya 
> > ---
> >  drivers/acpi/mcfg.c  | 30 ++
> >  include/linux/pci-acpi.h |  8 
> >  2 files changed, 38 insertions(+)
> >
> > diff --git a/drivers/acpi/mcfg.c b/drivers/acpi/mcfg.c
> > index dca4c4e..dfc2d14 100644
> > --- a/drivers/acpi/mcfg.c
> > +++ b/drivers/acpi/mcfg.c
> > @@ -34,6 +34,36 @@ int __weak raw_pci_write(unsigned int domain, unsigned 
> > int bus,
> > return PCIBIOS_DEVICE_NOT_FOUND;
> >  }
> >
> > +void __iomem *
> > +pci_mcfg_dev_base(struct pci_bus *bus, unsigned int devfn, int offset)
> > +{
> > +   struct pci_mmcfg_region *cfg;
> > +
> > +   cfg = pci_mmconfig_lookup(pci_domain_nr(bus), bus->number);
> 
> In the existing code, calls to pci_mmconfig_lookup() is done inside an
> rcu_read_lock/rcu_read_unlock pair. Any reason that is not required here?
> 
> Also, you can avoid having to do the lookup every time by saving a cfg pointer
> see 
> http://lists.infradead.org/pipermail/linux-arm-kernel/2016-January/396921.html

Yes, this is much better (and sysdata usage is self-contained, it does
not trickle into other bits of the kernel - ie arch code), it should be
integrated in the final version of the patchset.

> > +   if (cfg && cfg->virt)
> > +   return cfg->virt +
> > +   (PCI_MMCFG_BUS_OFFSET(bus->number) | (devfn << 12)) 
> > +
> > +   offset;
> 
> PCI_MMCFG_OFFSET(bus->number, devfn) would be better

Ditto.

Thanks,
Lorenzo

> 
> > +   return NULL;
> > +}
> > +
> > +/* Default generic PCI config accessors */
> > +static struct pci_ops default_pci_mcfg_ops = {
> > +   .map_bus = pci_mcfg_dev_base,
> > +   .read = pci_generic_config_read,
> > +   .write = pci_generic_config_write,
> > +};
> > +
> > +struct pci_ops *pci_mcfg_get_ops(struct acpi_pci_root *root)
> > +{
> > +   /*
> > +* TODO: Match against platform specific quirks and return
> > +* corresponding PCI config space accessor set.
> > +*/
> > +
> > +   return _pci_mcfg_ops;
> > +}
> 
> Is it necessary to make these non-static, even in the next patch, the
> functions are only used from this file.
> 
> > +
> >  int __init acpi_parse_mcfg(struct acpi_table_header *header)
> >  {
> > struct acpi_table_mcfg *mcfg;
> > diff --git a/include/linux/pci-acpi.h b/include/linux/pci-acpi.h
> > index 65b91f3..c974586 100644
> > --- a/include/linux/pci-acpi.h
> > +++ b/include/linux/pci-acpi.h
> > @@ -83,10 +83,18 @@ void acpi_pci_remove_bus(struct pci_bus *bus);
> >  #ifdef CONFIG_PCI_MMCONFIG
> >  int pci_mmcfg_setup_map(struct acpi_pci_root_info *ci);
> >  void pci_mmcfg_teardown_map(struct acpi_pci_root_info *ci);
> > +struct pci_ops *pci_mcfg_get_ops(struct acpi_pci_root *root);
> > +void __iomem *
> > +pci_mcfg_dev_base(struct pci_bus *bus, unsigned int devfn, int offset);
> >  #else
> >  static inline int pci_mmcfg_setup_map(struct acpi_pci_root_info *ci)
> >  { return 0; }
> >  static inline void pci_mmcfg_teardown_map(struct acpi_pci_root_info *ci) { 
> > }
> > +static inline struct pci_ops *pci_mcfg_get_ops(struct acpi_pci_root *root)
> > +{ return NULL; }
> > +static inline void __iomem *
> > +pci_mcfg_dev_base(struct pci_bus *bus, unsigned int devfn, int offset)
> > +{ return NULL; }
> >  #endif
> >  #ifdef CONFIG_ACPI_PCI_SLOT
> 
> JC.
> 


Re: [PATCH 1/2] ARM: cpuidle: fix !cpuidle_ops[cpu].init case during init

2016-03-30 Thread Lorenzo Pieralisi
On Wed, Mar 30, 2016 at 10:09:12AM +0200, Daniel Lezcano wrote:
> On 03/30/2016 09:16 AM, Jisheng Zhang wrote:
> >Hi Daniel,
> 
> [ ... ]
> 
> Added Lorenzo and Catalin.
> 
> >>Hi Jisheng,
> >>
> >>this should be handled in the arm_cpuidle_read_ops function.
> >>
> >
> >Thanks for reviewing. After some consideration, I think this patch isn't 
> >correct
> >There may be platforms which doesn't need the init member at all, although
> >currently I don't see such platforms in mainline, So I'll drop this patch
> >and send out one v2 only does the optimization.
> 
> There is an inconsistency between ARM and ARM64. The 'cpu_get_ops',
> the arm_cpuidle_read_ops from the ARM64 side, returns -EOPNOTSUPP
> when the init function is not there for cpuidle.
> 
> I don't think it is a problem, but as ARM/ARM64 are sharing the same
> cpuidle-arm.c driver it would make sense to unify the behavior
> between both archs.

I agree and I think it makes sense to have an arm back-end that fails
if there is no cpuidle_ops.init function registered, I doubt any
usage of the cpuidle_ops.suspend is reasonable if it was not
initialized by a corresponding cpuidle_ops.init at boot, at least
that's how I see it working, I am open to other point of views.

Thanks,
Lorenzo


Re: [RFC PATCH 09/11] drivers: acpi: implement acpi_dma_configure

2016-04-22 Thread Lorenzo Pieralisi
Hi Andy,

On Fri, Apr 22, 2016 at 01:45:38AM +0300, Andy Shevchenko wrote:
> On Thu, Apr 14, 2016 at 8:25 PM, Lorenzo Pieralisi
> <lorenzo.pieral...@arm.com> wrote:
> > On DT based systems, the of_dma_configure() API implements DMA configuration
> > for a given device. On ACPI systems an API equivalent to of_dma_configure()
> > is missing which implies that it is currently not possible to set-up DMA
> > operations for devices through the ACPI generic kernel layer.
> >
> > This patch fills the gap by introducing acpi_dma_configure/deconfigure()
> > calls, that carry out IOMMU configuration through IORT (on systems where
> > it is present) and call arch_setup_dma_ops(...) with the retrieved
> > parameters.
> >
> > The DMA range size passed to arch_setup_dma_ops() is sized according
> > to the device coherent_dma_mask (starting at address 0x0), mirroring the
> > DT probing path behaviour when a dma-ranges property is not provided
> > for the device being probed; this changes the current arch_setup_dma_ops()
> > call parameters in the ACPI probing case, but since arch_setup_dma_ops()
> > is a NOP on all architectures but ARM/ARM64 this patch does not change
> > the current kernel behaviour on them.
> >
> > This patch updates ACPI and PCI core code to use the newly introduced
> > acpi_dma_configure function, providing the same functionality
> > as of_dma_configure on ARM systems and leaving behaviour unchanged
> > for all other arches.
> >
> 
> Nitpicks below.

Thanks for having a look.

> > --- a/drivers/acpi/iort.c
> > +++ b/drivers/acpi/iort.c
> > @@ -72,6 +72,31 @@ int iort_iommu_set_node(struct iommu_ops *ops, struct 
> > acpi_iort_node *node,
> > return 0;
> >  }
> >
> > +/**
> > + * iort_iommu_get_node - Retrieve iort_iommu_node associated with an IORT 
> > node.
> > + *
> > + * @node: IORT table node to be looked-up
> > + *
> > + * Returns: iort_iommu_node pointer on success
> > + *  NULL on failure
> > + */
> > +static struct iort_iommu_node *iort_iommu_get_node(struct acpi_iort_node 
> > *node)
> > +{
> > +   struct iort_iommu_node *iommu_node;
> > +
> > +   spin_lock(_iommu_lock);
> > +   list_for_each_entry(iommu_node, _iommu_list, list) {
> > +   if (iommu_node->node == node)
> > +   goto found;
> > +   }
> > +
> > +   iommu_node = NULL;
> > +found:
> > +   spin_unlock(_iommu_lock);
> > +
> > +   return iommu_node;
> 
> Ouch, and why not to
> 
> strut iommu_node = NULL;
> 
> lock
> list for each() {
>  if ()
>   break;
> }
> unlock
> 
> return iommu_node;

To make sure iommu_node is NULL if no node is found, but this list handling
function needs updating anyway (both locking and list handling), so I will
rework it and take your suggestion into account, I agree it is not that
readable (or safe to begin with).

> ?
> 
> > +}
> 
> 
> > +/**
> > + * iort_iommu_configure - Set-up IOMMU configuration for a device.
> > + *
> > + * @dev: device that requires IOMMU set-up
> > + *
> > + * Returns: iommu_ops pointer on configuration success
> > + *  NULL on configuration failure
> > + */
> > +struct iommu_ops *iort_iommu_configure(struct device *dev)
> > +{
> > +   struct acpi_iort_node *node, *parent;
> > +   struct iommu_ops *ops = NULL;
> > +   struct iommu_fwspec fwspec;
> > +   struct iort_iommu_node *iommu_node;
> > +   u32 rid = 0, devid = 0;
> > +
> > +   if (dev_is_pci(dev)) {
> > +   struct pci_bus *bus = to_pci_dev(dev)->bus;
> > +
> > +   pci_for_each_dma_alias(to_pci_dev(dev), __get_pci_rid,
> > +  );
> > +
> > +   node = iort_scan_node(ACPI_IORT_NODE_PCI_ROOT_COMPLEX,
> > + iort_find_dev_callback, >dev);
> 
> > +   } else
> 
> checkpatch.pl ?

checkpatch.pl --strict does not even barf at it. I will add the braces
and go check why checkpatch.pl is quiet :)

> > +   node = iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT,
> > + iort_find_dev_callback, dev);
> > +
> > +   if (!node)
> > +   return NULL;
> > +
> > +   iort_dev_map_rid(node, rid, , ACPI_IORT_NODE_SMMU);
> > +
> > +   parent = iort_find_parent_node(node, ACPI_IORT_NODE_SMMU);
> 
> > +
> 
> Redundant.

Ok.

Thanks,
Lorenzo

> 

> > +   if (!parent)
> > +   return NULL;
> > +
> > +   iommu_node = iort_iommu_get_node(parent);
> > +   ops = iommu_node->ops;
> > +
> > +   fwspec.fwnode = iommu_node->fwnode;
> > +   fwspec.param_count = 1;
> > +   fwspec.param[0] = devid;
> > +
> > +   if (!ops || !ops->fw_xlate || ops->fw_xlate(dev, ))
> > +   return NULL;
> > +
> > +   return ops;
> > +}
> > +
> 
> -- 
> With Best Regards,
> Andy Shevchenko
> 


Re: [PATCH V6 08/13] PCI: generic, thunder: update to use generic ECAM API

2016-04-29 Thread Lorenzo Pieralisi
On Thu, Apr 28, 2016 at 05:47:15PM -0400, Jon Masters wrote:

[...]

> >>> In general, there's no reason we can't reassign BARs, whether we're
> >>> using DT, ACPI, or whatever.  In many cases, systems with ACPI also
> >>> assign all the BARs in firmware, and Linux doesn't reassign them
> >>> unless it needs to.  But that's just a coincidence.  There's no
> >>> requirement that Linux leave BARs as firmware programmed them.
> 
> There's no requirement, generally, that PCI compliant devices with ECAM
> can't be programmed with different base addresses. There's this PCI
> change called EA that is disjoint and some vendors have chosen to use
> it. We didn't catch that early in the definition of the SBSA for ARM,
> but just as an aside, I have already suggested we require future
> generations of chips to not use EA and only support writeable BARs (even
> for the decoders in the on-SoC platformish devices doing "PCI"). This
> isn't Cavium's fault - they did the right thing with the data at hand
> and nobody really considered the impact of PCI getting EA added. Again,
> that's something that will likely happen on x86 at some point (maybe it
> already is, I don't get any data about future Intel stuff).

PCI EA support in the kernel was implemented by Intel, for the records.

And I do not think anyone is questioning EA here (I mean implemented
through a real PCI capability, not config space quirks).

> On the rest of the quirks and hacks. Without going into too much detail,
> some "concerned citizens" are chatting with various folks to ensure that
> many of these common quirks aren't needed in future parts.
> 
> >> I'm thought I've seen systems in which the ACPI BIOS assumes that
> >> certain PCI devices never move around, because it pokes the registers
> >> from AML, and changing them would require never using the same device
> >> through ACPI. It's likely that this is against some standard, but that
> >> won't help you if you have to deal with the system anyway.
> 
> Right. This has happened, I think, and there you're no worse off on ARM
> than you would be on x86 if you had AML poking at something underneath.

Except that (if I read their code correctly - arch/x86/pci/i386.c,
see pcibios_resource_survey()) X86 claims the resources as
set-up by FW and thus does not reassign them, whereas on ARM we reassign
the whole PCI address space and we totally ignore the FW set-up (in DT
and ACPI alike), whether that's a problem or not time will tell,
as Bjorn mentioned I do not think that by the time FW hands over to
the OS there is any requirement whatsoever that prevents the OS
from reprogramming the PCI BARs set-up.

> > Yes, I'm pretty sure there are systems like that, e.g., I think SMM
> > code on some HP servers assumes the iLO address never changes.  I
> > think that is a firmware defect because I don't think there's any spec
> > that says firmware retains control over PCI BARs after handoff.  And
> > this particular case isn't really ACPI-specific.
> 
> If you substitute SMM for EL3 on ARM we're bound to eventually have the
> same kinds of things happening on some systems. It's just life.
> 
> > But as you say, we have to deal with these systems anyway, even if we
> > consider that behavior broken.  My proposal has been to add quirks to
> > mark those devices as IORESOURCE_PCI_FIXED, but I don't think anybody
> > has gotten around to doing that.

Well, that's going to be interesting. To me it is more something FW
should be able to communicate to the OS rather than a device specific
quirk, it is not that the device has fixed BARs, it is that the FW
expects them to be immutable (not saying that's the correct FW
behaviour - but it looks like a FW specific issue, not device specific).

I wonder whether this can be solved (at least in ACPI) through
a PCI BAR Target Operation Region (ACPI 6.0, 5.5.2.4.2), I will have
a look into that.

Lorenzo


Re: [PATCH V6 09/13] pci, acpi: Support for ACPI based generic PCI host controller

2016-04-29 Thread Lorenzo Pieralisi
On Thu, Apr 28, 2016 at 04:48:00PM -0500, Bjorn Helgaas wrote:

[...]

> > +static int pci_acpi_setup_ecam_mapping(struct acpi_pci_root *root,
> > +  struct acpi_pci_generic_root_info *ri)
> > +{
> > +   u16 seg = root->segment;
> > +   u8 bus_start = root->secondary.start;
> > +   u8 bus_end = root->secondary.end;
> > +   struct pci_config_window *cfg;
> > +   struct mcfg_entry *e;
> > +   phys_addr_t addr;
> > +   int err = 0;
> > +
> > +   mutex_lock(_mcfg_lock);
> 
> What does this lock protect?  The pci_mcfg_list should already be
> initialized by the time we get there, and it should be immutable for
> the life of the system.  In fact, I would prefer if we could just
> search the static table itself whenever we need it rather than caching
> it in our own list.  But I don't think we can easily do that because
> acpi_table_parse() is __init.
> 
> > +   e = pci_mcfg_lookup(seg, bus_start);
> 
> I would argue that we should check for _CBA first, and fall back to
> MCFG if _CBA doesn't exist.
> 
> > +   if (!e) {
> > +   addr = acpi_pci_root_get_mcfg_addr(root->device->handle);
> 
> IMO, acpi_pci_root_get_mcfg_addr() is misnamed.  It should be
> acpi_pci_config_base_addr() or similar.  It definitely is not related
> to MCFG.  Not your fault, obviously.
> 
> > +   if (addr == 0) {
> > +   pr_err(PREFIX"%04x:%02x-%02x bus range error\n",
> > +  seg, bus_start, bus_end);
> > +   err = -ENOENT;
> > +   goto err_out;
> > +   }
> > +   } else {
> > +   if (bus_start != e->bus_start) {
> > +   pr_err("%04x:%02x-%02x bus range mismatch %02x\n",
> > +  seg, bus_start, bus_end, e->bus_start);
> > +   err = -EINVAL;
> > +   goto err_out;
> > +   } else if (bus_end != e->bus_end) {
> > +   pr_warn("%04x:%02x-%02x bus end mismatch %02x\n",
> > +   seg, bus_start, bus_end, e->bus_end);
> > +   bus_end = min(bus_end, e->bus_end);
> > +   }
> > +   addr = e->addr;
> > +   }
> 
> I really don't think you need a lock around this, so you can factor
> out the address lookup into something like:
> 
>   addr = acpi_pci_config_base_addr(...);
>   if (addr)
> return addr;
> 
>   return acpi_pci_mcfg_lookup(seg, busn_res);
> 
> You can check inside acpi_pci_mcfg_lookup() to make sure the entry you
> find covers the entire [busn_res.start-busn_res.end] range and return
> failure if it doesn't.  At this point, I'm not sure it's worth it to
> truncate the host bridge bus range to match something we find in MCFG.
> 
> If the MCFG entry covers *more* than the host bridge range from _CRS,
> that's fine.  In any case, we have to be careful with the start address,
> because the MCFG start address is always based on bus 0, but I think
> pci_generic_ecam_create() expects the start address based on the
> bus_start you pass to it.

Yes, I spotted this too, it is unfortunate but DT and MCFG handle
the ECAM regions differently. In DT the reg property is relative
to bus_start - ie reg MMIO region maps config space starting at
the first bus in bus-range:

Documentation/devicetree/bindings/pci/host-generic-pci.txt

in ACPI(MCFG) as you said it is always relative to bus 0, it is
unfortunate but the address to be mapped should be computed
differently in the ECAM layer.

Lorenzo


Re: [PATCH] arm64: Relocate screen_info.lfb_base on PCI BAR allocation

2016-04-29 Thread Lorenzo Pieralisi
On Thu, Apr 28, 2016 at 11:39:35PM +0200, Alexander Graf wrote:
> 
> 
> On 28.04.16 20:06, Bjorn Helgaas wrote:
> > On Thu, Apr 28, 2016 at 06:41:42PM +0200, Alexander Graf wrote:
> >> On 04/28/2016 06:20 PM, Bjorn Helgaas wrote:
> >>> On Thu, Apr 28, 2016 at 12:22:24AM +0200, Alexander Graf wrote:
>  When booting with efifb, we get a frame buffer address passed into the 
>  system.
>  This address can be backed by any device, including PCI devices.
> >>> I guess we get the frame buffer address via EFI, but it doesn't tell
> >>> us what PCI device it's connected to?
> >>
> >> Pretty much, yes. We can get the frame buffer address from a
> >> multitude of sources using various boot protocols, but the case
> >> where I ran into this was with efi on arm64.
> >>
> >>> This same thing could happen on any EFI arch, I guess.  Maybe even on
> >>
> >> Yes and no :). I would've put it into whatever code "owns"
> >> screen_info, but I couldn't find any. So instead I figured I'd make
> >> the approach as generic as I could and implemented the calculation
> >> for the case where I saw it break.
> >>
> >> The reason we don't see this on x86 (if I understand all pieces of
> >> the puzzle correctly) is that we get the BAR allocation from
> >> firmware using _CRS attributes in ACPI, so firmware tells the OS
> >> where to put the BARs. 
> > 
> > I think the real reason is that on x86, firmware typically assigns all
> > the BARs and Linux typically doesn't change them.  PCI host bridges
> 
> Can you point me to the code that "doesn't change them"? I couldn't find
> it, but I haven't see Linux reallocate BARs on x86.
> 
> The thing is that if a BAR is already allocated, we could as well not
> remap it on arm as well - but how do we know?

We don't. Long story short: if I understand X86 code correctly,
on X86 PCI resources are claimed at boot:

arch/x86/pci/i386.c (pcibios_resource_survey())

which means that if the BARs are set-up in a way that passes the resource
claiming validation tests (ie the resource fits into the resource tree),
the BAR resources are inserted into the resource tree and are not touched
by the code that reassigns the PCI resources.

Ergo, FW set-up is kept intact, that's my understanding of X86 code.

The other way of preventing a PCI resource to be moved is by marking it
IORESOURCE_PCI_FIXED, I am not sure that's what X86 does in your specific
case though.

> > have _CRS, which tells us where the host bridge windows are.  PCI
> > devices themselves don't normally have _CRS; we just make sure their
> > BARs are inside the ranges of an upstream _CRS.  If/when we get x86
> > boxes where firmware doesn't assign all the BARs, we should see the
> > same problem there.
> 
> So the check is whether all BARs get assigned by firmware?

Eheh, the problem, and I am glad that you raised the point, is how
do we know that FW assigned the BARs ? The only thing we can do is
we try to claim the BAR resource, if it fits into the resource tree
we successfully claim the resource and the kernel won't reassign it.

On ARM PCI resources are never claimed, they are always reassigned,
and that's the reason why you are experiencing these failures.

> >> In the device tree case (which is what I'm
> >> running on arm64) we however allocate BARs dynamically.
> >>
> >>> non-EFI arches, if there's a way to discover the frame buffer address
> >>> as a bare address rather than a "offset X into BAR Y of PCI device Z"
> >>> sort of thing.
> >>
> >> It'd be perfectly doable today - we do get a cpu physical address
> >> and use that in the notifier. All we would need to do is move the
> >> code that I added in arm64/efi.c to something more generic that
> >> "owns" the frame buffer address. Then any boot protocol that passes
> >> a screen_info in would get the frame buffer relocated on BAR remap.
> > 
> > We could consider a quirk that would mark any BAR that happened to
> > contain the frame buffer address as IORESOURCE_PCI_FIXED.  That would
> > (in theory, anyway) keep the PCI core from moving it.
> 
> That's what I thought I should do at first. Then I realized that we
> could have a PCIe GPU in the system that provides a really big BAR which
> we would need to map into an mmio64 region to make full use of it.
> Firmware however - because of limitations - only maps it into the mmio32
> space though.
> 
> That means we now break a case that would work without efifb, right?
> 
> > Is there any run-time EFI (or other firmware) dependency on the frame
> > buffer address?  If there is, things will break when we move it, even
> > if we have your notifier to tell efifb about it.
> 
> Simple answer is no :).
> 
> >> Drivers like vesafb might benefit from this as well - though
> >> apparently x86 fixed this using ACPI.
> > 
> > Where is this x86 vesafb ACPI fix?  I don't see anything ACPI-related
> > in drivers/video/fbdev/vesafb.c.  I'm just curious what this fix looks
> > like.
> 
> I don't know of any - I haven't found the code that 

Re: [PATCH V6 05/13] acpi, pci: Support IO resources when parsing PCI host bridge resources.

2016-04-27 Thread Lorenzo Pieralisi
On Wed, Apr 27, 2016 at 04:10:36PM +0100, liviu.du...@arm.com wrote:
> On Wed, Apr 27, 2016 at 03:26:59PM +0100, Lorenzo Pieralisi wrote:
> > On Tue, Apr 26, 2016 at 09:39:16PM -0500, Bjorn Helgaas wrote:
> > > On Fri, Apr 15, 2016 at 07:06:40PM +0200, Tomasz Nowicki wrote:
> > > > Platforms that have memory mapped IO port (such as ARM64) need special
> > > > handling for PCI I/O resources. For host bridge's resource probing case
> > > > these resources need to be fixed up with 
> > > > pci_register_io_range/pci_remap_iospace etc.
> > > 
> > > ia64 also has memory-mapped I/O port space.  It would be ideal to find
> > > some way to handle ia64 and ARM64 similarly.  At the very least, we
> > > have to make sure that this doesn't break ia64.  The ia64 dense/sparse
> > > I/O spaces complicate things; I don't know if ARM64 has something
> > > similar or not.
> > 
> > No it does not, and that's exactly the same problem we faced with
> > the DT generic version of of_pci_range_to_resource() which basically
> > relies on PCI_IOBASE to be defined to add code that creates IO port
> > resources out of the MMIO resource describing how IO port space is
> > mapped to MMIO (physical) address space.
> > 
> > IIRC everything hinges on PCI_IOBASE definition to make sure that
> > of_pci_range_to_resource() *works*, which means that if PCI_IOBASE is
> > not defined (ie IA64) that code - acpi_pci_root_remap_iospace() in this
> > case - does nothing.
> > 
> > So acpi_pci_root_remap_iospace() is of_pci_range_to_resource() ACPI
> > equivalent + the pci_remap_iospace() call (I have to dig into the
> > logs to check why Liviu did not add a call to pci_remap_iospace()
> > in of_pci_get_host_bridge_resources() - I want to do that actually).
> 
> Because of_pci_get_host_bridge_resources() only gives you a list of
> resources, it doesn't allocate them. An arch or platform could add
> further filtering to that list before it gets requested (in our case
> it is done in pci-host-common.c)

Well, it does register the IO cpu physical address in pci_register_io_range()
though, if pci_remap_iospace() fails in arch/platform code we can delete the
resource but we must also unregister the corresponding cpu address from
the IO ranges otherwise we end up with stale entries in the io_range_list.

Anyway, it is not related to this thread, I will see what I can do
to improve that API from this standpoint.

Thanks !
Lorenzo

> 
> Best regards,
> Liviu
> 
> > 
> > The point here is: IO space (in DT and ACPI) handling is arch specific.
> > 
> > For DT, by relying on PCI_IOBASE, we left that code in drivers/of and
> > it works (well, with some niggles - see the thread with Murali on IO
> > space on TI keystone) for ARM/ARM64.
> > 
> > http://www.spinics.net/lists/linux-pci/msg49725.html
> > 
> > What are we going to do with the ACPI version ?
> > 
> > Do we want to add an arch specific call that takes the raw resource
> > describing IO space and creates an IO port resource (and the MMIO
> > equivalent - that's what add_io_space() does in IA64) and use that
> > in generic ACPI parsing code ?
> > 
> > Or we just do what Tomasz does, which is basically the approach we took
> > for DT ?
> > 
> > > > Furthermore, the same I/O resources need to be released after hotplug
> > > > removal so that it can be re-added back by the pci_remap_iospace
> > > > function during insertion. Therefore we implement new pci_unmap_iospace 
> > > > call
> > > > which unmaps I/O space as the symmetry to pci_remap_iospace.
> > > 
> > > "Furthermore" is a hint that we should check to see if this can be
> > > split into two patches.
> > > 
> > > We already have a pci_remap_iospace(), and you're adding
> > > pci_unmap_iospace(), which will be used for hotplug removal.  So let's 
> > > add pci_unmap_iospace() first in a patch by itself because that's
> > > potentially useful for other callers of pci_remap_iospace(), even if
> > > they don't need the acpi_pci_root_remap_iospace() stuff.
> > 
> > I agree.
> > 
> > Thanks,
> > Lorenzo
> > 
> > > > Signed-off-by: Jayachandran C <jchan...@broadcom.com>
> > > > Signed-off-by: Sinan Kaya <ok...@codeaurora.org>
> > > > Signed-off-by: Tomasz Nowicki <t...@semihalf.com>
> > > > ---
> > > >  drivers/acpi/pci_root.c | 33 +
> > > >  drivers/pci/pci.c   | 24 
&g

Re: [PATCH V6 02/13] pci, acpi: Provide generic way to assign bus domain number.

2016-04-27 Thread Lorenzo Pieralisi
On Wed, Apr 27, 2016 at 11:44:53AM -0500, Bjorn Helgaas wrote:
> On Wed, Apr 27, 2016 at 12:17:58PM +0100, Lorenzo Pieralisi wrote:
> > On Tue, Apr 26, 2016 at 09:26:49PM -0500, Bjorn Helgaas wrote:
> > > On Fri, Apr 15, 2016 at 07:06:37PM +0200, Tomasz Nowicki wrote:
> > > > As we now have valid PCI host bridge device reference we can
> > > > introduce code that is going to find its bus domain number using
> > > > ACPI _SEG method.
> > > > 
> > > > Note that _SEG method is optional, therefore _SEG absence means
> > > > that all PCI buses belong to domain 0.
> > > > 
> > > > While at it, for the sake of code clarity we put ACPI and DT domain
> > > > assign methods into the corresponding helpers.
> > > > 
> > > > Signed-off-by: Tomasz Nowicki <t...@semihalf.com>
> > > > Reviewed-by: Liviu Dudau <liviu.du...@arm.com>
> > > > Tested-by: Suravee Suthikulpanit <suravee.suthikulpa...@amd.com>
> > > > Tested-by: Jeremy Linton <jeremy.lin...@arm.com>
> > > > Tested-by: Duc Dang <dhd...@apm.com>
> > > > Tested-by: Dongdong Liu <liudongdo...@huawei.com>
> > > > Tested-by: Hanjun Guo <hanjun@linaro.org>
> > > > Tested-by: Graeme Gregory <graeme.greg...@linaro.org>
> > > > Tested-by: Sinan Kaya <ok...@codeaurora.org>
> > > > ---
> > > >  drivers/acpi/pci_root.c  | 18 ++
> > > >  drivers/pci/pci.c| 11 +--
> > > >  include/linux/pci-acpi.h |  2 ++
> > > >  3 files changed, 29 insertions(+), 2 deletions(-)
> > > > 
> > > > diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
> > > > index 4581e0e..d9a70c4 100644
> > > > --- a/drivers/acpi/pci_root.c
> > > > +++ b/drivers/acpi/pci_root.c
> > > > @@ -419,6 +419,24 @@ out:
> > > >  }
> > > >  EXPORT_SYMBOL(acpi_pci_osc_control_set);
> > > >  
> > > > +int acpi_pci_bus_domain_nr(struct device *parent)
> 
> It looks like acpi_pci_bus_domain_nr() could be under #ifdef
> CONFIG_PCI_DOMAINS_GENERIC, right?

Yes it should.

> > > > +{
> > > > +   struct acpi_device *acpi_dev = to_acpi_device(parent);
> > > > +   unsigned long long segment = 0;
> > > > +   acpi_status status;
> > > > +
> > > > +   /*
> > > > +* If _SEG method does not exist, following ACPI spec (6.5.6)
> > > > +* all PCI buses belong to domain 0.
> > > > +*/
> > > > +   status = acpi_evaluate_integer(acpi_dev->handle, 
> > > > METHOD_NAME__SEG, NULL,
> > > > +  );
> > > 
> > > We already have code in acpi_pci_root_add() to evaluate _SEG.  We
> > > don't want to evaluate it *twice*, do we?
> > > 
> > > I was sort of expecting that if you added it here, we'd remove the
> > > existing call, but it looks like you're keeping both?
> > 
> > We can't remove the existing call, since it is used on X86 and IA64
> > to store the segment number that, in the process, is used in their
> > pci_domain_nr() arch specific callback to retrieve the domain nr.
> > 
> > On ARM64, that selects PCI_DOMAINS_GENERIC, we have to find a way
> > to retrieve the domain number that is not arch dependent, since
> > this is generic code, we can't rely on any bus->sysdata format (unless
> > we do something like JC did below), therefore the only way is to call
> > the _SEG method *again* here, which also forced Tomasz to go through
> > the ACPI_COMPANION setting song and dance and pass the parent pointer
> > to pci_create_root_bus() (see patch 1), which BTW is a source of
> > trouble on its own as you noticed.
> > 
> > JC solved it differently, via sysdata and pseudo-generic code:
> > 
> > http://www.spinics.net/lists/arm-kernel/msg478167.html
> 
> The thing I don't like about this is the special case of checking
> parent and parent->of_node to figure out whether we should use the
> segment from ACPI and the fragility of depending on the fact that the
> companion hasn't been set yet.
> 
> > http://www.spinics.net/lists/arm-kernel/msg478169.html
> > 
> > I like neither, we need the lesser of two evils though.
> 
> Today we call pci_bus_assign_domain_nr() from the PCI core (from
> pci_create_root_bus()).  This is only implemented for
> PCI_DOMAINS_GENERIC, but even s

Re: [PATCH V6 02/13] pci, acpi: Provide generic way to assign bus domain number.

2016-04-27 Thread Lorenzo Pieralisi
On Tue, Apr 26, 2016 at 09:26:49PM -0500, Bjorn Helgaas wrote:
> On Fri, Apr 15, 2016 at 07:06:37PM +0200, Tomasz Nowicki wrote:
> > As we now have valid PCI host bridge device reference we can
> > introduce code that is going to find its bus domain number using
> > ACPI _SEG method.
> > 
> > Note that _SEG method is optional, therefore _SEG absence means
> > that all PCI buses belong to domain 0.
> > 
> > While at it, for the sake of code clarity we put ACPI and DT domain
> > assign methods into the corresponding helpers.
> > 
> > Signed-off-by: Tomasz Nowicki 
> > Reviewed-by: Liviu Dudau 
> > Tested-by: Suravee Suthikulpanit 
> > Tested-by: Jeremy Linton 
> > Tested-by: Duc Dang 
> > Tested-by: Dongdong Liu 
> > Tested-by: Hanjun Guo 
> > Tested-by: Graeme Gregory 
> > Tested-by: Sinan Kaya 
> > ---
> >  drivers/acpi/pci_root.c  | 18 ++
> >  drivers/pci/pci.c| 11 +--
> >  include/linux/pci-acpi.h |  2 ++
> >  3 files changed, 29 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
> > index 4581e0e..d9a70c4 100644
> > --- a/drivers/acpi/pci_root.c
> > +++ b/drivers/acpi/pci_root.c
> > @@ -419,6 +419,24 @@ out:
> >  }
> >  EXPORT_SYMBOL(acpi_pci_osc_control_set);
> >  
> > +int acpi_pci_bus_domain_nr(struct device *parent)
> > +{
> > +   struct acpi_device *acpi_dev = to_acpi_device(parent);
> > +   unsigned long long segment = 0;
> > +   acpi_status status;
> > +
> > +   /*
> > +* If _SEG method does not exist, following ACPI spec (6.5.6)
> > +* all PCI buses belong to domain 0.
> > +*/
> > +   status = acpi_evaluate_integer(acpi_dev->handle, METHOD_NAME__SEG, NULL,
> > +  );
> 
> We already have code in acpi_pci_root_add() to evaluate _SEG.  We
> don't want to evaluate it *twice*, do we?
> 
> I was sort of expecting that if you added it here, we'd remove the
> existing call, but it looks like you're keeping both?

We can't remove the existing call, since it is used on X86 and IA64
to store the segment number that, in the process, is used in their
pci_domain_nr() arch specific callback to retrieve the domain nr.

On ARM64, that selects PCI_DOMAINS_GENERIC, we have to find a way
to retrieve the domain number that is not arch dependent, since
this is generic code, we can't rely on any bus->sysdata format (unless
we do something like JC did below), therefore the only way is to call
the _SEG method *again* here, which also forced Tomasz to go through
the ACPI_COMPANION setting song and dance and pass the parent pointer
to pci_create_root_bus() (see patch 1), which BTW is a source of
trouble on its own as you noticed.

JC solved it differently, via sysdata and pseudo-generic code:

http://www.spinics.net/lists/arm-kernel/msg478167.html
http://www.spinics.net/lists/arm-kernel/msg478169.html

I like neither, we need the lesser of two evils though.

Lorenzo

> > +   if (ACPI_FAILURE(status) && status != AE_NOT_FOUND)
> > +   dev_err(_dev->dev, "can't evaluate _SEG\n");
> > +
> > +   return segment;
> > +}
> > +
> >  static void negotiate_os_control(struct acpi_pci_root *root, int *no_aspm)
> >  {
> > u32 support, control, requested;
> > diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
> > index 25e0327..1a74e87 100644
> > --- a/drivers/pci/pci.c
> > +++ b/drivers/pci/pci.c
> > @@ -19,6 +19,7 @@
> >  #include 
> >  #include 
> >  #include 
> > +#include 
> >  #include 
> >  #include 
> >  #include 
> > @@ -4779,7 +4780,7 @@ int pci_get_new_domain_nr(void)
> >  }
> >  
> >  #ifdef CONFIG_PCI_DOMAINS_GENERIC
> > -void pci_bus_assign_domain_nr(struct pci_bus *bus, struct device *parent)
> > +static int of_pci_bus_domain_nr(struct device *parent)
> >  {
> > static int use_dt_domains = -1;
> > int domain = -1;
> > @@ -4823,7 +4824,13 @@ void pci_bus_assign_domain_nr(struct pci_bus *bus, 
> > struct device *parent)
> > domain = -1;
> > }
> >  
> > -   bus->domain_nr = domain;
> > +   return domain;
> > +}
> > +
> > +void pci_bus_assign_domain_nr(struct pci_bus *bus, struct device *parent)
> > +{
> > +   bus->domain_nr = acpi_disabled ? of_pci_bus_domain_nr(parent) :
> > +acpi_pci_bus_domain_nr(parent);
> >  }
> >  #endif
> >  #endif
> > diff --git a/include/linux/pci-acpi.h b/include/linux/pci-acpi.h
> > index 89ab057..a72e22d 100644
> > --- a/include/linux/pci-acpi.h
> > +++ b/include/linux/pci-acpi.h
> > @@ -22,6 +22,7 @@ static inline acpi_status 
> > pci_acpi_remove_pm_notifier(struct acpi_device *dev)
> >  {
> > return acpi_remove_pm_notifier(dev);
> >  }
> > +extern int acpi_pci_bus_domain_nr(struct device *parent);
> >  extern phys_addr_t acpi_pci_root_get_mcfg_addr(acpi_handle handle);
> >  
> >  static 

Re: [PATCH V6 06/13] arm64, pci, acpi: ACPI support for legacy IRQs parsing and consolidation with DT code.

2016-04-27 Thread Lorenzo Pieralisi
On Tue, Apr 26, 2016 at 09:44:30PM -0500, Bjorn Helgaas wrote:
> On Fri, Apr 15, 2016 at 07:06:41PM +0200, Tomasz Nowicki wrote:
> > To enable PCI legacy IRQs on platforms booting with ACPI, arch code
> > should include ACPI specific callbacks that parse and set-up the
> > device IRQ number, equivalent to the DT boot path. Owing to the current
> > ACPI core scan handlers implementation, ACPI PCI legacy IRQs bindings
> > cannot be parsed at device add time, since that would trigger ACPI scan
> > handlers ordering issues depending on how the ACPI tables are defined.
> 
> Can you be a little more specific about the issue here?  I think you
> mean pci_device_add()-time, because that's where we call
> pcibios_add_device.  Which ACPI tables are involved?  _PRT?  Why is
> that a problem?  We don't cache those tables any more after
> 181380b702ee ("PCI/ACPI: Don't cache _PRT, and don't associate them
> with bus numbers").

https://lists.linaro.org/pipermail/linaro-acpi/2015-October/005944.html

I think it is a scan handler ordering issue and probably by caching
_PRT this problem would not exist but I have to read the commit above
in details to understand if that's the case.

> x86 and ia64 both call acpi_pci_irq_enable() from
> pcibios_enable_device().  Could you do the same on ARM64?
> pcibios_enable_device() happens later than either pci_device_add() or
> pci_device_probe().

We could in theory. In practice we have to see if that triggers DT
regressions on PCI host controllers that do not call pci_fixup_irqs(),
but rely on the legacy IRQ routing to be done in arm64
pcibios_add_device().

> > To solve this problem and consolidate FW PCI legacy IRQs parsing in
> > one single pcibios callback (pending final removal), this patch moves
> > DT PCI IRQ parsing to the pcibios_alloc_irq() callback (called by
> > PCI core code at device probe time) and adds ACPI PCI legacy IRQs
> > parsing to the same callback too, so that FW PCI legacy IRQs parsing
> > is confined in one single arch callback that can be easily removed
> > when code parsing PCI legacy IRQs is consolidated and moved to core
> > PCI code.
> > 
> > Signed-off-by: Tomasz Nowicki <t...@semihalf.com>
> > Suggested-by: Lorenzo Pieralisi <lorenzo.pieral...@arm.com>
> > ---
> >  arch/arm64/kernel/pci.c | 11 ---
> >  1 file changed, 8 insertions(+), 3 deletions(-)
> > 
> > diff --git a/arch/arm64/kernel/pci.c b/arch/arm64/kernel/pci.c
> > index c72de66..15109c11 100644
> > --- a/arch/arm64/kernel/pci.c
> > +++ b/arch/arm64/kernel/pci.c
> > @@ -50,11 +50,16 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
> >  }
> >  
> >  /*
> > - * Try to assign the IRQ number from DT when adding a new device
> > + * Try to assign the IRQ number when probing a new device
> >   */
> > -int pcibios_add_device(struct pci_dev *dev)
> > +int pcibios_alloc_irq(struct pci_dev *dev)
> >  {
> > -   dev->irq = of_irq_parse_and_map_pci(dev, 0, 0);
> > +   if (acpi_disabled)
> > +   dev->irq = of_irq_parse_and_map_pci(dev, 0, 0);
> > +#ifdef CONFIG_ACPI
> > +   else
> > +   return acpi_pci_irq_enable(dev);
> > +#endif
> 
> Not your problem, but your patch makes it obvious: it's ugly that we
> set dev->irq to the IRQ returned from of_irq_parse_and_map_pci(), but
> acpi_pci_irq_enable() sets dev->irq internally.
> 
> x86 also has the situation of calling either acpi_pci_irq_enable() or
> of_irq_parse_and_map_pci(), and it looks like they can even decide at
> run-time as you can here.  If we're solving the same problem, can we
> use a similar mechanism?  x86 sets a pcibios_enable_irq function
> pointer.

Yes we could, but that's orthogonal to this patch, it's basically
rewriting this code in a different way and adding flexibility to the
function mapping irqs.

Thanks,
Lorenzo

> 
> > return 0;
> >  }
> > -- 
> > 1.9.1
> > 
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-pci" in
> > the body of a message to majord...@vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 


Re: [PATCH 3/3] ACPI: ARM64: support for ACPI_TABLE_UPGRADE

2016-05-23 Thread Lorenzo Pieralisi
On Tue, May 17, 2016 at 12:48:53PM -0400, Jon Masters wrote:
> On 05/17/2016 12:44 PM, Jon Masters wrote:
> 
> > 1). During development of a platform, it is much easier to debug
> > problems with tables if you can test replacement ones without having to
> > respin the firmware. In the server world, you usually don't have the
> > firmware source code, so to get it respun could be days-weeks even if
> > you are working with the authors closely. We have practically used this
> > feature on a number of platforms already and it will continue.
> 
> For example, on one platform we were unable to fully boot RHEL(SA) due
> to a bug in one of the ACPI tables. But I was able to boot the system to
> a ramdisk containing a uuencode library and then write out the content
> of the tables over the serial port, then decompile/patch/recompile, and
> override replacement tables on the system. Then we beat the vendor up
> with the fixes and the official firmware was corrected.

Can you explain to me please why you can't do it with GRUB ?

I am using mainline GRUB and its acpi command all the time to update
static ACPI tables for testing new features (ie IORT) and it works
just fine for me (and you can still override the DSDT, which is
likely to be the main source of bugs, through the CONFIG_ACPI_CUSTOM_DSDT
config option, that works on ARM in mainline with no changes required).

I just want to understand if there is really a compelling reason
for adding this stuff when we can easily implement its features
through something that is usable today without any kernel changes.

Thanks,
Lorenzo


Re: [RFC PATCH] Increase in idle power with schedutil

2016-05-23 Thread Lorenzo Pieralisi
On Sun, May 22, 2016 at 01:42:52PM -0700, Steve Muckle wrote:
> On Sun, May 22, 2016 at 12:39:12PM +0200, Peter Zijlstra wrote:
> > On Fri, May 20, 2016 at 05:53:41PM +0530, Shilpasri G Bhat wrote:
> > > 
> > > Below are the comparisons by disabling watchdog.
> > > Both schedutil and ondemand have a similar ramp-down trend. And in both 
> > > the
> > > cases I can see that frequency of the cpu is not reduced in deterministic
> > > fashion. In a observation window of 30 seconds after running a workload I 
> > > can
> > > see that the frequency is not ramped down on some cpus in the system and 
> > > are
> > > idling at max frequency.
> > 
> > So does it actually matter what the frequency is when you idle? Isn't
> > the whole thing clock gated anyway?
> > 
> > Because this seems to generate contradictory requirements, on the one
> > hand we want to stay idle as long as possible while on the other hand
> > you seem to want to clock down while idle, which requires not being
> > idle.
> > 
> > If it matters; should not your idle state muck explicitly set/restore
> > frequency?
> 
> AFAIK this is very platform dependent. Some will waste more power than
> others when a CPU idles above fmin due to things like resource (bus
> bandwidth, shared cache freq etc) voting.

It is also related to static leakage power that depends on the operating
voltage (ie higher operating frequencies require higher voltage) so in a
way scaling frequency before going idle may not be effective if voltage
does not scale too in turn.

Lorenzo


Re: [PATCH V7 00/11] Support for generic ACPI based PCI host controller

2016-05-23 Thread Lorenzo Pieralisi
On Fri, May 20, 2016 at 11:14:03AM +0200, Ard Biesheuvel wrote:
> On 20 May 2016 at 10:40, Gabriele Paoloni  wrote:
> > Hi Ard
> >
> >> -Original Message-
> >> From: Ard Biesheuvel [mailto:ard.biesheu...@linaro.org]
> [...]
> >>
> >> Is the PCIe root complex so special that you cannot simply describe an
> >> implementation that is not PNP0408 compatible as something else, under
> >> its own unique HID? If everybody is onboard with using ACPI, how is
> >> this any different from describing other parts of the platform
> >> topology? Even if the SBSA mandates generic PCI, they already deviated
> >> from that when they built the hardware, so pretending that it is a
> >> PNP0408 with quirks really does not buy us anything.
> >
> > From my understanding we want to avoid this as this would allow each
> > vendor to come up with his own code and it would be much more effort
> > for the PCI maintainer to rework the PCI framework to accommodate X86
> > and "all" ARM64 Host Controllers...
> >
> > I guess this approach is too risky and we want to avoid this. Through
> > standardization we can more easily maintain the code and scale it to
> > multiple SoCs...
> >
> > So this is my understanding; maybe Jon, Tomasz or Lorenzo can give
> > a bit more explanation...
> >
> 
> OK, so that boils down to recommending to vendors to represent known
> non-compliant hardware as compliant, just so that we don't have to
> change the code to support additional flavors of ECAM ? It's fine to
> be pragmatic, but that sucks.
> 
> We keep confusing the x86 case with the ARM case here: for x86, they
> needed to deal with broken hardware *after* the fact, and all they
> could do is find /some/ distinguishing feature in order to guess which
> exact hardware they might be running on. For arm64, it is the opposite
> case. We are currently in a position where we can demand vendors to
> comply with the standards they endorsed themselves, and (ab)using ACPI
> + DMI as a de facto platform description rather than plain ACPI makes
> me think the DT crowd were actually right from the beginning. It
> *directly* violates the standardization principle, since it requires a
> priori knowledge inside the OS that a certain 'generic' device must be
> driven in a special way.
> 
> So can anyone comment on the feasibility of adding support for devices
> with vendor specific HIDs (and no generic CIDs) to the current ACPI
> ECAM driver in Linux?

Host bridges in ACPI are handled through PNP0A08/PNP0A03 ids, and
most of the arch specific code is handled in the respective arch
directories (X86 and IA64, even though IA64 does not rely on ECAM/MCFG for
PCI ops), it is not a driver per-se, PNP0A08/PNP0A03 are detected through
ACPI scan handlers and the respective arch code (ie pci_acpi_scan_root)
sets-up resources AND config space on an arch specific basis.

X86 deals with that with code in arch/x86 that sets-up the pci_raw_ops
on a platform specific basis (and it is not nice, but it works because
as you all know the number of platforms in X86 world is contained).

Will this happen for ARM64 in arch/arm64 based on vendor specific
HIDs ?

No.

So given the current state of play (we were requested to move the
arch/arm64 specific ACPI PCI bits to arch/arm64), we would end up
with arch/arm64 code requiring code in /drivers to set-up pci_ops
in a platform specific way, it is horrible, if feasible at all.

The only way this can be implemented is by pretending that the
ACPI/PCI arch/arm64 implementation is generic code (that's what this
series does), move it to /drivers (where it is in this series), and
implement _DSD vendor specific bindings (per HID) to set-up the pci
operations; whether this solution should go upstream, given that it
is just a short-term solution for early platforms bugs, it is another
story and my personal answer is no.

Lorenzo


Re: [PATCH V7 00/11] Support for generic ACPI based PCI host controller

2016-05-24 Thread Lorenzo Pieralisi
Hi Bjorn,

On Mon, May 23, 2016 at 06:39:18PM -0500, Bjorn Helgaas wrote:

[...]

> On Mon, May 23, 2016 at 03:16:01PM +, Gabriele Paoloni wrote:
> I don't think of ECAM support itself as a "driver".  It's just a
> service available to drivers, similar to OF resource parsing.
> 
> Per PCI Firmware r3.2, sec 4.1.5, "PNP0A03" means a PCI/PCI-X/PCIe
> host bridge.  "PNP0A08" means a PCI-X Mode 2 or PCIe bridge that
> supports extended config space.  It doesn't specify how we access that
> config space, so I think hardware with non-standard ECAM should still
> have PNP0A03 and PNP0A08 in _CID or _HID.
> 
> "ECAM" as used in the specs (PCIe r3.0, sec 7.2.2, and PCI Firmware
> r3.2, sec 4.1) means:
> 
>   (a) a memory-mapped model for config space access, and
>   (b) a specific mapping of address bits to bus/device/function/
>   register
> 
> MCFG and _CBA assume both (a) and (b), so I think a device with
> non-standard ECAM mappings should not be described in MCFG or _CBA.
> 
> If a bridge has ECAM with non-standard mappings, I think either a
> vendor-specific _HID or a device-specific method, e.g., _DSM, could
> communicate that.
> 
> Jon, I agree that we should avoid describing non-standardized hardware
> in Linux-specific ways.  Is there a mechanism in use already?  How
> does Windows handle this?  DMI is a poor long-term solution because it
> requires ongoing maintenance for new platforms, but I think it's OK
> for getting started with platforms already shipping.
> 
> A _DSM has the advantage that once it is defined and supported, OEMs
> can ship new platforms without requiring a new quirk or a new _HID to
> be added to a driver.
> 
> There would still be the problem of config access before the namespace
> is available, i.e., the MCFG use case.  I don't know how important
> that is.  Defining an MCFG extension seems like the most obvious
> solution.

Your summary above is a perfect representation of the situation.

We had an opportunity to sync-up on the current status of ACPI PCI
for ARM64 (and talked about a way forward for this series, which
includes quirks handling), let me summarize it here for everyone
involved so that we can agree on a way forward.

1) ACPI PCI support for PNP0A03/PNP0A08 host bridges on top of MCFG
   ECAM for config space is basically ready (Tomasz and JC addressed
   Rafael's concerns in relation to ARM64 specific code, and managed
   to find a way to allocate domain numbers in preparation for Arnd
   pci_create_root_bus() clean-up, v8 to be posted shortly and should
   be final). This provides support for de-facto ACPI/PCI ECAM base
   standard for ARM64 (with a clean-split between generic code and ARM64
   bits, where ARM64, like X86 and IA64, manages in arch code IO space and
   PCI resources, to be further consolidated in the near future).
   I do not think anyone can complain about the generality of what we
   achieved, for systems that are PCI standard (yes, PCI STANDARD) this
   would just be sufficient.
2) In a real world (1) is not enough. Some ARM64 platforms, not entirely
   ECAM compliant, already shipped with the corresponding firmware that
   we can't update. HW has ECAM quirks and to work around it in the kernel
   we put forward many solutions to the problem, it is time we found a
   solution (when, of course, (1) is completed and upstream).
   Using the MCFG table OEMID matching floated around in this thread
   would work fine for most of the platforms (and cross-OS) that have
   shipped with HW ECAM quirks, so I think that's the starting point for
   our solution and that's how we can sort this out, _today_.

   The solution is a trivial look-up table:
   MCFG OEMID <-> PCI config space ops

3) (2) does not just work on some platforms (and we can't predict the
   future either - actually I can, it is three letters, ECAM), simply
   because MCFG OEMID matching does not provide a way to attach further
   data to the MCFG (eg if config space for, say, bus 0 domain 0, is not
   ECAM compliant, the config region can't be handled and must not be
   handled through a corresponding MCFG region.
   That's the problem Gabriele is facing and wants to solve through
   something like:

   https://lkml.org/lkml/2016/3/9/91

   in the respective ACPI tables-bindings. It may be an idea worth
   pursuing, it does not solve (2) simply because that FW has shipped,
   we can't patch it any longer.

Hence to finally support ACPI PCI on ARM64 I suggest we carry out the
following steps, in order:

- Let's complete/merge (1), that's fundamental to this whole thread
- On top of (1) we apply a quirking mechanism based on (2) that allows
  us to boot mainline with boxes shipping today with no FW update required.
- We devise a way to handle quirks that is more generic than (2) so that
  can we can accomodate further platforms that can't rely on (2) but
  have more leeway in terms of FW updates.

I hope that's a reasonable plan, Tomasz's v8 series coming to kick it off.

Thank you,

Re: [PATCH V7 07/11] pci, acpi: Handle ACPI companion assignment.

2016-05-11 Thread Lorenzo Pieralisi
On Tue, May 10, 2016 at 08:37:00PM +0200, Rafael J. Wysocki wrote:
> On Tue, May 10, 2016 at 5:19 PM, Tomasz Nowicki  wrote:
> > This patch provides a way to set the ACPI companion in PCI code.
> > We define acpi_pci_set_companion() to set the ACPI companion pointer and
> > call it from PCI core code. The function is stub for now.
> >
> > Signed-off-by: Jayachandran C 
> > Signed-off-by: Tomasz Nowicki 
> > ---
> >  drivers/pci/probe.c  | 2 ++
> >  include/linux/pci-acpi.h | 4 
> >  2 files changed, 6 insertions(+)
> >
> > diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> > index 8004f67..fb0b752 100644
> > --- a/drivers/pci/probe.c
> > +++ b/drivers/pci/probe.c
> > @@ -12,6 +12,7 @@
> >  #include 
> >  #include 
> >  #include 
> > +#include 
> >  #include 
> >  #include 
> >  #include 
> > @@ -2141,6 +2142,7 @@ struct pci_bus *pci_create_root_bus(struct device 
> > *parent, int bus,
> > bridge->dev.parent = parent;
> > bridge->dev.release = pci_release_host_bridge_dev;
> > dev_set_name(>dev, "pci%04x:%02x", pci_domain_nr(b), bus);
> > +   acpi_pci_set_companion(bridge);
> 
> Yes, we'll probably add something similar here.
> 
> Do I think now is the right time to do that?  No.
> 
> > error = pcibios_root_bridge_prepare(bridge);
> > if (error) {
> > kfree(bridge);
> > diff --git a/include/linux/pci-acpi.h b/include/linux/pci-acpi.h
> > index 09f9f02..1baa515 100644
> > --- a/include/linux/pci-acpi.h
> > +++ b/include/linux/pci-acpi.h
> > @@ -111,6 +111,10 @@ static inline void acpi_pci_add_bus(struct pci_bus 
> > *bus) { }
> >  static inline void acpi_pci_remove_bus(struct pci_bus *bus) { }
> >  #endif /* CONFIG_ACPI */
> >
> > +static inline void acpi_pci_set_companion(struct pci_host_bridge *bridge)
> > +{
> > +}
> > +
> >  static inline int acpi_pci_bus_domain_nr(struct pci_bus *bus)
> >  {
> > return 0;
> > --
> 
> Honestly, to me it looks like this series is trying very hard to avoid
> doing any PCI host bridge configuration stuff from arch/arm64/
> although (a) that might be simpler and (b) it would allow us to
> identify the code that's common between *all* architectures using ACPI
> support for host bridge configuration and to move *that* to a common
> place later.  As done here it seems to be following the "ARM64 is
> generic and the rest of the world is special" line which isn't really
> helpful.

I think patch [1-2] should be merged regardless (they may require minor
tweaks if we decide to move pci_acpi_scan_root() to arch/arm64 though,
for include files location). I guess you are referring to patch 8 in
your comments above, which boils down to deciding whether:

- pci_acpi_scan_root() (and unfortunately all the MCFG/ECAM handling that
  goes with it) should live in arch/arm64 or drivers/acpi

acpi_pci_bus_domain_nr() is a bit more problematic since it is meant
to be called from PCI core code (ARM64 selects PCI_DOMAINS_GENERIC for
DT and same kernel has to work with OF and ACPI selected) and it is
arch specific (because what we have in bus->sysdata is arch specific,
waiting for the domain number to be embedded in struct pci_host_bridge).

Your point is fair, I am not sure that moving the pci_acpi_scan_root()
to arch/arm64 would make things much simpler though, it is just a matter
of deciding where that code has to live.

How do you want us to proceed ?

Thanks,
Lorenzo


Re: [PATCH V7 07/11] pci, acpi: Handle ACPI companion assignment.

2016-05-13 Thread Lorenzo Pieralisi
On Thu, May 12, 2016 at 01:27:23PM +0200, Rafael J. Wysocki wrote:
> On Thu, May 12, 2016 at 12:43 PM, Jayachandran C <jchan...@broadcom.com> 
> wrote:
> > On Thu, May 12, 2016 at 4:13 AM, Bjorn Helgaas <helg...@kernel.org> wrote:
> >> On Wed, May 11, 2016 at 10:30:51PM +0200, Rafael J. Wysocki wrote:
> >>> On Wed, May 11, 2016 at 12:11 PM, Lorenzo Pieralisi
> >>> <lorenzo.pieral...@arm.com> wrote:
> >>> > On Tue, May 10, 2016 at 08:37:00PM +0200, Rafael J. Wysocki wrote:
> >>> >> On Tue, May 10, 2016 at 5:19 PM, Tomasz Nowicki <t...@semihalf.com> 
> >>> >> wrote:
> 
> [cut]
> 
> >
> > If we are moving the ACPI/PCI code from drivers/acpi to
> > arch/arm64/ , there is an issue in having the header file
> > ecam.h in drivers/pci
> >
> > The current include of "../pci/ecam.h" is slightly ugly (Arnd
> > and David had already noted this), but including the driver
> > header from arch code would be even worse.
> >
> > I can either merge ecam.h into include/linux/pci.h
> > or move it to a new file include/linux/pci-ecam.h, any
> > suggestion on which is preferable?
> 
> My preference would be pci-ecam.h as we did a similar thing for
> pci-dma.h, for example, but basically this is up to Bjorn.

A word of caution for all interested parties, what we may move
to arch/arm64 (if Catalin and Will are ok with that) here is content
of drivers/acpi/pci_root_generic.c, not drivers/acpi/pci_mcfg.c (and
definitely not the MCFG quirks handling that is coming up next on top
of this series).

I just wanted to make sure we understand that MCFG quirks handling
like eg:

https://lkml.org/lkml/2016/4/28/790

that is coming up following this series has no chance whatsoever to
be handled within arch/arm64, it is just not going to happen.

Maybe I am jumping the gun, I just want to make sure that everyone is
aware that moving part of this series to arch/arm64 has implications,
(and that's why I said that moving part of this code to arch/arm64 is
not as simple as it looks) it may be ok to have an ACPI PCI
implementation that is arch/arm64 specific (mostly for IO space and PCI
resources assignment handling that unfortunately is not uniform across
X86, IA64 and ARM64), but MCFG quirks and related platform code stay out
of arch/arm64 I guess we are all aware of that, just wanted to make
sure :)

Lorenzo


Re: [PATCH V7 07/11] pci, acpi: Handle ACPI companion assignment.

2016-05-12 Thread Lorenzo Pieralisi
On Wed, May 11, 2016 at 05:43:14PM -0500, Bjorn Helgaas wrote:
> On Wed, May 11, 2016 at 10:30:51PM +0200, Rafael J. Wysocki wrote:
> > On Wed, May 11, 2016 at 12:11 PM, Lorenzo Pieralisi
> > <lorenzo.pieral...@arm.com> wrote:
> > > On Tue, May 10, 2016 at 08:37:00PM +0200, Rafael J. Wysocki wrote:
> > >> On Tue, May 10, 2016 at 5:19 PM, Tomasz Nowicki <t...@semihalf.com> 
> > >> wrote:
> > >> > This patch provides a way to set the ACPI companion in PCI code.
> > >> > We define acpi_pci_set_companion() to set the ACPI companion pointer 
> > >> > and
> > >> > call it from PCI core code. The function is stub for now.
> > >> >
> > >> > Signed-off-by: Jayachandran C <jchan...@broadcom.com>
> > >> > Signed-off-by: Tomasz Nowicki <t...@semihalf.com>
> > >> > ---
> > >> >  drivers/pci/probe.c  | 2 ++
> > >> >  include/linux/pci-acpi.h | 4 
> > >> >  2 files changed, 6 insertions(+)
> > >> >
> > >> > diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> > >> > index 8004f67..fb0b752 100644
> > >> > --- a/drivers/pci/probe.c
> > >> > +++ b/drivers/pci/probe.c
> > >> > @@ -12,6 +12,7 @@
> > >> >  #include 
> > >> >  #include 
> > >> >  #include 
> > >> > +#include 
> > >> >  #include 
> > >> >  #include 
> > >> >  #include 
> > >> > @@ -2141,6 +2142,7 @@ struct pci_bus *pci_create_root_bus(struct 
> > >> > device *parent, int bus,
> > >> > bridge->dev.parent = parent;
> > >> > bridge->dev.release = pci_release_host_bridge_dev;
> > >> > dev_set_name(>dev, "pci%04x:%02x", pci_domain_nr(b), 
> > >> > bus);
> > >> > +   acpi_pci_set_companion(bridge);
> > >>
> > >> Yes, we'll probably add something similar here.
> > >>
> > >> Do I think now is the right time to do that?  No.
> > >>
> > >> > error = pcibios_root_bridge_prepare(bridge);
> > >> > if (error) {
> > >> > kfree(bridge);
> > >> > diff --git a/include/linux/pci-acpi.h b/include/linux/pci-acpi.h
> > >> > index 09f9f02..1baa515 100644
> > >> > --- a/include/linux/pci-acpi.h
> > >> > +++ b/include/linux/pci-acpi.h
> > >> > @@ -111,6 +111,10 @@ static inline void acpi_pci_add_bus(struct 
> > >> > pci_bus *bus) { }
> > >> >  static inline void acpi_pci_remove_bus(struct pci_bus *bus) { }
> > >> >  #endif /* CONFIG_ACPI */
> > >> >
> > >> > +static inline void acpi_pci_set_companion(struct pci_host_bridge 
> > >> > *bridge)
> > >> > +{
> > >> > +}
> > >> > +
> > >> >  static inline int acpi_pci_bus_domain_nr(struct pci_bus *bus)
> > >> >  {
> > >> > return 0;
> > >> > --
> > >>
> > >> Honestly, to me it looks like this series is trying very hard to avoid
> > >> doing any PCI host bridge configuration stuff from arch/arm64/
> > >> although (a) that might be simpler and (b) it would allow us to
> > >> identify the code that's common between *all* architectures using ACPI
> > >> support for host bridge configuration and to move *that* to a common
> > >> place later.  As done here it seems to be following the "ARM64 is
> > >> generic and the rest of the world is special" line which isn't really
> > >> helpful.
> > >
> > > I think patch [1-2] should be merged regardless (they may require minor
> > > tweaks if we decide to move pci_acpi_scan_root() to arch/arm64 though,
> > > for include files location). I guess you are referring to patch 8 in
> > > your comments above, which boils down to deciding whether:
> > >
> > > - pci_acpi_scan_root() (and unfortunately all the MCFG/ECAM handling that
> > >   goes with it) should live in arch/arm64 or drivers/acpi
> > 
> > To be precise, everything under #ifdef CONFIG_ACPI_PCI_HOST_GENERIC or
> > equivalent is de facto ARM64-specific, because (as it stands in the
> > patch series) ARM64 is the only architecture that will select that
> > option.  Unless you are aware of any more architectures planning to
> > use ACPI (

Re: [PATCH V6 09/13] pci, acpi: Support for ACPI based generic PCI host controller

2016-05-03 Thread Lorenzo Pieralisi
On Fri, Apr 29, 2016 at 11:05:34PM +0530, Jayachandran C wrote:
> On Fri, Apr 29, 2016 at 2:07 PM, Lorenzo Pieralisi
> <lorenzo.pieral...@arm.com> wrote:
> > On Thu, Apr 28, 2016 at 04:48:00PM -0500, Bjorn Helgaas wrote:
> >
> > [...]
> >
> >> > +static int pci_acpi_setup_ecam_mapping(struct acpi_pci_root *root,
> >> > +  struct acpi_pci_generic_root_info *ri)
> >> > +{
> >> > +   u16 seg = root->segment;
> >> > +   u8 bus_start = root->secondary.start;
> >> > +   u8 bus_end = root->secondary.end;
> >> > +   struct pci_config_window *cfg;
> >> > +   struct mcfg_entry *e;
> >> > +   phys_addr_t addr;
> >> > +   int err = 0;
> >> > +
> >> > +   mutex_lock(_mcfg_lock);
> >>
> >> What does this lock protect?  The pci_mcfg_list should already be
> >> initialized by the time we get there, and it should be immutable for
> >> the life of the system.  In fact, I would prefer if we could just
> >> search the static table itself whenever we need it rather than caching
> >> it in our own list.  But I don't think we can easily do that because
> >> acpi_table_parse() is __init.
> >>
> >> > +   e = pci_mcfg_lookup(seg, bus_start);
> >>
> >> I would argue that we should check for _CBA first, and fall back to
> >> MCFG if _CBA doesn't exist.
> >>
> >> > +   if (!e) {
> >> > +   addr = acpi_pci_root_get_mcfg_addr(root->device->handle);
> >>
> >> IMO, acpi_pci_root_get_mcfg_addr() is misnamed.  It should be
> >> acpi_pci_config_base_addr() or similar.  It definitely is not related
> >> to MCFG.  Not your fault, obviously.
> >>
> >> > +   if (addr == 0) {
> >> > +   pr_err(PREFIX"%04x:%02x-%02x bus range error\n",
> >> > +  seg, bus_start, bus_end);
> >> > +   err = -ENOENT;
> >> > +   goto err_out;
> >> > +   }
> >> > +   } else {
> >> > +   if (bus_start != e->bus_start) {
> >> > +   pr_err("%04x:%02x-%02x bus range mismatch %02x\n",
> >> > +  seg, bus_start, bus_end, e->bus_start);
> >> > +   err = -EINVAL;
> >> > +   goto err_out;
> >> > +   } else if (bus_end != e->bus_end) {
> >> > +   pr_warn("%04x:%02x-%02x bus end mismatch %02x\n",
> >> > +   seg, bus_start, bus_end, e->bus_end);
> >> > +   bus_end = min(bus_end, e->bus_end);
> >> > +   }
> >> > +   addr = e->addr;
> >> > +   }
> >>
> >> I really don't think you need a lock around this, so you can factor
> >> out the address lookup into something like:
> >>
> >>   addr = acpi_pci_config_base_addr(...);
> >>   if (addr)
> >> return addr;
> >>
> >>   return acpi_pci_mcfg_lookup(seg, busn_res);
> >>
> >> You can check inside acpi_pci_mcfg_lookup() to make sure the entry you
> >> find covers the entire [busn_res.start-busn_res.end] range and return
> >> failure if it doesn't.  At this point, I'm not sure it's worth it to
> >> truncate the host bridge bus range to match something we find in MCFG.
> >>
> >> If the MCFG entry covers *more* than the host bridge range from _CRS,
> >> that's fine.  In any case, we have to be careful with the start address,
> >> because the MCFG start address is always based on bus 0, but I think
> >> pci_generic_ecam_create() expects the start address based on the
> >> bus_start you pass to it.
> >
> > Yes, I spotted this too, it is unfortunate but DT and MCFG handle
> > the ECAM regions differently. In DT the reg property is relative
> > to bus_start - ie reg MMIO region maps config space starting at
> > the first bus in bus-range:
> >
> > Documentation/devicetree/bindings/pci/host-generic-pci.txt
> >
> > in ACPI(MCFG) as you said it is always relative to bus 0, it is
> > unfortunate but the address to be mapped should be computed
> > differently in the ECAM layer.
> 
> Can't this be handled by fixing up the address before passing to
> pci_generic_ecam_create?

Yes it can, you just need to apply the bus shift, given that we know
it is ECAM anyway you can even add a macro in the ecam generic header to
compute it, anyway that's a minor detail, we just should not forget to
fix it.

Lorenzo


Re: [PATCH V6 02/13] pci, acpi: Provide generic way to assign bus domain number.

2016-05-03 Thread Lorenzo Pieralisi
On Mon, May 02, 2016 at 06:56:13PM +0530, Jayachandran C wrote:
> On Mon, May 2, 2016 at 6:13 PM, Tomasz Nowicki <t...@semihalf.com> wrote:
> > On 04/27/2016 01:17 PM, Lorenzo Pieralisi wrote:
> >>
> >> On Tue, Apr 26, 2016 at 09:26:49PM -0500, Bjorn Helgaas wrote:
> >>>
> >>> On Fri, Apr 15, 2016 at 07:06:37PM +0200, Tomasz Nowicki wrote:
> >
> > [...]
> >
> >>>   +int acpi_pci_bus_domain_nr(struct device *parent)
> >>> +{
> >>> +   struct acpi_device *acpi_dev = to_acpi_device(parent);
> >>> +   unsigned long long segment = 0;
> >>> +   acpi_status status;
> >>> +
> >>> +   /*
> >>> +* If _SEG method does not exist, following ACPI spec (6.5.6)
> >>> +* all PCI buses belong to domain 0.
> >>> +*/
> >>> +   status = acpi_evaluate_integer(acpi_dev->handle,
> >>> METHOD_NAME__SEG, NULL,
> >>> +  );
> >>> We already have code in acpi_pci_root_add() to evaluate _SEG.  We
> >>> don't want to evaluate it *twice*, do we?
> >>>
> >>> I was sort of expecting that if you added it here, we'd remove the
> >>> existing call, but it looks like you're keeping both?
> >>
> >> We can't remove the existing call, since it is used on X86 and IA64
> >> to store the segment number that, in the process, is used in their
> >> pci_domain_nr() arch specific callback to retrieve the domain nr.
> >>
> >> On ARM64, that selects PCI_DOMAINS_GENERIC, we have to find a way
> >> to retrieve the domain number that is not arch dependent, since
> >> this is generic code, we can't rely on any bus->sysdata format (unless
> >> we do something like JC did below), therefore the only way is to call
> >> the _SEG method *again* here, which also forced Tomasz to go through
> >> the ACPI_COMPANION setting song and dance and pass the parent pointer
> >> to pci_create_root_bus() (see patch 1), which BTW is a source of
> >> trouble on its own as you noticed.
> >
> > What trouble in patch 1 do you mean? I may miss something.
> >
> > I agree that patch 1 is not necessary if we decide to use sysdata or rework
> > root bus scanning to move domain to host bridge. Nevertheless, patch 1 is
> > still a cleanup IMO.
> 
> In this case, getting the domain should be trivial since the ACPI
> companion on parent is already set, this should work
> 
> int acpi_pci_bus_domain_nr(struct device *parent)
> {
> struct acpi_device *acpi_dev = to_acpi_device(parent);
> struct acpi_pci_root *root = acpi_dev->driver_data;
> 
> return root->segment;
> }
> 
> Or am I missing something here?

Well, I thought that the whole idea behind this exercise was to move
the domain number into struct pci_host_bridge (Arnd did not do it with
his first set but this does not mean we can't add it as Bjorn suggested),
so that the domain number could be read from there straight away in an
arch (and FW) independent manner, right ?

Lorenzo


Re: [PATCH V6 02/13] pci, acpi: Provide generic way to assign bus domain number.

2016-05-03 Thread Lorenzo Pieralisi
On Tue, May 03, 2016 at 07:52:52PM +0530, Jayachandran C wrote:
> On Tue, May 3, 2016 at 4:32 PM, Lorenzo Pieralisi
> <lorenzo.pieral...@arm.com> wrote:
> > On Mon, May 02, 2016 at 06:56:13PM +0530, Jayachandran C wrote:
> >> On Mon, May 2, 2016 at 6:13 PM, Tomasz Nowicki <t...@semihalf.com> wrote:
> >> > On 04/27/2016 01:17 PM, Lorenzo Pieralisi wrote:
> >> >>
> >> >> On Tue, Apr 26, 2016 at 09:26:49PM -0500, Bjorn Helgaas wrote:
> >> >>>
> >> >>> On Fri, Apr 15, 2016 at 07:06:37PM +0200, Tomasz Nowicki wrote:
> >> >
> >> > [...]
> >> >
> >> >>>   +int acpi_pci_bus_domain_nr(struct device *parent)
> >> >>> +{
> >> >>> +   struct acpi_device *acpi_dev = to_acpi_device(parent);
> >> >>> +   unsigned long long segment = 0;
> >> >>> +   acpi_status status;
> >> >>> +
> >> >>> +   /*
> >> >>> +* If _SEG method does not exist, following ACPI spec (6.5.6)
> >> >>> +* all PCI buses belong to domain 0.
> >> >>> +*/
> >> >>> +   status = acpi_evaluate_integer(acpi_dev->handle,
> >> >>> METHOD_NAME__SEG, NULL,
> >> >>> +  );
> >> >>> We already have code in acpi_pci_root_add() to evaluate _SEG.  We
> >> >>> don't want to evaluate it *twice*, do we?
> >> >>>
> >> >>> I was sort of expecting that if you added it here, we'd remove the
> >> >>> existing call, but it looks like you're keeping both?
> >> >>
> >> >> We can't remove the existing call, since it is used on X86 and IA64
> >> >> to store the segment number that, in the process, is used in their
> >> >> pci_domain_nr() arch specific callback to retrieve the domain nr.
> >> >>
> >> >> On ARM64, that selects PCI_DOMAINS_GENERIC, we have to find a way
> >> >> to retrieve the domain number that is not arch dependent, since
> >> >> this is generic code, we can't rely on any bus->sysdata format (unless
> >> >> we do something like JC did below), therefore the only way is to call
> >> >> the _SEG method *again* here, which also forced Tomasz to go through
> >> >> the ACPI_COMPANION setting song and dance and pass the parent pointer
> >> >> to pci_create_root_bus() (see patch 1), which BTW is a source of
> >> >> trouble on its own as you noticed.
> >> >
> >> > What trouble in patch 1 do you mean? I may miss something.
> >> >
> >> > I agree that patch 1 is not necessary if we decide to use sysdata or 
> >> > rework
> >> > root bus scanning to move domain to host bridge. Nevertheless, patch 1 is
> >> > still a cleanup IMO.
> >>
> >> In this case, getting the domain should be trivial since the ACPI
> >> companion on parent is already set, this should work
> >>
> >> int acpi_pci_bus_domain_nr(struct device *parent)
> >> {
> >> struct acpi_device *acpi_dev = to_acpi_device(parent);
> >> struct acpi_pci_root *root = acpi_dev->driver_data;
> >>
> >> return root->segment;
> >> }
> >>
> >> Or am I missing something here?
> >
> > Well, I thought that the whole idea behind this exercise was to move
> > the domain number into struct pci_host_bridge (Arnd did not do it with
> > his first set but this does not mean we can't add it as Bjorn suggested),
> > so that the domain number could be read from there straight away in an
> > arch (and FW) independent manner, right ?
> 
> The original issue was using _SEG call again instead of using
> the value from acpi_pci_root, and the solution for that problem
> is very simple.
> 
> The pci host bridge work is of course very useful, but creating a
> dependency with that work for an issue that can be so easily solved
> is unnecessary.

It can be easily solved if we do not drop patch 1 (I understood the
additional call to _SEG was only part of the problem). If we keep patch
1 the code above is fine by me, if we have to drop patch 1 (IIRC by
passing the parent pointer to pci_create_root_bus() we are affecting
IA64 and X86 code, if that's acceptable that's fine by me) I do not
think we can use the code above anymore, that's what my comment was
all about because Bjorn was concerned about the fragility of the code
setting the ACPI companion.

Lorenzo


Re: [PATCH] firmware/drivers/psci: Fix unused functions when CONFIG_CPU_IDLE=n

2016-05-10 Thread Lorenzo Pieralisi
On Tue, May 10, 2016 at 09:18:49AM +0200, Daniel Lezcano wrote:
> On the ARM64 architecture, when CPUIDLE is not set in the configuration,
> the compilation raises a couple of warnings:
> 
> drivers/firmware/psci.c:70:12: warning: 'psci_pd_power_off' defined but not 
> used [-Wunused-function]
> drivers/firmware/psci.c:273:12: warning: 'psci_set_suspend_mode_osi' defined 
> but not used [-Wunused-function]

That's not mainline code :)

Thanks,
Lorenzo

> Fix those warnings by moving the functions inside the #ifdef CONFIG_CPU_IDLE
> section.
> 
> Signed-off-by: Daniel Lezcano 
> ---
>  drivers/firmware/psci.c | 21 +++--
>  1 file changed, 11 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/firmware/psci.c b/drivers/firmware/psci.c
> index 9c6a1f9..d7e0632 100644
> --- a/drivers/firmware/psci.c
> +++ b/drivers/firmware/psci.c
> @@ -54,7 +54,6 @@
>   */
>  static int resident_cpu = -1;
>  static bool psci_has_osi_pd;
> -static bool psci_suspend_mode_is_osi;
>  static DEFINE_PER_CPU(u32, cluster_state_id);
>  
>  static inline u32 psci_get_composite_state_id(u32 cpu_state)
> @@ -67,13 +66,6 @@ static inline void psci_reset_composite_state_id(void)
>   this_cpu_write(cluster_state_id, 0);
>  }
>  
> -static int psci_pd_power_off(u32 state_idx, u32 param,
> - const struct cpumask *mask)
> -{
> - __this_cpu_add(cluster_state_id, param);
> - return 0;
> -}
> -
>  bool psci_tos_resident_on(int cpu)
>  {
>   return cpu == resident_cpu;
> @@ -270,6 +262,11 @@ static int __init psci_features(u32 psci_func_id)
> psci_func_id, 0, 0);
>  }
>  
> +#ifdef CONFIG_CPU_IDLE
> +static bool psci_suspend_mode_is_osi;
> +
> +static DEFINE_PER_CPU_READ_MOSTLY(u32 *, psci_power_state);
> +
>  static int psci_set_suspend_mode_osi(bool enable)
>  {
>   int ret;
> @@ -290,8 +287,12 @@ static int psci_set_suspend_mode_osi(bool enable)
>   return psci_to_linux_errno(ret);
>  }
>  
> -#ifdef CONFIG_CPU_IDLE
> -static DEFINE_PER_CPU_READ_MOSTLY(u32 *, psci_power_state);
> +static int psci_pd_power_off(u32 state_idx, u32 param,
> + const struct cpumask *mask)
> +{
> + __this_cpu_add(cluster_state_id, param);
> + return 0;
> +}
>  
>  static int psci_dt_cpu_init_idle(struct device_node *cpu_node, int cpu)
>  {
> -- 
> 1.9.1
> 


Re: [PATCH V6 01/13] pci, acpi, x86, ia64: Move ACPI host bridge device companion assignment to core code.

2016-05-10 Thread Lorenzo Pieralisi
On Tue, May 10, 2016 at 12:18:59AM +0200, Rafael J. Wysocki wrote:

[...]

> > >> diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
> > >> index ae3fe4e..4581e0e 100644
> > >> --- a/drivers/acpi/pci_root.c
> > >> +++ b/drivers/acpi/pci_root.c
> > >> @@ -564,6 +564,11 @@ static int acpi_pci_root_add(struct acpi_device 
> > >> *device,
> > >>  }
> > >>  }
> > >>
> > >> +/*
> > >> + * pci_create_root_bus() needs to detect the parent device type,
> > >> + * so initialize its companion data accordingly.
> > >> + */
> > >> +ACPI_COMPANION_SET(>dev, device);
> > >>  root->device = device;
> > >>  root->segment = segment & 0x;
> > >>  strcpy(acpi_device_name(device), ACPI_PCI_ROOT_DEVICE_NAME);
> > >> @@ -846,7 +851,7 @@ struct pci_bus *acpi_pci_root_create(struct 
> > >> acpi_pci_root *root,
> > >>
> > >>  pci_acpi_root_add_resources(info);
> > >>  pci_add_resource(>resources, >secondary);
> > >> -bus = pci_create_root_bus(NULL, busnum, ops->pci_ops,
> > >> +bus = pci_create_root_bus(>dev, busnum, ops->pci_ops,
> > >>sysdata, >resources);
> > >
> > > "device" here is a struct acpi_device *.  Rafael, is that the right
> > > thing to do?  I dimly recall proposing something similar long ago and
> > > that it turned out to be a bad idea.
> > >
> > 
> > Joining Bjorn's question. Rafael, do you recall what was the issue here 
> > from the past?
> 
> Yes, I do.
> 
> Anything struct acpi_device doesn't represent a real device.  It
> represents a firmware object that can be associated with a device.
> IOW, nothing under LNXSYSTM\:00/ should ever be used as the parent or
> sibling etc with respect to anything outside of that directory.  In
> fact, the entire LNXSYSTM\:00/ should be located under
> /sys/firmware/acpi/ and it was a mistake to put it under
> /sys/devices/.
> 
> One immediate consequence of the above change, AFAICS, would be that
> the whole PCI hierarchy would now hang under
> /sys/devices/LNXSYSTM\:00/LNXSYBUS\:00/PNP0A08\:00/ which would not
> make any sense whatever, because
> /sys/devices/LNXSYSTM\:00/LNXSYBUS\:00/PNP0A08\:00/physical_node
> already points to /sys/devices/pci\:00/.
> 
> IOW, both PNP0A08\:00/ and pci\:00/ already represent the same
> thing, ie. the host bridge.
> 
> If you want to have a parent for pci\:00/, you need a
> physical_node for LNXSYBUS\:00 and point to that as the parent from
> pci\:00/.  That at least will lead to a sysfs hierarchy that makes
> sense, although it may break user space tools I suppose (which may be
> assuming that pci\:00/ will always be present directly under
> /sys/devices/).

Ok, I have a question though. As an example, DT based host controllers
(that pass the parent pointer to pci_create_root_bus()), are already
rooted at the respective host controller platform device sysfs path, so
if user space can't cope with that, that is a problem *now* on some
systems unless I am missing something.

Anyway, thanks for clarifying the companion handling mechanism, we
decidedly have to find a proper way to handle it instead of working
around it.

Lorenzo


Re: [PATCH V6 01/13] pci, acpi, x86, ia64: Move ACPI host bridge device companion assignment to core code.

2016-05-10 Thread Lorenzo Pieralisi
On Mon, May 09, 2016 at 08:53:36PM -0500, Bjorn Helgaas wrote:
> On Tue, May 10, 2016 at 12:56:37AM +0200, Rafael J. Wysocki wrote:
> > On Friday, April 15, 2016 07:06:36 PM Tomasz Nowicki wrote:
> > > Currently we have two platforms (x86 & ia64) capable of PCI ACPI host
> > > bridge initialization. They both use arch-specific sysdata to pass down
> > > parent device reference and both rely on NULL parent in 
> > > pci_create_root_bus()
> > > to validate sysdata content.
> > 
> > No, this is not relied on for that.  It is just NULL, because we don't
> > have a physical parent device representation for the PCI host bridge.
> > 
> > > It looks hacky and prevents us from getting some firmware specific
> > > info for PCI host controller based on its acpi_device structure
> > > in generic pci_create_root_bus() function.
> > 
> > You can't get that info without adding ACPI-specific code to that function
> > anyway.
> > 
> > > However, we overcome that blocker by passing down parent device via
> > > pci_create_root_bus parameter (as the ACPI device type).
> > 
> > Which is completely wrong.
> > 
> > > Then we use ACPI_COMPANION_SET in core code
> > > for ACPI boot method only. ACPI_COMPANION_SET is safe to run for all
> > > cases DT, ACPI and DT
> > > 
> > > Since now PCI core code is setting ACPI companion device for us,
> > > x86 & ia64 specific ACPI companion device setting turns out to be dead 
> > > now.
> > > We can get rid of it, including related companion reference from
> > > PCI sysdata structure. Aslo, PCI_CONTROLLER macro cannot return valid
> > > companion device anymore. Therefore we need to convert its usage to
> > > ACPI_COMPANION.
> 
> I think getting rid of arch-specific sysdata is a good goal (at least
> for things like the domain and ACPI companion that are really not
> arch-specific).
> 
> But I'm afraid I've been guilty of allowing the perfect to be the
> enemy of the good.  I think it will be more useful in the end if we
> can get as much of this work in v4.7 as possible, even if there's more
> polishing we'd like to do later.
> 
> What if we keep the x86 and ia64 handling of ACPI_COMPANION the way it
> is today, and do it the same way for arm64?  Then later, after we
> merge Arnd's work to make a generic pci_register_host() or similar, I
> suspect we might be able to unify the ACPI_COMPANION stuff more
> easily.  If the driver (acpi/pci_root.c) allocates the struct
> pci_host_bridge, then maybe it will be able to fill in the domain and
> set up the ACPI_COMPANION before it calls the scan interface.

Ok, JC already solved that problem like this:

http://www.spinics.net/lists/arm-kernel/msg478167.html
http://www.spinics.net/lists/arm-kernel/msg478169.html

Since ARM64 relies on PCI_DOMAINS_GENERIC (DT) I do not see any other
way of pulling it off quickly (and in a really generic way), sysdata
is the only way of handling it in ACPI unless we start clutching
at straws (which we already did with the ACPI companion hacks).

Thanks,
Lorenzo


Re: [PATCH v3] ARM64: ACPI: Update documentation for latest specification version

2016-04-15 Thread Lorenzo Pieralisi
Hi Al,

On Mon, Mar 28, 2016 at 06:06:42PM -0600, Al Stone wrote:
> The ACPI 6.1 specification was recently released at the end of January
> 2016, but the arm64 kernel documentation for the use of ACPI was written
> for the 5.1 version of the spec.  There were significant additions to the
> spec that had not yet been mentioned -- for example, the 6.0 mechanisms
> added to make it easier to define processors and low power idle states,
> as well as the 6.1 addition allowing regular interrupts (not just from
> GPIO) be used to signal ACPI general purpose events.
> 
> This patch reflects going back through and examining the specs in detail
> and updating content appropriately.  Whilst there, a few odds and ends of
> typos were caught as well.  This brings the documentation up to date with
> ACPI 6.1 for arm64.
> 
> Changes for v3:
>-- Clarify use of _LPI/_RDI (Vikas Sajjan)
>-- Whitespace cleanup as pointed out by checkpatch
> 
> Changes for v2:
>-- Clean up white space (Harb Abdulhahmid)
>-- Clarification on _CCA usage (Harb Abdulhamid)
>-- IORT moved to required from recommended (Hanjun Guo)
>-- Clarify IORT description (Hanjun Guo)
> 
> Signed-off-by: Al Stone 
> Cc: Catalin Marinas 
> Cc: Will Deacon 
> Cc: Jonathan Corbet 
> ---
>  Documentation/arm64/acpi_object_usage.txt | 446 
> ++
>  Documentation/arm64/arm-acpi.txt  |  28 +-
>  2 files changed, 357 insertions(+), 117 deletions(-)

I went through this patch twice and before posting my review comments
I have some questions to _ASK ;-):

-  Do we really need acpi_object_usage.txt to list all possible ACPI
   methods in the ACPI specs ("Use as needed") and update them as the
   specs evolve ?
   IMO that's what the ACPI specs are for and that's what AML developers
   will refer to, I do not see the point in listing all methods in that
   file (can't it become an ARM addendum to the ACPI specs at least to
   deprecate methods/tables that are obsolete in ARM's world) ?

-  How do we keep acpi_object_usage.txt in sync with ACPI specs from now
   onwards ? Is that what we really want/need ?

-  How do we keep arm-acpi.txt in sync with kernel supported ARM64 ACPI
   features (if - given that this document is part of the Linux kernel docs -
   its aim is to describe what bits of ACPI are supported on arm64 (?)) ?

So, agreed with fixing the typos, agreed with arm-acpi.txt (and with
updating it) which describes how the ARM64 kernel is using ACPI
methods/tables, but acpi_object_usage.txt and in particular describing
in there what methods are _useful_ and what are not, honestly I think we
should ask ourselves what that file is really meant to be.

Happy to send my review comments as a follow-up since overall the patch
is OK, I wanted to ask the basic questions above first.

Thanks,
Lorenzo

> 
> diff --git a/Documentation/arm64/acpi_object_usage.txt 
> b/Documentation/arm64/acpi_object_usage.txt
> index a6e1a18..756d2f8 100644
> --- a/Documentation/arm64/acpi_object_usage.txt
> +++ b/Documentation/arm64/acpi_object_usage.txt
> @@ -11,15 +11,16 @@ outside of the UEFI Forum (see Section 5.2.6 of the 
> specification).
>  
>  For ACPI on arm64, tables also fall into the following categories:
>  
> -   -- Required: DSDT, FADT, GTDT, MADT, MCFG, RSDP, SPCR, XSDT
> +   -- Required: DSDT, FADT, GTDT, IORT, MADT, MCFG, RSDP, SPCR, XSDT
>  
> -   -- Recommended: BERT, EINJ, ERST, HEST, SSDT
> +   -- Recommended: BERT, EINJ, ERST, HEST, PCCT, SSDT
>  
> -   -- Optional: BGRT, CPEP, CSRT, DRTM, ECDT, FACS, FPDT, MCHI, MPST,
> -  MSCT, RASF, SBST, SLIT, SPMI, SRAT, TCPA, TPM2, UEFI
> +   -- Optional: BGRT, CPEP, CSRT, DBG2, DRTM, ECDT, FACS, FPDT, MCHI,
> +  MPST, MSCT, NFIT, PMTT, RASF, SBST, SLIT, SPMI, SRAT, STAO, TCPA,
> +  TPM2, UEFI, XENV
>  
> -   -- Not supported: BOOT, DBG2, DBGP, DMAR, ETDT, HPET, IBFT, IVRS,
> -  LPIT, MSDM, RSDT, SLIC, WAET, WDAT, WDRT, WPBT
> +   -- Not supported: BOOT, DBGP, DMAR, ETDT, HPET, IBFT, IVRS, LPIT,
> +  MSDM, OEMx, PSDT, RSDT, SLIC, WAET, WDAT, WDRT, WPBT
>  
>  
>  Table  Usage for ARMv8 Linux
> @@ -50,7 +51,8 @@ CSRT   Signature Reserved (signature == "CSRT")
>  
>  DBG2   Signature Reserved (signature == "DBG2")
> == DeBuG port table 2 ==
> -   Microsoft only table, will not be supported.
> +   License has changed and should be usable.  Optional if used instead
> +   of earlycon= on the command line.
>  
>  DBGP   Signature Reserved (signature == "DBGP")
> == DeBuG Port table ==
> @@ -133,10 +135,11 @@ GTDT   Section 5.2.24 (signature == "GTDT")
>  
>  HEST   Section 18.3.2 (signature == "HEST")
> == Hardware Error Source Table ==
> -   Until further error source types are defined, use only types 6 (AER
> -   Root Port), 7 (AER Endpoint), 8 (AER Bridge), or 9 (Generic 

Re: [PATCH v3] ARM64: ACPI: Update documentation for latest specification version

2016-04-15 Thread Lorenzo Pieralisi
On Fri, Apr 15, 2016 at 10:41:02AM -0600, Al Stone wrote:
> On 04/15/2016 08:37 AM, Lorenzo Pieralisi wrote:
> > Hi Al,
> > 
> > On Mon, Mar 28, 2016 at 06:06:42PM -0600, Al Stone wrote:
> >> The ACPI 6.1 specification was recently released at the end of January
> >> 2016, but the arm64 kernel documentation for the use of ACPI was written
> >> for the 5.1 version of the spec.  There were significant additions to the
> >> spec that had not yet been mentioned -- for example, the 6.0 mechanisms
> >> added to make it easier to define processors and low power idle states,
> >> as well as the 6.1 addition allowing regular interrupts (not just from
> >> GPIO) be used to signal ACPI general purpose events.
> >>
> >> This patch reflects going back through and examining the specs in detail
> >> and updating content appropriately.  Whilst there, a few odds and ends of
> >> typos were caught as well.  This brings the documentation up to date with
> >> ACPI 6.1 for arm64.
> >>
> >> Changes for v3:
> >>-- Clarify use of _LPI/_RDI (Vikas Sajjan)
> >>-- Whitespace cleanup as pointed out by checkpatch
> >>
> >> Changes for v2:
> >>-- Clean up white space (Harb Abdulhahmid)
> >>-- Clarification on _CCA usage (Harb Abdulhamid)
> >>-- IORT moved to required from recommended (Hanjun Guo)
> >>-- Clarify IORT description (Hanjun Guo)
> >>
> >> Signed-off-by: Al Stone <al.st...@linaro.org>
> >> Cc: Catalin Marinas <catalin.mari...@arm.com>
> >> Cc: Will Deacon <will.dea...@arm.com>
> >> Cc: Jonathan Corbet <cor...@lwn.net>
> >> ---
> >>  Documentation/arm64/acpi_object_usage.txt | 446 
> >> ++
> >>  Documentation/arm64/arm-acpi.txt  |  28 +-
> >>  2 files changed, 357 insertions(+), 117 deletions(-)
> > 
> > I went through this patch twice and before posting my review comments
> > I have some questions to _ASK ;-):
> > 
> > -  Do we really need acpi_object_usage.txt to list all possible ACPI
> >methods in the ACPI specs ("Use as needed") and update them as the
> >specs evolve ?
> >IMO that's what the ACPI specs are for and that's what AML developers
> >will refer to, I do not see the point in listing all methods in that
> >file (can't it become an ARM addendum to the ACPI specs at least to
> >deprecate methods/tables that are obsolete in ARM's world) ?
> 
> The original intent was to provide guidance to those unfamiliar with ACPI,
> and in particular provide some details on what usage makes sense on ARM.
> In writing it, the objective was that arm-acpi.txt be primarily an overall
> view, but that acpi_object_usage.txt answered specific questions about
> specific objects, which we got asked about frequently since APCI was very
> new on ARM at the time.  That being said, however, it is possible that
> acpi_object_usage.txt has outlived its usefulness, as those that need to
> have become familiar with ACPI.
> 
> It doesn't help in the ACPI specs since the idea was to try to document
> recommended Linux-specific usage, which may or may not be OS-agnostic, but
> would at least be in the open to encourage common usage.

Understood, the point I wanted to make is that adding a list of methods
in acpi_object_usage.txt ("Use as needed") is not necessarily additional
information, you can add a pointer at ACPI specs (for that specific
purpose - as I said there are parts of the patch that add additional
information Linux related) for that purpose instead of having to list
all of them in acpi_object_usage.txt again.

> > -  How do we keep acpi_object_usage.txt in sync with ACPI specs from now
> >onwards ? Is that what we really want/need ?
> > 
> > -  How do we keep arm-acpi.txt in sync with kernel supported ARM64 ACPI
> >features (if - given that this document is part of the Linux kernel docs 
> > -
> >its aim is to describe what bits of ACPI are supported on arm64 (?)) ?
> 
> Well, maintenance will be necessary as new spec revisions come out, just like
> any other part of the kernel code.  I don't see anything unique about these
> documents versus any other; is there something else in the question that I'm
> not seeing?

No, see above.

> I guess I just assumed that since I wrote these, I'd be responsible
> for keeping them up to date.  If you're volunteering to do so, I would
> not object :-).

I asked because it is kernel documentation and it has to be reviewed
as such, some updates I found them necessary, adding a list of new
AC

Re: [PATCH] drivers: firmware: psci: add __init mark to psci_dt_cpu_init_idle

2016-04-19 Thread Lorenzo Pieralisi
On Tue, Apr 19, 2016 at 04:20:38PM +0100, Sudeep Holla wrote:
> 
> 
> On 19/04/16 16:05, Lorenzo Pieralisi wrote:
> >Hi Jisheng,
> >
> >On Tue, Mar 22, 2016 at 10:35:29PM +0800, Jisheng Zhang wrote:
> >>psci_dt_cpu_init_idle() and psci_cpu_init_idle() are not needed after
> >>booting, so mark them as __init.
> >>
> 
> On the other hand, when I was trying to reuse arm_cpuidle_init to
> support ACPI LPIs, I found that we may need to remove __init tag on it
> as it gets called by hotplug notifiers in ACPI context.
> 
> I am not objecting this change, just mentioning with the hope to get
> solution to the above issue.

Yep, good point, it is not strictly necessary to merge it either
and I would avoid churning out changes given that we know we will
require to remove those __init tags anyway, so patch dropped.

Lorenzo


Re: [PATCH 0/4] ARM: cpuidle: use const and __initconst for cpuidle_ops

2016-04-19 Thread Lorenzo Pieralisi
Hi Daniel,

On Fri, Mar 25, 2016 at 12:26:27PM +0100, Daniel Lezcano wrote:
> On 03/22/2016 03:42 PM, Jisheng Zhang wrote:
> >These trivial patches are similar as Masahiro posted in[1]. The main
> >purpose is let cpuidle_ops structure be constified and replace
> >"__initdata" with "__initconst".
> >
> >[1] 
> >http://lists.infradead.org/pipermail/linux-arm-kernel/2015-August/365826.html
> >
> >Jisheng Zhang (4):
> >   ARM: cpuidle: add const qualifier to cpuidle_ops member in structures
> >   ARM: cpuidle: constify return value of arm_cpuidle_get_ops()
> >   soc: qcom: spm: use const and __initconst for qcom_cpuidle_ops
> >   drivers: firmware: psci: use const and __initconst for
> > psci_cpuidle_ops
> >
> >  arch/arm/include/asm/cpuidle.h | 2 +-
> >  arch/arm/kernel/cpuidle.c  | 6 +++---
> >  drivers/firmware/psci.c| 2 +-
> >  drivers/soc/qcom/spm.c | 2 +-
> >  4 files changed, 6 insertions(+), 6 deletions(-)
> 
> Sounds reasonable.

Are you taking them ? I could send the last one but it would
make more sense for them to be part of the same series, I will
check they do not conflict with patches queued for PSCI.

Thanks,
Lorenzo


Re: [PATCH] drivers: firmware: psci: add __init mark to psci_dt_cpu_init_idle

2016-04-19 Thread Lorenzo Pieralisi
Hi Jisheng,

On Tue, Mar 22, 2016 at 10:35:29PM +0800, Jisheng Zhang wrote:
> psci_dt_cpu_init_idle() and psci_cpu_init_idle() are not needed after
> booting, so mark them as __init.
> 
> Signed-off-by: Jisheng Zhang <jszh...@marvell.com>
> ---

I've slightly changed the $SUBJECT, patch below FYI.

Lorenzo

-- >8 --
Subject: [PATCH] drivers: firmware: psci: mark idle init functions __init

psci_dt_cpu_init_idle() and psci_cpu_init_idle() are not needed after
booting, so mark them as __init.

Signed-off-by: Jisheng Zhang <jszh...@marvell.com>
[lpieralisi: updated patch subject]
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieral...@arm.com>
---
 drivers/firmware/psci.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/firmware/psci.c b/drivers/firmware/psci.c
index 6d86881..4a6a7de 100644
--- a/drivers/firmware/psci.c
+++ b/drivers/firmware/psci.c
@@ -250,7 +250,7 @@ static int __init psci_features(u32 psci_func_id)
 #ifdef CONFIG_CPU_IDLE
 static DEFINE_PER_CPU_READ_MOSTLY(u32 *, psci_power_state);
 
-static int psci_dt_cpu_init_idle(struct device_node *cpu_node, int cpu)
+static int __init psci_dt_cpu_init_idle(struct device_node *cpu_node, int cpu)
 {
int i, ret, count = 0;
u32 *psci_states;
@@ -310,7 +310,7 @@ free_mem:
return ret;
 }
 
-int psci_cpu_init_idle(unsigned int cpu)
+int __init psci_cpu_init_idle(unsigned int cpu)
 {
struct device_node *cpu_node;
int ret;


Re: [PATCH v2 3/6] ARM: PSCI: Register with kernel restart handler

2016-04-19 Thread Lorenzo Pieralisi
On Thu, Apr 14, 2016 at 07:42:34PM -0700, Guenter Roeck wrote:
> Register with kernel restart handler instead of setting arm_pm_restart
> directly. This enables support for replacing the PSCI restart handler
> with a different handler if necessary for a specific board.
> 
> Select a priority of 129 to indicate a higher than default priority, but
> keep it as low as possible since PSCI reset is known to fail on some
> boards.

I do not think you should play with notifiers priorities to paper over
FW bugs, if PSCI SYSTEM_RESET is broken FW is not PSCI0.2+ compliant
so it should not even be advertised as such in the DT.

This means that this priority kludge must disappear soon, what priority
to assign to the PSCI reset handler remains to be seen.

Are you sending this patch series via arm-soc ? If so:

Acked-by: Lorenzo Pieralisi <lorenzo.pieral...@arm.com>

> Acked-by: Arnd Bergmann <a...@arndb.de>
> Reviewed-by: Wolfram Sang <wsa+rene...@sang-engineering.com>
> Tested-by: Wolfram Sang <wsa+rene...@sang-engineering.com>
> Signed-off-by: Guenter Roeck <li...@roeck-us.net>
> ---
> v2: Rebased to v4.6-rc3, added Reviewed/by/Acked-by/Tested-by tags
> Variable name change: np -> nb
> 
>  drivers/firmware/psci.c | 11 +--
>  1 file changed, 9 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/firmware/psci.c b/drivers/firmware/psci.c
> index 11bfee8b79a9..a0f71480f145 100644
> --- a/drivers/firmware/psci.c
> +++ b/drivers/firmware/psci.c
> @@ -231,11 +231,18 @@ static int get_set_conduit_method(struct device_node 
> *np)
>   return 0;
>  }
>  
> -static void psci_sys_reset(enum reboot_mode reboot_mode, const char *cmd)
> +static int psci_sys_reset(struct notifier_block *nb, unsigned long action,
> +   void *data)
>  {
>   invoke_psci_fn(PSCI_0_2_FN_SYSTEM_RESET, 0, 0, 0);
> + return NOTIFY_DONE;
>  }
>  
> +static struct notifier_block psci_sys_reset_nb = {
> + .notifier_call = psci_sys_reset,
> + .priority = 129,
> +};
> +
>  static void psci_sys_poweroff(void)
>  {
>   invoke_psci_fn(PSCI_0_2_FN_SYSTEM_OFF, 0, 0, 0);
> @@ -461,7 +468,7 @@ static void __init psci_0_2_set_functions(void)
>  
>   psci_ops.migrate_info_type = psci_migrate_info_type;
>  
> - arm_pm_restart = psci_sys_reset;
> + register_restart_handler(_sys_reset_nb);
>  
>   pm_power_off = psci_sys_poweroff;
>  }
> -- 
> 2.5.0
> 


Re: [RFC PATCH 09/11] drivers: acpi: implement acpi_dma_configure

2016-04-18 Thread Lorenzo Pieralisi
On Fri, Apr 15, 2016 at 01:29:14PM -0500, Timur Tabi wrote:
> On Thu, Apr 14, 2016 at 12:25 PM, Lorenzo Pieralisi
> <lorenzo.pieral...@arm.com> wrote:
> > +void acpi_dma_configure(struct device *dev, enum dev_dma_attr attr)
> > +{
> > +   struct iommu_ops *iommu;
> > +
> > +   iommu = iort_iommu_configure(dev);
> > +
> > +   /*
> > +* Assume dma valid range starts at 0 and covers the whole
> > +* coherent_dma_mask.
> > +*/
> > +   arch_setup_dma_ops(dev, 0, dev->coherent_dma_mask + 1, iommu,
> > +  attr == DEV_DMA_COHERENT);
> > +}
> 
> I have a network driver that is impacted by this code, so thank you
> for posting this. (See
> https://www.mail-archive.com/netdev@vger.kernel.org/msg106249.html).
> 
> One one SOC, the driver needs to set the mask to 32 bits.  On another
> SOC, it needs to set it to 64 bits.  On device tree, the driver will
> use dma-ranges.

First off I think we agree this patch does not change current behaviour
as far as the devices default dma_mask are concerned. They are
initialized in PCI/ACPI core code:

- pci_setup_device()
- acpi_create_platform_device()

As for ACPI DT-dma-ranges equivalent I have to check if I can use
the _DMA method for that so that we can put in place the same
mechanism as DT to override the default masks, other than that it is
up to the drivers to set-up the dma mask accordingly, that's not
something this patchset is changing anyway.

> In your patches, where is coherent_dma_mask initialized?  I found this
> code in add_smmu_platform_device(), but I think this is setting the
> mask for the IOMMU driver, not the individual devices.  Either way, I
> don't understand where the correct value is going to be overridden.

For the ARM SMMU table walker:

arm_smmu_device_cfg_probe() - dma_set_mask_and_coherent()

For other devices see above.

Thanks,
Lorenzo

> 
> +   /*
> +* Set default dma mask value for the table walker,
> +* to be overridden on probing with correct value.
> +*/
> +   *pdev->dev.dma_mask = DMA_BIT_MASK(32);
> +   pdev->dev.coherent_dma_mask = *pdev->dev.dma_mask;
> 
> -- 
> Qualcomm Innovation Center, Inc.
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
> a Linux Foundation Collaborative Project.
> 


Re: [PATCH RESEND] drivers: firmware: psci: drop duplicate const from psci_of_match

2016-04-20 Thread Lorenzo Pieralisi
On Tue, Mar 22, 2016 at 10:45:46PM +0800, Jisheng Zhang wrote:
> This is to fix below sparse warning:
> drivers/firmware/psci.c:mmm:nn: warning: duplicate const
> 
> Signed-off-by: Jisheng Zhang 
> ---
>  drivers/firmware/psci.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

I am sending it to arm-soc to merge it.

Thanks,
Lorenzo

> 
> diff --git a/drivers/firmware/psci.c b/drivers/firmware/psci.c
> index d24f35d..ae70d24 100644
> --- a/drivers/firmware/psci.c
> +++ b/drivers/firmware/psci.c
> @@ -424,7 +424,7 @@ out_put_node:
>   return err;
>  }
>  
> -static const struct of_device_id const psci_of_match[] __initconst = {
> +static const struct of_device_id psci_of_match[] __initconst = {
>   { .compatible = "arm,psci", .data = psci_0_1_init},
>   { .compatible = "arm,psci-0.2", .data = psci_0_2_init},
>   { .compatible = "arm,psci-1.0", .data = psci_0_2_init},
> -- 
> 2.6.2
> 


Re: [PATCH 4/4] drivers: firmware: psci: use const and __initconst for psci_cpuidle_ops

2016-04-20 Thread Lorenzo Pieralisi
On Tue, Mar 22, 2016 at 10:42:43PM +0800, Jisheng Zhang wrote:
> The psci_cpuidle_ops structures is not over-written, so add "const"
> qualifier and replace __initdata with __initconst.
> 
> Signed-off-by: Jisheng Zhang <jszh...@marvell.com>
> ---
>  drivers/firmware/psci.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Acked-by: Lorenzo Pieralisi <lorenzo.pieral...@arm.com>

> diff --git a/drivers/firmware/psci.c b/drivers/firmware/psci.c
> index 6d86881..7d52186 100644
> --- a/drivers/firmware/psci.c
> +++ b/drivers/firmware/psci.c
> @@ -355,7 +355,7 @@ int psci_cpu_suspend_enter(unsigned long index)
>  
>  /* ARM specific CPU idle operations */
>  #ifdef CONFIG_ARM
> -static struct cpuidle_ops psci_cpuidle_ops __initdata = {
> +static const struct cpuidle_ops psci_cpuidle_ops __initconst = {
>   .suspend = psci_cpu_suspend_enter,
>   .init = psci_dt_cpu_init_idle,
>  };
> -- 
> 2.8.0.rc3
> 


Re: [PATCH v2 2/4] PCI: Provide common functions for ECAM mapping

2016-04-14 Thread Lorenzo Pieralisi
On Thu, Apr 14, 2016 at 01:55:32AM -0400, Jon Masters wrote:

[...]

> > I will comment on the patches as soon as I have time to review
> > them, I certainly would like to understand what we have to do with the
> > rest of the code though (provided this series is good to go) see above.
> 
> Right. That's my reason for asking. I'd like to know who is driving (I
> believe that to be Lorenzo) and what the path forward is, and whether we
> need to get additional support from anyone else. There's a multi-vendor
> meeting in the morning where I'm going to summarize the current state of
> these patches and I would like to know (soon) what the plan is so that
> we can get everyone on deck to help out at least with testing (most have
> tested the previous set, but we need public acks happening).

Testing always helps, this code needs reviewing from PCI and ACPI
standpoints, what we can do is review this series and repost the whole
thing when we agree the ECAM refactoring this series is implementing
is the right way to go and it is a step in that direction, with no
generic MCFG support in the kernel ACPI PCI on ARM64 can't be
implemented so I would start from that.

Lorenzo


Re: [PATCH v4] ARM64: ACPI: Update documentation for latest specification version

2016-04-19 Thread Lorenzo Pieralisi
states may become available at
> +some point in the future, but most current design work appears to favor CPPC.
>  
>  Further, it is essential that the ARMv8 SoC provide a fully functional
>  implementation of PSCI; this will be the only mechanism supported by ACPI
> -to control CPU power state (including secondary CPU booting).
> -
> -More details will be provided on the release of the ACPI 6.0 specification.
> +to control CPU power state.  Booting of secondary CPUs may be possible using
> +parking protocol, but only PSCI is to be used for ARM servers.

"Booting of secondary CPUs using the ACPI parking protocol
is possible but discouraged, only PSCI is to be supported for
ARM systems".

[...]

> diff --git a/Documentation/arm64/arm-acpi.txt 
> b/Documentation/arm64/arm-acpi.txt
> index 570a4f8..12381c1 100644
> --- a/Documentation/arm64/arm-acpi.txt
> +++ b/Documentation/arm64/arm-acpi.txt
> @@ -57,11 +57,11 @@ The short form of the rationale for ACPI on ARM is:
>  
>  -- The new ACPI governance process works well and Linux is now at the same
> table as hardware vendors and other OS vendors.  In fact, there is no
> -   longer any reason to feel that ACPI is only belongs to Windows or that
> +   longer any reason to feel that ACPI only belongs to Windows or that
> Linux is in any way secondary to Microsoft in this arena.  The move of
> ACPI governance into the UEFI forum has significantly opened up the
> specification development process, and currently, a large portion of the
> -   changes being made to ACPI is being driven by Linux.
> +   changes being made to ACPI are being driven by Linux.
>  
>  Key to the use of ACPI is the support model.  For servers in general, the
>  responsibility for hardware behaviour cannot solely be the domain of the
> @@ -159,7 +159,7 @@ Further, the ACPI core will only use the 64-bit address 
> fields in the FADT
>  (Fixed ACPI Description Table).  Any 32-bit address fields in the FADT will
>  be ignored on arm64.
>  
> -Hardware reduced mode (see Section 4.1 of the ACPI 5.1 specification) will
> +Hardware reduced mode (see Section 4.1 of the ACPI 6.1 specification) will
>  be enforced by the ACPI core on arm64.  Doing so allows the ACPI core to
>  run less complex code since it no longer has to provide support for legacy
>  hardware from other architectures.  Any fields that are not to be used for
> @@ -167,7 +167,7 @@ hardware reduced mode must be set to zero.
>  
>  For the ACPI core to operate properly, and in turn provide the information
>  the kernel needs to configure devices, it expects to find the following
> -tables (all section numbers refer to the ACPI 5.1 specfication):
> +tables (all section numbers refer to the ACPI 6.1 specfication):

s/specfication/specification

There are others in this document.

>  
>  -- RSDP (Root System Description Pointer), section 5.2.5
>  
> @@ -185,9 +185,22 @@ tables (all section numbers refer to the ACPI 5.1 
> specfication):
>  -- If PCI is supported, the MCFG (Memory mapped ConFiGuration
> Table), section 5.2.6, specifically Table 5-31.
>  
> +-- If booting without a console= kernel parameter is
> +   supported, the SPCR (Serial Port Console Redirection table),
> +   section 5.2.6, specifically Table 5-31.
> +
> +-- If virtualization is supported, the IORT (Input Output Remapping
> +   Table, section 5.2.6, specifically Table 5-31.

Why only "If virtualization is supported" ? Missing closing bracket.

I still question sections of this document that IMHO do not belong
in the kernel documentation (but in the ACPI specs - eg _PRx methods
usage), anyway the information seems accurate so, pending changes above:

Acked-by: Lorenzo Pieralisi <lorenzo.pieral...@arm.com>


Re: [RFC PATCH 06/11] drivers: iommu: make of_xlate() interface DT agnostic

2016-04-19 Thread Lorenzo Pieralisi
Hi Marek,

On Tue, Apr 19, 2016 at 10:28:02AM +0200, Marek Szyprowski wrote:
> Hello,
> 
> On 2016-04-14 19:25, Lorenzo Pieralisi wrote:
> >On systems booting with ACPI, the IOMMU drivers require the same
> >kind of id mapping carried out with a DT tree through the of_xlate()
> >API in order to map devices identifiers to IOMMU ones.
> >
> >On ACPI systems, since DT nodes are not present (ie struct
> >device.of_node == NULL), to identify the device requiring the translation
> >the struct device_node (and the structure used to pass translation
> >information - struct of_phandle_args - that contains a struct device_node)
> >cannot be used, so a generic translation structure to be used for IOMMU
> >mapping should be defined, based on the firmware agnostic fwnode_handle
> >type.
> >
> >This patch mechanically refactors/renames the of_xlate API to make
> >it DT agnostic, by declaring a new type (struct iommu_fwspec), that
> >allows the kernel to pass a device identifier (fwnode - which can
> >represent either a DT node or an IOMMU FW node) and by changing the
> >of_xlate signature so that it does not take anymore the DT specific
> >of_phandle_args argument and replaces it with the DT agnostic
> >iommu_fwspec one.
> >
> >Signed-off-by: Lorenzo Pieralisi <lorenzo.pieral...@arm.com>
> >Cc: Matthias Brugger <matthias@gmail.com>
> >Cc: Will Deacon <will.dea...@arm.com>
> >Cc: Hanjun Guo <hanjun@linaro.org>
> >Cc: Rob Herring <robh...@kernel.org>
> >Cc: Krzysztof Kozlowski <k.kozlow...@samsung.com>
> >Cc: Robin Murphy <robin.mur...@arm.com>
> >Cc: Tomasz Nowicki <t...@semihalf.com>
> >Cc: Joerg Roedel <j...@8bytes.org>
> >Cc: Marek Szyprowski <m.szyprow...@samsung.com>
> 
> I'm not sure if this is the right approach, although I have not enough
> knowledge on ACPI firmware. Do you plan to rewrite all subsystems to the
> new "fwspec" based interface? Right now of_xlate is rather common
> interface used by various subsystems. Maybe it will be much easier to

Yes, that's a valid concern, when you say "it is rather common" though,
it seems to me that the of_xlate footprint is still subsystem specific,
so this patch should be self-contained anyway (granted, doing this
conversion for a specific subsystem is questionable, I guess that what
you are asking is, if you do it for IOMMU, why would not you do it for
other subsystems ?).

It is an RFC for this specific reason.

> just add acpi_xlate callback and plumb it to the generic code? Maybe later
> when similar code will be in other subsystems and drivers, it can be
> unified, having much more real use cases?

Yes, that's a possibility, it means adding yet another hook into
the IOMMU drivers, probably a simpler change than this one, I
posted this code as and RFC to see which direction we want to take
so further feedback is welcome we can then choose the best approach.

Thanks,
Lorenzo

> 
> >---
> >  drivers/iommu/arm-smmu.c | 12 +++-
> >  drivers/iommu/exynos-iommu.c | 11 +++
> >  drivers/iommu/mtk_iommu.c| 13 -
> >  drivers/iommu/of_iommu.c | 20 ++--
> >  include/linux/iommu.h| 24 
> >  5 files changed, 60 insertions(+), 20 deletions(-)
> >
> >diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
> >index 6c42770..84bcff7 100644
> >--- a/drivers/iommu/arm-smmu.c
> >+++ b/drivers/iommu/arm-smmu.c
> >@@ -1440,18 +1440,20 @@ out_unlock:
> > return ret;
> >  }
> >-static int arm_smmu_of_xlate(struct device *dev, struct of_phandle_args 
> >*args)
> >+static int arm_smmu_fw_xlate(struct device *dev, struct iommu_fwspec *args)
> >  {
> > struct arm_smmu_device *smmu;
> >-struct platform_device *smmu_pdev;
> >+struct platform_device *smmu_pdev = NULL;
> >+
> >+if (is_of_node(args->fwnode))
> >+smmu_pdev = of_find_device_by_node(to_of_node(args->fwnode));
> >-smmu_pdev = of_find_device_by_node(args->np);
> > if (!smmu_pdev)
> > return -ENODEV;
> > smmu = platform_get_drvdata(smmu_pdev);
> >-return arm_smmu_add_dev_streamid(smmu, dev, args->args[0]);
> >+return arm_smmu_add_dev_streamid(smmu, dev, args->param[0]);
> >  }
> >  static struct iommu_ops arm_smmu_ops = {
> >@@ -1468,7 +1470,7 @@ static struct iommu_ops arm_smmu_ops = {
> > .device_group   = arm_smmu_device_group,
> > .domain_get_attr= arm_smmu_domain_get_attr,
> > .domain_set_attr   

[RFC PATCH 11/11] drivers: irqchip: make struct irq_fwspec generic

2016-04-14 Thread Lorenzo Pieralisi
The struct irq_fwspec is used in IRQ domain core code to carry out
IRQ translations (on both DT and ACPI systems) but it has nothing
IRQ specific in it, hence it can be reused by other kernel subsystems
(ie IOMMU) to carry out translation mappings as they deem fit.

This patch mechanically converts the struct irq_fwspec to a generic
struct fwspec available to all kernel subsystems that envisage a use
for it, and generalizes the IRQ domain helper (that is not IRQ domain
specific) to translate struct of_phandle_args to a struct fwspec.

Since the struct fwspec is subsystem agnostic, the struct iommu_fwspec
can be converted to it too in all kernel components currently making
use of it.

Signed-off-by: Lorenzo Pieralisi <lorenzo.pieral...@arm.com>
Cc: Joerg Roedel <j...@8bytes.org>
Cc: "Rafael J. Wysocki" <r...@rjwysocki.net>
Cc: Marc Zyngier <marc.zyng...@arm.com>
---
 Documentation/IRQ-domain.txt |  2 +-
 arch/arm/mach-exynos/suspend.c   |  6 +++---
 arch/arm/mach-imx/gpc.c  |  6 +++---
 arch/arm/mach-omap2/omap-wakeupgen.c |  6 +++---
 drivers/acpi/gsi.c   |  2 +-
 drivers/acpi/iort.c  |  2 +-
 drivers/gpio/gpio-xgene-sb.c |  8 
 drivers/iommu/arm-smmu.c |  2 +-
 drivers/iommu/exynos-iommu.c |  2 +-
 drivers/iommu/mtk_iommu.c|  2 +-
 drivers/iommu/of_iommu.c | 14 +-
 drivers/irqchip/irq-alpine-msi.c |  2 +-
 drivers/irqchip/irq-crossbar.c   |  6 +++---
 drivers/irqchip/irq-gic-v2m.c|  2 +-
 drivers/irqchip/irq-gic-v3-its.c |  2 +-
 drivers/irqchip/irq-gic-v3.c |  4 ++--
 drivers/irqchip/irq-gic.c|  4 ++--
 drivers/irqchip/irq-imx-gpcv2.c  |  6 +++---
 drivers/irqchip/irq-mbigen.c |  4 ++--
 drivers/irqchip/irq-mips-gic.c   |  2 +-
 drivers/irqchip/irq-mtk-sysirq.c |  6 +++---
 drivers/irqchip/irq-mvebu-odmi.c |  2 +-
 drivers/irqchip/irq-nvic.c   |  4 ++--
 drivers/irqchip/irq-tegra.c  |  6 +++---
 drivers/irqchip/irq-vf610-mscm-ir.c  |  6 +++---
 drivers/of/base.c| 24 
 include/linux/fwnode.h   | 20 
 include/linux/iommu.h| 20 +---
 include/linux/irqdomain.h| 22 ++
 include/linux/of.h   |  7 +++
 kernel/irq/irqdomain.c   | 17 +++--
 31 files changed, 105 insertions(+), 113 deletions(-)

diff --git a/Documentation/IRQ-domain.txt b/Documentation/IRQ-domain.txt
index 8d990bd..c9085e5 100644
--- a/Documentation/IRQ-domain.txt
+++ b/Documentation/IRQ-domain.txt
@@ -32,7 +32,7 @@ top of the irq_alloc_desc*() API.  An irq_domain to manage 
mapping is
 preferred over interrupt controller drivers open coding their own
 reverse mapping scheme.
 
-irq_domain also implements translation from an abstract irq_fwspec
+irq_domain also implements translation from an abstract fwspec
 structure to hwirq numbers (Device Tree and ACPI GSI so far), and can
 be easily extended to support other IRQ topology data sources.
 
diff --git a/arch/arm/mach-exynos/suspend.c b/arch/arm/mach-exynos/suspend.c
index fee2b00..40a48c0 100644
--- a/arch/arm/mach-exynos/suspend.c
+++ b/arch/arm/mach-exynos/suspend.c
@@ -179,7 +179,7 @@ static struct irq_chip exynos_pmu_chip = {
 };
 
 static int exynos_pmu_domain_translate(struct irq_domain *d,
-  struct irq_fwspec *fwspec,
+  struct fwspec *fwspec,
   unsigned long *hwirq,
   unsigned int *type)
 {
@@ -203,8 +203,8 @@ static int exynos_pmu_domain_alloc(struct irq_domain 
*domain,
   unsigned int virq,
   unsigned int nr_irqs, void *data)
 {
-   struct irq_fwspec *fwspec = data;
-   struct irq_fwspec parent_fwspec;
+   struct fwspec *fwspec = data;
+   struct fwspec parent_fwspec;
irq_hw_number_t hwirq;
int i;
 
diff --git a/arch/arm/mach-imx/gpc.c b/arch/arm/mach-imx/gpc.c
index fd87205..5e4aac6 100644
--- a/arch/arm/mach-imx/gpc.c
+++ b/arch/arm/mach-imx/gpc.c
@@ -184,7 +184,7 @@ static struct irq_chip imx_gpc_chip = {
 };
 
 static int imx_gpc_domain_translate(struct irq_domain *d,
-   struct irq_fwspec *fwspec,
+   struct fwspec *fwspec,
unsigned long *hwirq,
unsigned int *type)
 {
@@ -208,8 +208,8 @@ static int imx_gpc_domain_alloc(struct irq_domain *domain,
  unsigned int irq,
  unsigned int nr_irqs, void *data)
 {
-   struct irq_fwspec *fwspec = data;
-   struct irq_fwspec parent_fwspec;
+   struct fwspec *fwspec = data;
+

[RFC PATCH 01/11] drivers: acpi: iort: fix struct pci_dev compiler warnings

2016-04-14 Thread Lorenzo Pieralisi
When the kernel is configured with no IORT support the compilation
issues the following warnings:

In file included from drivers/irqchip/irq-gic-v3-its-pci-msi.c:19:0:
include/linux/iort.h:28:33: warning: 'struct pci_dev' declared inside
parameter list
 u32 iort_pci_get_msi_rid(struct pci_dev *pdev, u32 req_id);
 ^
include/linux/iort.h:28:33: warning: its scope is only this definition
or declaration, which is probably not what you want
include/linux/iort.h:29:50: warning: 'struct pci_dev' declared inside
parameter list
 struct fwnode_handle *iort_pci_get_domain(struct pci_dev *pdev, u32
req_id);

This patch fixes the warnings with a struct pci_dev forward declaration
in the IORT header file.

Signed-off-by: Lorenzo Pieralisi <lorenzo.pieral...@arm.com>
Cc: Tomasz Nowicki <t...@semihalf.com>
---
 include/linux/iort.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/linux/iort.h b/include/linux/iort.h
index 7441941..b15fe1a 100644
--- a/include/linux/iort.h
+++ b/include/linux/iort.h
@@ -21,6 +21,7 @@
 
 #include 
 
+struct pci_dev;
 struct fwnode_handle;
 int iort_register_domain_token(int trans_id, struct fwnode_handle *fw_node);
 void iort_deregister_domain_token(int trans_id);
-- 
2.6.4



[RFC PATCH 06/11] drivers: iommu: make of_xlate() interface DT agnostic

2016-04-14 Thread Lorenzo Pieralisi
On systems booting with ACPI, the IOMMU drivers require the same
kind of id mapping carried out with a DT tree through the of_xlate()
API in order to map devices identifiers to IOMMU ones.

On ACPI systems, since DT nodes are not present (ie struct
device.of_node == NULL), to identify the device requiring the translation
the struct device_node (and the structure used to pass translation
information - struct of_phandle_args - that contains a struct device_node)
cannot be used, so a generic translation structure to be used for IOMMU
mapping should be defined, based on the firmware agnostic fwnode_handle
type.

This patch mechanically refactors/renames the of_xlate API to make
it DT agnostic, by declaring a new type (struct iommu_fwspec), that
allows the kernel to pass a device identifier (fwnode - which can
represent either a DT node or an IOMMU FW node) and by changing the
of_xlate signature so that it does not take anymore the DT specific
of_phandle_args argument and replaces it with the DT agnostic
iommu_fwspec one.

Signed-off-by: Lorenzo Pieralisi <lorenzo.pieral...@arm.com>
Cc: Matthias Brugger <matthias@gmail.com>
Cc: Will Deacon <will.dea...@arm.com>
Cc: Hanjun Guo <hanjun@linaro.org>
Cc: Rob Herring <robh...@kernel.org>
Cc: Krzysztof Kozlowski <k.kozlow...@samsung.com>
Cc: Robin Murphy <robin.mur...@arm.com>
Cc: Tomasz Nowicki <t...@semihalf.com>
Cc: Joerg Roedel <j...@8bytes.org>
Cc: Marek Szyprowski <m.szyprow...@samsung.com>
---
 drivers/iommu/arm-smmu.c | 12 +++-
 drivers/iommu/exynos-iommu.c | 11 +++
 drivers/iommu/mtk_iommu.c| 13 -
 drivers/iommu/of_iommu.c | 20 ++--
 include/linux/iommu.h| 24 
 5 files changed, 60 insertions(+), 20 deletions(-)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 6c42770..84bcff7 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -1440,18 +1440,20 @@ out_unlock:
return ret;
 }
 
-static int arm_smmu_of_xlate(struct device *dev, struct of_phandle_args *args)
+static int arm_smmu_fw_xlate(struct device *dev, struct iommu_fwspec *args)
 {
struct arm_smmu_device *smmu;
-   struct platform_device *smmu_pdev;
+   struct platform_device *smmu_pdev = NULL;
+
+   if (is_of_node(args->fwnode))
+   smmu_pdev = of_find_device_by_node(to_of_node(args->fwnode));
 
-   smmu_pdev = of_find_device_by_node(args->np);
if (!smmu_pdev)
return -ENODEV;
 
smmu = platform_get_drvdata(smmu_pdev);
 
-   return arm_smmu_add_dev_streamid(smmu, dev, args->args[0]);
+   return arm_smmu_add_dev_streamid(smmu, dev, args->param[0]);
 }
 
 static struct iommu_ops arm_smmu_ops = {
@@ -1468,7 +1470,7 @@ static struct iommu_ops arm_smmu_ops = {
.device_group   = arm_smmu_device_group,
.domain_get_attr= arm_smmu_domain_get_attr,
.domain_set_attr= arm_smmu_domain_set_attr,
-   .of_xlate   = arm_smmu_of_xlate,
+   .fw_xlate   = arm_smmu_fw_xlate,
.pgsize_bitmap  = -1UL, /* Restricted during device attach */
 };
 
diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 5ecc86c..84ff5bb 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -1250,13 +1250,16 @@ static void exynos_iommu_remove_device(struct device 
*dev)
iommu_group_remove_device(dev);
 }
 
-static int exynos_iommu_of_xlate(struct device *dev,
-struct of_phandle_args *spec)
+static int exynos_iommu_fw_xlate(struct device *dev,
+struct iommu_fwspec *args)
 {
struct exynos_iommu_owner *owner = dev->archdata.iommu;
-   struct platform_device *sysmmu = of_find_device_by_node(spec->np);
+   struct platform_device *sysmmu = NULL;
struct sysmmu_drvdata *data;
 
+   if (is_of_node(args->fwnode))
+   sysmmu = of_find_device_by_node(to_of_node(args->fwnode));
+
if (!sysmmu)
return -ENODEV;
 
@@ -1290,7 +1293,7 @@ static struct iommu_ops exynos_iommu_ops = {
.add_device = exynos_iommu_add_device,
.remove_device = exynos_iommu_remove_device,
.pgsize_bitmap = SECT_SIZE | LPAGE_SIZE | SPAGE_SIZE,
-   .of_xlate = exynos_iommu_of_xlate,
+   .fw_xlate = exynos_iommu_fw_xlate,
 };
 
 static bool init_done;
diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 929a66a..e08dc0a 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -436,20 +436,23 @@ static struct iommu_group *mtk_iommu_device_group(struct 
device *dev)
return data->m4u_group;
 }
 
-static int mtk_iommu_of_xlate(struct device *dev, struct of_phandle_args *args)
+static int mtk_iommu_fw_xlate(struct device *dev, struct iommu

[RFC PATCH 08/11] drivers: acpi: iort: enhance mapping API

2016-04-14 Thread Lorenzo Pieralisi
The current IORT API works only for mappings that have the GIC ITS
as a sink node and does not allow mapping components other than
PCI root complexes.

This patch enhances the IORT API to allow any mapping permitted by
the IORT specifications, inclusive of IORT translations for named
components.

Based on prior work by Hanjun Guo <hanjun@linaro.org>.

Signed-off-by: Lorenzo Pieralisi <lorenzo.pieral...@arm.com>
Cc: Hanjun Guo <hanjun@linaro.org>
Cc: Tomasz Nowicki <t...@semihalf.com>
Cc: "Rafael J. Wysocki" <r...@rjwysocki.net>
---
 drivers/acpi/iort.c | 59 +++--
 1 file changed, 53 insertions(+), 6 deletions(-)

diff --git a/drivers/acpi/iort.c b/drivers/acpi/iort.c
index 080888a..2b5ce65 100644
--- a/drivers/acpi/iort.c
+++ b/drivers/acpi/iort.c
@@ -182,15 +182,61 @@ iort_scan_node(enum acpi_iort_node_type type,
return NULL;
 }
 
+static struct acpi_iort_node *
+iort_find_parent_node(struct acpi_iort_node *node, u8 type)
+{
+   struct acpi_iort_id_mapping *id;
+
+   if (!node || !node->mapping_offset || !node->mapping_count)
+   return NULL;
+
+   id = ACPI_ADD_PTR(struct acpi_iort_id_mapping, node,
+ node->mapping_offset);
+
+   if (!id->output_reference) {
+   pr_err(FW_BUG "[node %p type %d] ID map has NULL parent 
reference\n",
+  node, node->type);
+   return NULL;
+   }
+
+   node = ACPI_ADD_PTR(struct acpi_iort_node, iort_table,
+   id->output_reference);
+
+   return node->type == type ? node : NULL;
+}
+
 static acpi_status
 iort_find_dev_callback(struct acpi_iort_node *node, void *context)
 {
-   struct acpi_iort_root_complex *pci_rc;
struct device *dev = context;
-   struct pci_bus *bus;
 
switch (node->type) {
-   case ACPI_IORT_NODE_PCI_ROOT_COMPLEX:
+   case ACPI_IORT_NODE_NAMED_COMPONENT: {
+   struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+   struct acpi_iort_named_component *ncomp;
+   struct acpi_device *adev = to_acpi_device_node(dev->fwnode);
+
+   if (!adev)
+   break;
+
+   ncomp = (struct acpi_iort_named_component *)node->node_data;
+
+   if (ACPI_FAILURE(acpi_get_name(adev->handle,
+  ACPI_FULL_PATHNAME, ))) {
+   pr_warn("Can't get device full path name\n");
+   break;
+   }
+
+   if (!strcmp(ncomp->device_name, (char *)buffer.pointer))
+   return AE_OK;
+
+   break;
+   }
+
+   case ACPI_IORT_NODE_PCI_ROOT_COMPLEX: {
+   struct acpi_iort_root_complex *pci_rc;
+   struct pci_bus *bus;
+
bus = to_pci_bus(dev);
pci_rc = (struct acpi_iort_root_complex *)node->node_data;
 
@@ -204,20 +250,21 @@ iort_find_dev_callback(struct acpi_iort_node *node, void 
*context)
 
break;
}
+   }
 
return AE_NOT_FOUND;
 }
 
 static struct acpi_iort_node *
 iort_dev_map_rid(struct acpi_iort_node *node, u32 rid_in,
-   u32 *rid_out)
+   u32 *rid_out, u8 type)
 {
 
if (!node)
goto out;
 
/* Go upstream */
-   while (node->type != ACPI_IORT_NODE_ITS_GROUP) {
+   while (node->type != type) {
struct acpi_iort_id_mapping *id;
int i, found = 0;
 
@@ -283,7 +330,7 @@ iort_its_find_node_and_map_rid(struct pci_dev *pdev, u32 
req_id, u32 *dev_id)
return NULL;
}
 
-   return iort_dev_map_rid(node, req_id, dev_id);
+   return iort_dev_map_rid(node, req_id, dev_id, ACPI_IORT_NODE_ITS_GROUP);
 }
 
 /**
-- 
2.6.4



[RFC PATCH 03/11] drivers: iommu: add FWNODE_IOMMU fwnode type

2016-04-14 Thread Lorenzo Pieralisi
On systems booting with a device tree, every struct device is
associated with a struct device_node, that represents its DT
representation. The device node can be used in generic kernel
contexts (eg IRQ translation, IOMMU streamid mapping), to
retrieve the properties associated with the device and carry
out kernel operation accordingly. Owing to the 1:1 relationship
between the device and its device_node, the device_node can also
be used as a look-up token for the device (eg looking up a device
through its device_node), to retrieve the device in kernel paths
where the device_node is available.

On systems booting with ACPI, the same abstraction provided by
the device_node is required to provide:

- Look-up functionality
- Identify the device in kernel functions that must be firmware
  agnostic (eg IOMMU of_xlate() callbacks)

Therefore, mirroring the approach implemented in the IRQ domain
kernel layer, this patch adds an additional fwnode type FWNODE_IOMMU.

This patch also implements a glue kernel layer that allows to
allocate/free FWNODE_IOMMU fwnode_handle structures and associate
them with IOMMU devices.

Signed-off-by: Lorenzo Pieralisi <lorenzo.pieral...@arm.com>
Cc: Joerg Roedel <j...@8bytes.org>
Cc: "Rafael J. Wysocki" <r...@rjwysocki.net>
---
 include/linux/fwnode.h |  1 +
 include/linux/iommu.h  | 25 +
 2 files changed, 26 insertions(+)

diff --git a/include/linux/fwnode.h b/include/linux/fwnode.h
index 8516717..6e10050 100644
--- a/include/linux/fwnode.h
+++ b/include/linux/fwnode.h
@@ -19,6 +19,7 @@ enum fwnode_type {
FWNODE_ACPI_DATA,
FWNODE_PDATA,
FWNODE_IRQCHIP,
+   FWNODE_IOMMU,
 };
 
 struct fwnode_handle {
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index a5c539f..0bba25e 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -37,6 +37,7 @@ struct bus_type;
 struct device;
 struct iommu_domain;
 struct notifier_block;
+struct fwnode_handle;
 
 /* iommu fault flags */
 #define IOMMU_FAULT_READ   0x0
@@ -542,4 +543,28 @@ static inline void iommu_device_unlink(struct device *dev, 
struct device *link)
 
 #endif /* CONFIG_IOMMU_API */
 
+/* IOMMU fwnode handling */
+static inline bool is_fwnode_iommu(struct fwnode_handle *fwnode)
+{
+   return fwnode && fwnode->type == FWNODE_IOMMU;
+}
+
+static inline struct fwnode_handle *iommu_alloc_fwnode(void)
+{
+   struct fwnode_handle *fwnode;
+
+   fwnode = kzalloc(sizeof(struct fwnode_handle), GFP_KERNEL);
+   fwnode->type = FWNODE_IOMMU;
+
+   return fwnode;
+}
+
+static inline void iommu_free_fwnode(struct fwnode_handle *fwnode)
+{
+   if (WARN_ON(!is_fwnode_iommu(fwnode)))
+   return;
+
+   kfree(fwnode);
+}
+
 #endif /* __LINUX_IOMMU_H */
-- 
2.6.4



[RFC PATCH 10/11] drivers: iommu: arm-smmu: implement ACPI probing

2016-04-14 Thread Lorenzo Pieralisi
In ACPI world ARM SMMU components are described through IORT table
entries, that contain SMMU parameters and provide the kernel with
data to create the corresponding kernel abstractions and allow
SMMU probing and initialization.

Currently, the arm-smmu driver probe routines are DT based, hence,
to enable the driver to probe through ACPI they should be augmented
so that the DT and ACPI probing paths can actually share the common
code that probes and initializes the ARM SMMU allowing them to co-exist
seamlessly.

This patch refactors the ARM SMMU probing path to introduce ACPI
probing effectively enabling the ARM SMMU on ACPI based systems.

To create the required platform devices representing ARM SMMU components
and initialize them with the required data, this patch also implements
ARM SMMU ACPI probing by adding a hook into the ACPI IORT linker section,
that is executed automatically by the kernel on boot and allows
to detect and configure the ARM SMMU devices present in the system.

Based on prior work by Hanjun Guo <hanjun@linaro.org>.

Signed-off-by: Lorenzo Pieralisi <lorenzo.pieral...@arm.com>
Cc: Will Deacon <will.dea...@arm.com>
Cc: Hanjun Guo <hanjun@linaro.org>
Cc: Robin Murphy <robin.mur...@arm.com>
Cc: Tomasz Nowicki <t...@semihalf.com>
---
 drivers/iommu/arm-smmu.c | 240 +--
 include/linux/iort.h |   3 +
 2 files changed, 233 insertions(+), 10 deletions(-)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 0f1e784..85ab4b7 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -28,6 +28,7 @@
 
 #define pr_fmt(fmt) "arm-smmu: " fmt
 
+#include 
 #include 
 #include 
 #include 
@@ -36,6 +37,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -1729,6 +1731,103 @@ static int arm_smmu_device_cfg_probe(struct 
arm_smmu_device *smmu)
return 0;
 }
 
+#ifdef CONFIG_ACPI
+static int __init acpi_smmu_version(u32 model, u32 *version)
+{
+   switch (model) {
+   case ACPI_IORT_SMMU_V1:
+   case ACPI_IORT_SMMU_CORELINK_MMU400:
+   *version = ARM_SMMU_V1;
+   return 0;
+   case ACPI_IORT_SMMU_V2:
+   case ACPI_IORT_SMMU_CORELINK_MMU500:
+   *version = ARM_SMMU_V2;
+   return 0;
+   default:
+   break;
+   }
+
+   return -ENODEV;
+}
+
+static int __init arm_smmu_acpi_probe(struct platform_device *pdev,
+ struct arm_smmu_device *smmu)
+{
+   struct device *dev = smmu->dev;
+   struct acpi_iort_node *node =
+   *(struct acpi_iort_node **)dev_get_platdata(dev);
+   struct acpi_iort_smmu *iort_smmu;
+   int num_irqs, i, err, trigger, ret, irq_idx;
+   u64 *ctx_irq, *glb_irq;
+
+   /* Retrieve SMMU1/2 specific data */
+   iort_smmu = (struct acpi_iort_smmu *)node->node_data;
+
+   ret = acpi_smmu_version(iort_smmu->model, >version);
+   if (ret < 0)
+   return ret;
+
+   glb_irq = ACPI_ADD_PTR(u64, node, iort_smmu->global_interrupt_offset);
+   if (!IORT_IRQ_MASK(glb_irq[1])) /* 0 means not implemented */
+   smmu->num_global_irqs = 1;
+   else
+   smmu->num_global_irqs = 2;
+
+   smmu->num_context_irqs = iort_smmu->context_interrupt_count;
+   num_irqs = smmu->num_context_irqs + smmu->num_global_irqs;
+
+   if (!smmu->num_context_irqs) {
+   dev_err(dev, "found %d interrupts but expected at least %d\n",
+   num_irqs, smmu->num_global_irqs + 1);
+   return -ENODEV;
+   }
+
+   smmu->irqs = devm_kzalloc(dev, sizeof(*smmu->irqs) * num_irqs,
+ GFP_KERNEL);
+   if (!smmu->irqs) {
+   dev_err(dev, "failed to allocate %d irqs\n", num_irqs);
+   return -ENOMEM;
+   }
+
+   /* Global IRQs */
+   for (i = irq_idx = 0; i < smmu->num_global_irqs; i++, irq_idx++) {
+   int hw_irq = IORT_IRQ_MASK(glb_irq[i]);
+
+   trigger = IORT_IRQ_TRIGGER_MASK(glb_irq[i]);
+   smmu->irqs[irq_idx] = acpi_register_gsi(NULL, hw_irq, trigger,
+   ACPI_ACTIVE_HIGH);
+   }
+
+   /* Context IRQs */
+   ctx_irq = ACPI_ADD_PTR(u64, node, iort_smmu->context_interrupt_offset);
+   for (i = 0; i < smmu->num_context_irqs; i++, irq_idx++) {
+   int hw_irq = IORT_IRQ_MASK(ctx_irq[i]);
+
+   trigger = IORT_IRQ_TRIGGER_MASK(ctx_irq[i]);
+   smmu->irqs[irq_idx] = acpi_register_gsi(NULL, hw_irq, trigger,
+   ACPI_ACTIVE_HIGH);
+   }
+
+   if (iort_smmu->flags & ACPI_IORT_SMMU_COHERENT_WALK)
+   smmu->features |= ARM_

[RFC PATCH 05/11] drivers: iommu: arm-smmu: split probe functions into DT/generic portions

2016-04-14 Thread Lorenzo Pieralisi
Current ARM SMMU probe functions intermingle HW and DT probing
in the initialization functions to detect and programme the ARM SMMU
driver features. In order to allow probing the ARM SMMU with other
firmwares than DT, this patch splits the ARM SMMU init functions into
DT and HW specific portions so that other FW interfaces (ie ACPI) can
reuse the HW probing functions and skip the DT portion accordingly.

This patch implements no functional change, only code reshuffling.

Signed-off-by: Lorenzo Pieralisi <lorenzo.pieral...@arm.com>
Cc: Will Deacon <will.dea...@arm.com>
Cc: Hanjun Guo <hanjun@linaro.org>
Cc: Robin Murphy <robin.mur...@arm.com>
---
 drivers/iommu/arm-smmu.c | 80 +++-
 1 file changed, 52 insertions(+), 28 deletions(-)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 2d65de4..6c42770 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -1551,7 +1551,7 @@ static int arm_smmu_device_cfg_probe(struct 
arm_smmu_device *smmu)
unsigned long size;
void __iomem *gr0_base = ARM_SMMU_GR0(smmu);
u32 id;
-   bool cttw_dt, cttw_reg;
+   bool cttw_reg, cttw_fw = smmu->features & ARM_SMMU_FEAT_COHERENT_WALK;
 
dev_notice(smmu->dev, "probing hardware configuration...\n");
dev_notice(smmu->dev, "SMMUv%d with:\n", smmu->version);
@@ -1593,20 +1593,18 @@ static int arm_smmu_device_cfg_probe(struct 
arm_smmu_device *smmu)
 
/*
 * In order for DMA API calls to work properly, we must defer to what
-* the DT says about coherency, regardless of what the hardware claims.
+* the FW says about coherency, regardless of what the hardware
+* claims.
 * Fortunately, this also opens up a workaround for systems where the
 * ID register value has ended up configured incorrectly.
 */
-   cttw_dt = of_dma_is_coherent(smmu->dev->of_node);
cttw_reg = !!(id & ID0_CTTW);
-   if (cttw_dt)
-   smmu->features |= ARM_SMMU_FEAT_COHERENT_WALK;
-   if (cttw_dt || cttw_reg)
+   if (cttw_fw || cttw_reg)
dev_notice(smmu->dev, "\t%scoherent table walk\n",
-  cttw_dt ? "" : "non-");
-   if (cttw_dt != cttw_reg)
+  cttw_fw ? "" : "non-");
+   if (cttw_fw != cttw_reg)
dev_notice(smmu->dev,
-  "\t(IDR0.CTTW overridden by dma-coherent 
property)\n");
+  "\t(IDR0.CTTW overridden by FW configuration)\n");
 
if (id & ID0_SMS) {
u32 smr, sid, mask;
@@ -1827,30 +1825,17 @@ static int arm_smmu_probe_mmu_masters(struct 
arm_smmu_device *smmu)
return err;
 }
 
-static int arm_smmu_device_dt_probe(struct platform_device *pdev)
+static int arm_smmu_dt_probe(struct platform_device *pdev,
+struct arm_smmu_device *smmu)
 {
const struct of_device_id *of_id;
struct resource *res;
-   struct arm_smmu_device *smmu;
struct device *dev = >dev;
int num_irqs, i, err;
 
-   smmu = devm_kzalloc(dev, sizeof(*smmu), GFP_KERNEL);
-   if (!smmu) {
-   dev_err(dev, "failed to allocate arm_smmu_device\n");
-   return -ENOMEM;
-   }
-   smmu->dev = dev;
-
of_id = of_match_node(arm_smmu_of_match, dev->of_node);
smmu->version = (enum arm_smmu_arch_version)of_id->data;
 
-   res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-   smmu->base = devm_ioremap_resource(dev, res);
-   if (IS_ERR(smmu->base))
-   return PTR_ERR(smmu->base);
-   smmu->size = resource_size(res);
-
if (of_property_read_u32(dev->of_node, "#global-interrupts",
 >num_global_irqs)) {
dev_err(dev, "missing #global-interrupts property\n");
@@ -1887,12 +1872,54 @@ static int arm_smmu_device_dt_probe(struct 
platform_device *pdev)
smmu->irqs[i] = irq;
}
 
+   /*
+* In order for DMA API calls to work properly, we must defer to what
+* the DT says about coherency, regardless of what the hardware detect
+* through probing in arm_smmu_device_cfg_probe(). Check the DT dma
+* coherent property and initialize the corresponding SMMU feature
+* so that arm_smmu_device_cfg_probe() can check the FW reported value.
+*/
+   if (of_dma_is_coherent(smmu->dev->of_node))
+   smmu->features |= ARM_SMMU_FEAT_COHERENT_WALK;
+
err = arm_smmu_device_cfg_probe(smmu);
if (err)
return err;
 
parse_driver_options(smmu);
 
+   /* Check first to avoid of_parse_phandle_with_args complai

[RFC PATCH 04/11] drivers: acpi: iort: introduce linker section for IORT entries probing

2016-04-14 Thread Lorenzo Pieralisi
Since commit e647b532275b ("ACPI: Add early device probing
infrastructure") the kernel has gained the infrastructure that allows
adding linker script section entries to execute ACPI driver callbacks
(ie probe routines) for all subsystems that register a table entry
in the respective kernel section (eg clocksource, irqchip).

Since ARM IOMMU devices data is described through IORT tables when
booting with ACPI, the ARM IOMMU drivers must be made able to hook ACPI
callback routines that are called to probe IORT entries and initialize
the respective IOMMU devices.

To avoid adding driver specific hooks into IORT table initialization
code (breaking therefore code modularity - ie ACPI IORT code must be made
aware of ARM SMMU drivers ACPI init callbacks), this patch adds code
that allows ARM SMMU drivers to take advantage of the ACPI early probing
infrastructure, so that they can add linker script section entries
containing drivers callback to be executed on IORT tables detection.

Since IORT nodes are differentiated by a type, the callback routines
can easily parse the IORT table entries, check the IORT nodes and
carry out some actions whenever the IORT node type associated with
the driver specific callback is matched.

Signed-off-by: Lorenzo Pieralisi <lorenzo.pieral...@arm.com>
Cc: Tomasz Nowicki <t...@semihalf.com>
Cc: "Rafael J. Wysocki" <r...@rjwysocki.net>
Cc: Marc Zyngier <marc.zyng...@arm.com>
---
 drivers/acpi/iort.c   | 2 ++
 include/asm-generic/vmlinux.lds.h | 1 +
 include/linux/iort.h  | 3 +++
 3 files changed, 6 insertions(+)

diff --git a/drivers/acpi/iort.c b/drivers/acpi/iort.c
index 98db580..080888a 100644
--- a/drivers/acpi/iort.c
+++ b/drivers/acpi/iort.c
@@ -372,6 +372,8 @@ static int __init iort_table_detect(void)
return -EINVAL;
}
 
+   acpi_probe_device_table(iort);
+
return 0;
 }
 arch_initcall(iort_table_detect);
diff --git a/include/asm-generic/vmlinux.lds.h 
b/include/asm-generic/vmlinux.lds.h
index 339125b..0aae448 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -536,6 +536,7 @@
IRQCHIP_OF_MATCH_TABLE()\
ACPI_PROBE_TABLE(irqchip)   \
ACPI_PROBE_TABLE(clksrc)\
+   ACPI_PROBE_TABLE(iort)  \
EARLYCON_TABLE()
 
 #define INIT_TEXT  \
diff --git a/include/linux/iort.h b/include/linux/iort.h
index 148d9a1..766adda 100644
--- a/include/linux/iort.h
+++ b/include/linux/iort.h
@@ -31,4 +31,7 @@ struct fwnode_handle *iort_pci_get_domain(struct pci_dev 
*pdev, u32 req_id);
 int iort_iommu_set_node(struct iommu_ops *ops, struct acpi_iort_node *node,
struct fwnode_handle *fwnode);
 
+#define IORT_ACPI_DECLARE(name, table_id, fn)  \
+   ACPI_DECLARE_PROBE_ENTRY(iort, name, table_id, 0, NULL, 0, fn)
+
 #endif /* __IORT_H__ */
-- 
2.6.4



[RFC PATCH 02/11] drivers: acpi: iort: add support for IOMMU registration

2016-04-14 Thread Lorenzo Pieralisi
The ACPI IORT table provide entries for IOMMU (aka SMMU in ARM world)
components that allow creating the kernel data structures required to
probe and initialize the IOMMU devices.

This patch provides support in the IORT kernel code to register IOMMU
components.

Signed-off-by: Lorenzo Pieralisi <lorenzo.pieral...@arm.com>
Cc: Hanjun Guo <hanjun@linaro.org>
Cc: Tomasz Nowicki <t...@semihalf.com>
Cc: Joerg Roedel <j...@8bytes.org>
Cc: "Rafael J. Wysocki" <r...@rjwysocki.net>
---
 drivers/acpi/iort.c  | 42 ++
 include/linux/iort.h |  2 ++
 2 files changed, 44 insertions(+)

diff --git a/drivers/acpi/iort.c b/drivers/acpi/iort.c
index 3119683..98db580 100644
--- a/drivers/acpi/iort.c
+++ b/drivers/acpi/iort.c
@@ -19,10 +19,13 @@
 #define pr_fmt(fmt)"ACPI: IORT: " fmt
 
 #include 
+#include 
 #include 
 #include 
 #include 
+#include 
 #include 
+#include 
 
 struct iort_its_msi_chip {
struct list_headlist;
@@ -30,6 +33,45 @@ struct iort_its_msi_chip {
u32 translation_id;
 };
 
+struct iort_iommu_node {
+   struct list_head list;
+   struct iommu_ops *ops;
+   struct acpi_iort_node *node;
+   struct fwnode_handle*fwnode;
+};
+static LIST_HEAD(iort_iommu_list);
+static DEFINE_SPINLOCK(iort_iommu_lock);
+
+/**
+ * iort_iommu_set_node - Create iort_mmu_node and use it to register
+ *  iommu structures on iort_iommu_list.
+ *
+ * @ops: IOMMU operations
+ * @node: IORT table node associated with the IOMMU
+ * @fwnode: fwnode_handle associated with the IOMMU
+ *
+ * Returns: 0 on success
+ *  -ENOMEM on failure
+ */
+int iort_iommu_set_node(struct iommu_ops *ops, struct acpi_iort_node *node,
+   struct fwnode_handle *fwnode)
+{
+   struct iort_iommu_node *iommu = kzalloc(sizeof(*iommu), GFP_KERNEL);
+
+   if (WARN_ON(!iommu))
+   return -ENOMEM;
+
+   INIT_LIST_HEAD(>list);
+   iommu->ops = ops;
+   iommu->node = node;
+   iommu->fwnode = fwnode;
+   spin_lock(_iommu_lock);
+   list_add_tail(>list, _iommu_list);
+   spin_unlock(_iommu_lock);
+
+   return 0;
+}
+
 typedef acpi_status (*iort_find_node_callback)
(struct acpi_iort_node *node, void *context);
 
diff --git a/include/linux/iort.h b/include/linux/iort.h
index b15fe1a..148d9a1 100644
--- a/include/linux/iort.h
+++ b/include/linux/iort.h
@@ -28,5 +28,7 @@ void iort_deregister_domain_token(int trans_id);
 struct fwnode_handle *iort_its_find_domain_token(int trans_id);
 u32 iort_pci_get_msi_rid(struct pci_dev *pdev, u32 req_id);
 struct fwnode_handle *iort_pci_get_domain(struct pci_dev *pdev, u32 req_id);
+int iort_iommu_set_node(struct iommu_ops *ops, struct acpi_iort_node *node,
+   struct fwnode_handle *fwnode);
 
 #endif /* __IORT_H__ */
-- 
2.6.4



[RFC PATCH 00/11] ACPI IORT ARM SMMU support

2016-04-14 Thread Lorenzo Pieralisi
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, available through this posting:

https://marc.info/?l=linux-acpi=145976009630179=2

this patchset enables ARM SMMU 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 ARM SMMUv3 and future IOMMU components easier to integrate.

PATCH [1] fixes a warning caused by a missing forward structure
  declaration.

PATCH [2] provides IORT support for registering IOMMU components.

PATCH [3] adds a FWNODE_IOMMU type to the struct fwnode_handle type.
  It is required to attach a fwnode identifier to platform
  devices allocated/detected through IORT tables entries;
  IOMMU devices have to have an identifier to look them up
  eg IOMMU core layer carrying out id translation. This can be
  done through a fwnode_handle (ie IOMMU platform devices created
  out of IORT tables are not ACPI devices hence they can't be
  allocated as such, otherwise they would have a fwnode_handle of
  type FWNODE_ACPI). This patch requires discussion and it is key
  to the RFC.

PATCH [4] makes use of the ACPI early probing API to add a linker script
  section for probing devices via IORT ACPI kernel code.

PATCH [5] refactors the ARM SMMU driver so that the init functions are
  split in a way that groups together code that probes through DT
  and code that carries out HW registers FW agnostic probing, in
  preparation for adding the ACPI probing path.

PATCH [6] makes the of_xlate() interface for IOMMUs DT agnostic by
  changing its API and making it work on ACPI systems too
  through the introduction of a generic IOMMU FW translation
  specifier.

PATCH [7] implements ARM SMMU streamid mapping based on the previously
  introduced infrastructure.

PATCH [8] enhances IORT kernel code to implement the full set of mappings
  allowed through the ACPI IORT table.

PATCH [9] implements the of_dma_configure() API in ACPI world -
  acpi_dma_configure() - and patches PCI and ACPI core code to start
  making use of it.

PATCH [10] implements and enables code for probing the ARM SMMU with ACPI,
   building on top of the previously introduced generic infrastructure.

PATCH [11] is a mechanical conversion of IRQ domain infrastructure to
   generalize its translation capabilities for other kernel
   subsystems, and it is there to prove that the approach taken
   to implement IOMMU translation in a DT agnostic way would lead
   to structure data duplication that may be deemed unnecessary
   and can therefore be avoided.

This patchset is built on top and depends on these two patch series:

R.Murphy "Generic DT bindings for PCI and ARM SMMU"
https://marc.info/?l=linux-arm-kernel=145675372917701=2

T.Nowicki "Introduce ACPI world to ITS irqchip"
https://marc.info/?l=linux-acpi=145976009630179=2

Tested on Juno-r2 board with both DT and ACPI probing paths.

Lorenzo Pieralisi (11):
  drivers: acpi: iort: fix struct pci_dev compiler warnings
  drivers: acpi: iort: add support for IOMMU registration
  drivers: iommu: add FWNODE_IOMMU fwnode type
  drivers: acpi: iort: introduce linker section for IORT entries probing
  drivers: iommu: arm-smmu: split probe functions into DT/generic
portions
  drivers: iommu: make of_xlate() interface DT agnostic
  drivers: iommu: arm-smmu: allow ACPI based streamid translation
  drivers: acpi: iort: enhance mapping API
  drivers: acpi: implement acpi_dma_configure
  drivers: iommu: arm-smmu: implement ACPI probing
  drivers: irqchip: make struct irq_fwspec generic

 Documentation/IRQ-domain.txt |   2 +-
 arch/arm/mach-exynos/suspend.c   |   6 +-
 arch/arm/mach-imx/gpc.c  |   6 +-
 arch/arm/mach-omap2/omap-wakeupgen.c |   6 +-
 drivers/acpi/glue.c  |   4 +-
 drivers/acpi/gsi.c   |   2 +-
 drivers/acpi/iort.c  | 188 ++-
 drivers/acpi/scan.c  |  29 +++
 drivers/gpio/gpio-xgene-sb.c |   8 +-
 drivers/iommu/arm-smmu.c | 346 ++-
 drivers/iommu/exynos-iommu.c |  11 +-
 drivers/iommu/mtk_iommu.c|  13 +-
 drivers/iommu/of_iommu.c |   8 +-
 drivers/irqchip/irq-alpine-msi.c |   2 +-
 drivers/irqchip/irq-crossbar.c   |   6 +-
 drivers/irqchip/irq-gic-v2m.c|   2 +-
 drivers/irqchip/irq-gic-v3-its.c |   2 +-
 dri

[RFC PATCH 09/11] drivers: acpi: implement acpi_dma_configure

2016-04-14 Thread Lorenzo Pieralisi
On DT based systems, the of_dma_configure() API implements DMA configuration
for a given device. On ACPI systems an API equivalent to of_dma_configure()
is missing which implies that it is currently not possible to set-up DMA
operations for devices through the ACPI generic kernel layer.

This patch fills the gap by introducing acpi_dma_configure/deconfigure()
calls, that carry out IOMMU configuration through IORT (on systems where
it is present) and call arch_setup_dma_ops(...) with the retrieved
parameters.

The DMA range size passed to arch_setup_dma_ops() is sized according
to the device coherent_dma_mask (starting at address 0x0), mirroring the
DT probing path behaviour when a dma-ranges property is not provided
for the device being probed; this changes the current arch_setup_dma_ops()
call parameters in the ACPI probing case, but since arch_setup_dma_ops()
is a NOP on all architectures but ARM/ARM64 this patch does not change
the current kernel behaviour on them.

This patch updates ACPI and PCI core code to use the newly introduced
acpi_dma_configure function, providing the same functionality
as of_dma_configure on ARM systems and leaving behaviour unchanged
for all other arches.

Signed-off-by: Lorenzo Pieralisi <lorenzo.pieral...@arm.com>
Cc: Bjorn Helgaas <bhelg...@google.com>
Cc: Robin Murphy <robin.mur...@arm.com>
Cc: Tomasz Nowicki <t...@semihalf.com>
Cc: Joerg Roedel <j...@8bytes.org>
Cc: "Rafael J. Wysocki" <r...@rjwysocki.net>
---
 drivers/acpi/glue.c |  4 +--
 drivers/acpi/iort.c | 85 +
 drivers/acpi/scan.c | 29 +
 drivers/pci/probe.c |  3 +-
 include/acpi/acpi_bus.h |  2 ++
 include/linux/acpi.h|  5 +++
 include/linux/iort.h|  9 ++
 7 files changed, 133 insertions(+), 4 deletions(-)

diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index 5ea5dc2..f8d6564 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -227,8 +227,7 @@ int acpi_bind_one(struct device *dev, struct acpi_device 
*acpi_dev)
 
attr = acpi_get_dma_attr(acpi_dev);
if (attr != DEV_DMA_NOT_SUPPORTED)
-   arch_setup_dma_ops(dev, 0, 0, NULL,
-  attr == DEV_DMA_COHERENT);
+   acpi_dma_configure(dev, attr);
 
acpi_physnode_link_name(physical_node_name, node_id);
retval = sysfs_create_link(_dev->dev.kobj, >kobj,
@@ -251,6 +250,7 @@ int acpi_bind_one(struct device *dev, struct acpi_device 
*acpi_dev)
return 0;
 
  err:
+   acpi_dma_deconfigure(dev);
ACPI_COMPANION_SET(dev, NULL);
put_device(dev);
put_device(_dev->dev);
diff --git a/drivers/acpi/iort.c b/drivers/acpi/iort.c
index 2b5ce65..b1bb8fb 100644
--- a/drivers/acpi/iort.c
+++ b/drivers/acpi/iort.c
@@ -72,6 +72,31 @@ int iort_iommu_set_node(struct iommu_ops *ops, struct 
acpi_iort_node *node,
return 0;
 }
 
+/**
+ * iort_iommu_get_node - Retrieve iort_iommu_node associated with an IORT node.
+ *
+ * @node: IORT table node to be looked-up
+ *
+ * Returns: iort_iommu_node pointer on success
+ *  NULL on failure
+ */
+static struct iort_iommu_node *iort_iommu_get_node(struct acpi_iort_node *node)
+{
+   struct iort_iommu_node *iommu_node;
+
+   spin_lock(_iommu_lock);
+   list_for_each_entry(iommu_node, _iommu_list, list) {
+   if (iommu_node->node == node)
+   goto found;
+   }
+
+   iommu_node = NULL;
+found:
+   spin_unlock(_iommu_lock);
+
+   return iommu_node;
+}
+
 typedef acpi_status (*iort_find_node_callback)
(struct acpi_iort_node *node, void *context);
 
@@ -405,6 +430,66 @@ iort_pci_get_domain(struct pci_dev *pdev, u32 req_id)
return domain_handle;
 }
 
+static int __get_pci_rid(struct pci_dev *pdev, u16 alias, void *data)
+{
+   u32 *rid = data;
+
+   *rid = alias;
+   return 0;
+}
+
+/**
+ * iort_iommu_configure - Set-up IOMMU configuration for a device.
+ *
+ * @dev: device that requires IOMMU set-up
+ *
+ * Returns: iommu_ops pointer on configuration success
+ *  NULL on configuration failure
+ */
+struct iommu_ops *iort_iommu_configure(struct device *dev)
+{
+   struct acpi_iort_node *node, *parent;
+   struct iommu_ops *ops = NULL;
+   struct iommu_fwspec fwspec;
+   struct iort_iommu_node *iommu_node;
+   u32 rid = 0, devid = 0;
+
+   if (dev_is_pci(dev)) {
+   struct pci_bus *bus = to_pci_dev(dev)->bus;
+
+   pci_for_each_dma_alias(to_pci_dev(dev), __get_pci_rid,
+  );
+
+   node = iort_scan_node(ACPI_IORT_NODE_PCI_ROOT_COMPLEX,
+ iort_find_dev_callback, >dev);
+   } else
+   node = iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT,
+ iort_find_dev_callback, dev);
+
+   if (!node)
+

[RFC PATCH 07/11] drivers: iommu: arm-smmu: allow ACPI based streamid translation

2016-04-14 Thread Lorenzo Pieralisi
The ACPI IORT table provides data to ARM IOMMU drivers to carry out
streamid mappings and the kernel has the infrastructure to implement
it through the fw_xlate() struct iommu_ops hook.

By relying on the DT agnostic struct iommu_fwspec fields, this
patch adds code in the ARM SMMU fw_xlate() callback that allows
streamid translation on ACPI based ARM system.

Signed-off-by: Lorenzo Pieralisi <lorenzo.pieral...@arm.com>
Cc: Will Deacon <will.dea...@arm.com>
Cc: Robin Murphy <robin.mur...@arm.com>
---
 drivers/iommu/arm-smmu.c | 16 
 1 file changed, 16 insertions(+)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 84bcff7..0f1e784 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -1440,6 +1440,20 @@ out_unlock:
return ret;
 }
 
+static int arm_smmu_dev_node_match(struct device *dev, void *data)
+{
+   return is_fwnode_iommu(dev->fwnode) && dev->fwnode == data;
+}
+
+static struct platform_device *arm_smmu_get_dev(struct fwnode_handle *fwnode)
+{
+   struct device *dev;
+
+   dev = bus_find_device(_bus_type, NULL, fwnode,
+ arm_smmu_dev_node_match);
+   return dev ? to_platform_device(dev) : NULL;
+}
+
 static int arm_smmu_fw_xlate(struct device *dev, struct iommu_fwspec *args)
 {
struct arm_smmu_device *smmu;
@@ -1447,6 +1461,8 @@ static int arm_smmu_fw_xlate(struct device *dev, struct 
iommu_fwspec *args)
 
if (is_of_node(args->fwnode))
smmu_pdev = of_find_device_by_node(to_of_node(args->fwnode));
+   else if (is_fwnode_iommu(args->fwnode))
+   smmu_pdev = arm_smmu_get_dev(args->fwnode);
 
if (!smmu_pdev)
return -ENODEV;
-- 
2.6.4



Re: [PATCH v3] ARM64: ACPI: Update documentation for latest specification version

2016-04-18 Thread Lorenzo Pieralisi
On Fri, Apr 15, 2016 at 11:54:08AM -0600, Al Stone wrote:

[...]

> > Understood, the point I wanted to make is that adding a list of methods
> > in acpi_object_usage.txt ("Use as needed") is not necessarily additional
> > information, you can add a pointer at ACPI specs (for that specific
> > purpose - as I said there are parts of the patch that add additional
> > information Linux related) for that purpose instead of having to list
> > all of them in acpi_object_usage.txt again.
> 
> I see.  That makes sense.  How about I collapse those down with something
> on the order of "unless otherwise noted, use as needed" and just remove the
> ones that have no specific info?

Agreed, that would also help you avoid keeping track of new specs
updates that do not necessarily require updates to these docs.

Lorenzo


Re: [PATCH V6 05/13] acpi, pci: Support IO resources when parsing PCI host bridge resources.

2016-04-27 Thread Lorenzo Pieralisi
On Tue, Apr 26, 2016 at 09:39:16PM -0500, Bjorn Helgaas wrote:
> On Fri, Apr 15, 2016 at 07:06:40PM +0200, Tomasz Nowicki wrote:
> > Platforms that have memory mapped IO port (such as ARM64) need special
> > handling for PCI I/O resources. For host bridge's resource probing case
> > these resources need to be fixed up with 
> > pci_register_io_range/pci_remap_iospace etc.
> 
> ia64 also has memory-mapped I/O port space.  It would be ideal to find
> some way to handle ia64 and ARM64 similarly.  At the very least, we
> have to make sure that this doesn't break ia64.  The ia64 dense/sparse
> I/O spaces complicate things; I don't know if ARM64 has something
> similar or not.

No it does not, and that's exactly the same problem we faced with
the DT generic version of of_pci_range_to_resource() which basically
relies on PCI_IOBASE to be defined to add code that creates IO port
resources out of the MMIO resource describing how IO port space is
mapped to MMIO (physical) address space.

IIRC everything hinges on PCI_IOBASE definition to make sure that
of_pci_range_to_resource() *works*, which means that if PCI_IOBASE is
not defined (ie IA64) that code - acpi_pci_root_remap_iospace() in this
case - does nothing.

So acpi_pci_root_remap_iospace() is of_pci_range_to_resource() ACPI
equivalent + the pci_remap_iospace() call (I have to dig into the
logs to check why Liviu did not add a call to pci_remap_iospace()
in of_pci_get_host_bridge_resources() - I want to do that actually).

The point here is: IO space (in DT and ACPI) handling is arch specific.

For DT, by relying on PCI_IOBASE, we left that code in drivers/of and
it works (well, with some niggles - see the thread with Murali on IO
space on TI keystone) for ARM/ARM64.

http://www.spinics.net/lists/linux-pci/msg49725.html

What are we going to do with the ACPI version ?

Do we want to add an arch specific call that takes the raw resource
describing IO space and creates an IO port resource (and the MMIO
equivalent - that's what add_io_space() does in IA64) and use that
in generic ACPI parsing code ?

Or we just do what Tomasz does, which is basically the approach we took
for DT ?

> > Furthermore, the same I/O resources need to be released after hotplug
> > removal so that it can be re-added back by the pci_remap_iospace
> > function during insertion. Therefore we implement new pci_unmap_iospace call
> > which unmaps I/O space as the symmetry to pci_remap_iospace.
> 
> "Furthermore" is a hint that we should check to see if this can be
> split into two patches.
> 
> We already have a pci_remap_iospace(), and you're adding
> pci_unmap_iospace(), which will be used for hotplug removal.  So let's 
> add pci_unmap_iospace() first in a patch by itself because that's
> potentially useful for other callers of pci_remap_iospace(), even if
> they don't need the acpi_pci_root_remap_iospace() stuff.

I agree.

Thanks,
Lorenzo

> > Signed-off-by: Jayachandran C 
> > Signed-off-by: Sinan Kaya 
> > Signed-off-by: Tomasz Nowicki 
> > ---
> >  drivers/acpi/pci_root.c | 33 +
> >  drivers/pci/pci.c   | 24 
> >  include/linux/pci.h |  1 +
> >  3 files changed, 58 insertions(+)
> > 
> > diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
> > index d9a70c4..815b6ca 100644
> > --- a/drivers/acpi/pci_root.c
> > +++ b/drivers/acpi/pci_root.c
> > @@ -742,6 +742,34 @@ next:
> > resource_list_add_tail(entry, resources);
> > }
> >  }
> > +static void acpi_pci_root_remap_iospace(struct resource_entry *entry)
> > +{
> > +#ifdef PCI_IOBASE
> > +   struct resource *res = entry->res;
> > +   resource_size_t cpu_addr = res->start;
> > +   resource_size_t pci_addr = cpu_addr - entry->offset;
> > +   resource_size_t length = resource_size(res);
> > +   unsigned long port;
> > +
> > +   if (pci_register_io_range(cpu_addr, length))
> > +   goto err;
> > +
> > +   port = pci_address_to_pio(cpu_addr);
> > +   if (port == (unsigned long)-1)
> > +   goto err;
> > +
> > +   res->start = port;
> > +   res->end = port + length - 1;
> > +   entry->offset = port - pci_addr;
> > +
> > +   if (pci_remap_iospace(res, cpu_addr) < 0)
> > +   goto err;
> > +   pr_info("Remapped I/O %pa to %pR\n", _addr, res);
> > +   return;
> > +err:
> > +   res->flags |= IORESOURCE_DISABLED;
> > +#endif
> > +}
> >  
> >  int acpi_pci_probe_root_resources(struct acpi_pci_root_info *info)
> >  {
> > @@ -763,6 +791,9 @@ int acpi_pci_probe_root_resources(struct 
> > acpi_pci_root_info *info)
> > "no IO and memory resources present in _CRS\n");
> > else {
> > resource_list_for_each_entry_safe(entry, tmp, list) {
> > +   if (entry->res->flags & IORESOURCE_IO)
> > +   acpi_pci_root_remap_iospace(entry);
> > +
> > if (entry->res->flags & IORESOURCE_DISABLED)
> 

Re: Why does BIOS assign memory to 16 byte BAR

2016-07-27 Thread Lorenzo Pieralisi
On Wed, Jul 27, 2016 at 06:33:29AM +, Bharat Kumar Gogada wrote:
> > Your system host bridge: has resource
> > pci_bus :00: root bus resource [mem 0xe010-0xefff] pci_bus
> > :00: root bus resource [mem 0x6-0x7 pref] then one pci
> > bridge:
> > pci :00:00.0
> > then :01:00.0 have four bars:
> > pci :01:00.0: BAR 0:  [mem size 0x4000] pci :01:00.0: BAR 4:
> > [mem size 0x0010 64bit] pci :01:00.0: BAR 2:  [mem size 0x0010]
> > pci :01:00.0: BAR 3:  [mem size 0x0010]
> > 
> > 
> > kernel need to get allocation for pci :00:00.0 at first
> > 
> > but can not find big enough space.
> > 
> > pci :00:00.0: BAR 8: no space for [mem size 0x6000] as it should
> > come from [mem 0xe010-0xefff], and that is less 1.5G.
> > 
> > so all children resource from pci :01:00.0 all fail.
> > 
> > 
> > please check if you modify your FPGA code to make pci :01:00.0
> > 
> > BAR 0, and BAR 4 to use 64bit pref instead non-pref mmio.
> > 
> > or you can check if can increase root bus mmio range
> > 
> >  MEM 0xe010..0xefff -> 0xe010 nwl-pcie fd0e.pcie: PCI host
> > bridge to bus :00
> > 
> > to have more than 1.5G.
> > 
> Thanks Yinghai Lu.
> We see that similar test is passing in x86 machine, where function one
> requesting 1GB BAR's is failing, but function two requesting BAR's
> with 16byte is getting assigned BAR's.
> 
> To my knowledge on x86 BIOS assigns resources, or will kernel assign
> reosurces on x86 ?  If kernel does is there any difference between x86
> and arm64 resource assignment logic ?

We can't answer your question if you do not provide a full log
of x86 and ARM PCI configurations you are testing I am afraid.

It is also unclear to me what "a similar test is passing in x86
machine" means, in particular in relation to the HW configuration
you are testing on x86.

Yes, there are differences between x86 and ARM resources assignments,
x86 tries to claim PCI resources as set-up by BIOS and assign them
iff the claiming fails whereas on ARM (and that's done in the host
bridge driver) FW configuration is always discarded and the kernel
reassigns the whole PCI resource hierarchy entirely, but to help we
need more data as I said above.

I suspect the issue you are facing has to do as Yinghai mentioned
with the prefetchable memory window set-up, saying that "it works"
on x86 does not really help unless you provide data to debug it.

Thanks,
Lorenzo


Re: Purpose of pci_remap_iospace

2016-07-13 Thread Lorenzo Pieralisi
On Wed, Jul 13, 2016 at 03:16:21PM +, Bharat Kumar Gogada wrote:
> > Subject: Re: Purpose of pci_remap_iospace
> >
> > On Wednesday, July 13, 2016 12:30:44 PM CEST Bharat Kumar Gogada wrote:
> > >  > On Wednesday, July 13, 2016 8:11:56 AM CEST Bharat Kumar Gogada
> > wrote:
> > > > > > Subject: Re: Purpose of pci_remap_iospace
> > > >
> > > > I notice you have 1MB of I/O space here
> > > >
> > > > > Kernel Boot log:
> > > > > [2.345294] nwl-pcie fd0e.pcie: Link is UP
> > > > > [2.345339] PCI host bridge /amba/pcie@fd0e ranges:
> > > > > [2.345356]   No bus range found for /amba/pcie@fd0e, using
> > [bus
> > > > 00-ff]
> > > > > [2.345382]IO 0xe000..0xe00f -> 0x
> > > > > [2.345401]   MEM 0xe010..0xeeff -> 0xe010
> > > > > [2.345498] nwl-pcie fd0e.pcie: PCI host bridge to bus :00
> > > > > [2.345517] pci_bus :00: root bus resource [bus 00-ff]
> > > > > [2.345533] pci_bus :00: root bus resource [io  0x-0xf]
> > > >
> > > > and all of it gets mapped by the PCI core. Usually you only have 64K
> > > > of I/O space per host bridge, and the PCI core should perhaps not
> > > > try to map all of it, though I don't think this is actually your 
> > > > problem here.
> > > >
> > > > > [2.345550] pci_bus :00: root bus resource [mem 0xe010-
> > > > 0xeeff]
> > > > > [2.345770] pci :00:00.0: cannot attach to SMMU, is it on the 
> > > > > same
> > > > bus?
> > > > > [2.345786] iommu: Adding device :00:00.0 to group 1
> > > > > [2.346142] pci :01:00.0: cannot attach to SMMU, is it on the 
> > > > > same
> > > > bus?
> > > > > [2.346158] iommu: Adding device :01:00.0 to group 1
> > > > > [2.346213] pci :00:00.0: BAR 8: assigned [mem 0xe010-
> > > > 0xe02f]
> > > > > [2.346234] pci :01:00.0: BAR 0: assigned [mem 0xe010-
> > 0xe01f
> > > > 64bit]
> > > > > [2.346268] pci :01:00.0: BAR 2: assigned [mem 0xe020-
> > 0xe02f
> > > > 64bit]
> > > > > [2.346300] pci :01:00.0: BAR 4: no space for [io  size 0x0040]
> > > > > [2.346316] pci :01:00.0: BAR 4: failed to assign [io  size 
> > > > > 0x0040]
> > > > > [2.346333] pci :00:00.0: PCI bridge to [bus 01-0c]
> > > > > [2.346350] pci :00:00.0:   bridge window [mem 0xe010-
> > > > 0xe02f]
> > > > >
> > > > > IO assignment fails.
> > > >
> > > > I would guess that the I/O space is not registered correctly. Is
> > > > this drivers/pci/host/pcie-xilinx.c ? We have had problems with this
> > > > in the past, since almost nobody uses I/O space and it requires
> > > > several steps to all be done correctly.
> > > >
> > > Thanks Arnd.
> > >
> > > we are testing using drivers/pci/host/pcie-xilinx-nwl.c.
> >
> > According to Documentation/devicetree/bindings/pci/xilinx-nwl-pcie.txt,
> > this hardware does not support I/O space.
> 
> We received a newer IP version with IO support, so we are trying to test this 
> feature.
> >
> > Is this on ARM or microblaze?
> 
> It is ARM 64-bit.
> 
> > This has neither the PCI memory nor the I/O resource, it looks like you 
> > never
> > call pci_add_resource_offset() to start with, or maybe it fails for some
> > reason.
> 
> I see that above API is used in ARM drivers, do we need to do it in
> ARM64 also ?

It is called in of_pci_get_host_bridge_resources(), since you
are using that API there is nothing more you have to do. The problem
with resources in /proc/iomem and /proc/ioports is that you
do not request the host bridge apertures in your host controller
driver, see drivers/pci/host/pci-host-common.c (devm_request_resource())
to see how to do it.

And as I said previously in this thread none of this is related to
your IO BAR assignment failures IMHO.

Lorenzo


Re: Purpose of pci_remap_iospace

2016-07-14 Thread Lorenzo Pieralisi
On Thu, Jul 14, 2016 at 01:32:13PM +, Bharat Kumar Gogada wrote:

[...]

> Hi Lorenzo,
> 
> I missed something in my device tree now I corrected it.
> 
> ranges = <0x0100 0x 0xe000 0x 0xe000 0 0x0001 
>   //io

You have not missed anything, you changed the PCI bus address at
which your host bridge responds to IO space and it must match
your configuration. At what PCI bus address your host bridge
maps IO space ?

>  0x0200 0x 0xe010 0x 0xe010 0 
> 0x0ef0>; //non prefetchabe memory
> 
> [2.389498] nwl-pcie fd0e.pcie: Link is UP
> [2.389541] PCI host bridge /amba/pcie@fd0e ranges:
> [2.389558]   No bus range found for /amba/pcie@fd0e, using [bus 00-ff]
> [2.389583]IO 0xe000..0xe000 -> 0xe000
> [2.389624]   MEM 0xe010..0xeeff -> 0xe010
> [2.389803] nwl-pcie fd0e.pcie: PCI host bridge to bus :00
> [2.389822] pci_bus :00: root bus resource [bus 00-ff]
> [2.389839] pci_bus :00: root bus resource [io  0x-0x] (bus 
> address [0xe000-0xe000])
> [2.389863] pci_bus :00: root bus resource [mem 0xe010-0xeeff]
> [2.390094] pci :00:00.0: cannot attach to SMMU, is it on the same bus?
> [2.390110] iommu: Adding device :00:00.0 to group 1
> [2.390274] pci :01:00.0: reg 0x20: initial BAR value 0x 
> invalid
> [2.390481] pci :01:00.0: cannot attach to SMMU, is it on the same bus?
> [2.390496] iommu: Adding device :01:00.0 to group 1
> [2.390533] in pci_bridge_check_ranges io 101
> [2.390545] in pci_bridge_check_ranges io 2 101
> [2.390575] pci :00:00.0: BAR 8: assigned [mem 0xe010-0xe02f]
> [2.390592] pci :00:00.0: BAR 7: assigned [io  0x1000-0x1fff]
> [2.390609] pci :00:00.0: BAR 6: assigned [mem 0xe030-0xe03007ff 
> pref]
> [2.390636] pci :01:00.0: BAR 0: assigned [mem 0xe010-0xe01f 
> 64bit]
> [2.390669] pci :01:00.0: BAR 2: assigned [mem 0xe020-0xe02f 
> 64bit]
> [2.390702] pci :01:00.0: BAR 4: assigned [io  0x1000-0x103f]
> [2.390721] pci :00:00.0: PCI bridge to [bus 01-0c]
> [2.390785] pci :00:00.0:   bridge window [io  0x1000-0x1fff]
> [2.390823] pci :00:00.0:   bridge window [mem 0xe010-0xe02f]
> 
> Lspci on bridge:
> 00:00.0 PCI bridge: Xilinx Corporation Device a024 (prog-if 00 [Normal 
> decode])
> Control: I/O- Mem- BusMaster- SpecCycle- MemWINV- VGASnoop- ParErr- 
> Stepping- SERR- FastB2B- DisINTx-
> Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- 
> SERR-  Interrupt: pin A routed to IRQ 224
> Bus: primary=00, secondary=01, subordinate=0c, sec-latency=0
> I/O behind bridge: e0001000-e0001fff
> Memory behind bridge: e010-e02f
> 
> Here my IO space is showing 4k, but what I'm providing is 4k ?(In above boot 
> log also IO space length 4k)
> 
> Lspci on EP:
> 01:00.0 Memory controller: Xilinx Corporation Device d024
> Subsystem: Xilinx Corporation Device 0007
> Control: I/O- Mem- BusMaster- SpecCycle- MemWINV- VGASnoop- ParErr- 
> Stepping- SERR- FastB2B- DisINTx-
> Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- 
> SERR-  Interrupt: pin A routed to IRQ 224
> Region 0: Memory at e010 (64-bit, non-prefetchable) [disabled] 
> [size=1M]
> Region 2: Memory at e020 (64-bit, non-prefetchable) [disabled] 
> [size=1M]
> Region 4: I/O ports at 1000 [disabled] [size=64]
> 
> On EP from where it is getting this 1000 address, it should be within
> I/O behind bridge range know ?


The CPU physical address in the DT range for PCI IO range is the
address at which your host bridge responds to PCI IO space cycle
(through memory mapped accesses, to emulate x86 IO port behaviour).

The PCI bus address in the range is the address your
host bridge will convert the incoming physical CPU address
and drive the PCI bus transactions.

Is your host bridge programmed with its address decoder
set-up according to what I say above (and your DT bindings) ?

If yes, on to the virtual address space.

On ARM, for IO space, we map the cpu physical address I
mention above to a chunk of virtual address space allocated
for PCI IO space, that's what pci_remap_iospace() is meant
for.

That physical address is mapped to a fixed virtual address range
(starting with PCI_IOBASE).

The value you see in the IO bar above is an offset into that chunk
of virtual addresses so that, when you do eg inb(offset) in a driver
the code behind it translates that access to a memory mapped access into
the virtual address space allocated to PCI IO space (that you
previously mapped through pci_remap_iospace()).

The offset allocated starts from 0x1000, since that's the
value of PCIBIOS_MIN_IO, that the code assigning resources
use to preserve the range 

Re: Purpose of pci_remap_iospace

2016-07-14 Thread Lorenzo Pieralisi
On Thu, Jul 14, 2016 at 03:05:40PM +, Bharat Kumar Gogada wrote:

[...]

> > On Thu, Jul 14, 2016 at 01:32:13PM +, Bharat Kumar Gogada wrote:
> > > ranges = <0x0100 0x 0xe000 0x 0xe000 0
> > 0x0001   //io
> >
> > You have not missed anything, you changed the PCI bus address at which
> > your host bridge responds to IO space and it must match your configuration.
> > At what PCI bus address your host bridge maps IO space ?
> >
> > >  0x0200 0x 0xe010 0x
> > > 0xe010 0 0x0ef0>; //non prefetchabe memory
> > >
> > > [2.389498] nwl-pcie fd0e.pcie: Link is UP
> > > [2.389541] PCI host bridge /amba/pcie@fd0e ranges:
> > > [2.389558]   No bus range found for /amba/pcie@fd0e, using [bus
> > 00-ff]
> > > [2.389583]IO 0xe000..0xe000 -> 0xe000
> > > [2.389624]   MEM 0xe010..0xeeff -> 0xe010
> > > [2.389803] nwl-pcie fd0e.pcie: PCI host bridge to bus :00
> > > [2.389822] pci_bus :00: root bus resource [bus 00-ff]
> > > [2.389839] pci_bus :00: root bus resource [io  0x-0x] (bus
> > address [0xe000-0xe000])
> > > [2.389863] pci_bus :00: root bus resource [mem 0xe010-
> > 0xeeff]
> > > [2.390094] pci :00:00.0: cannot attach to SMMU, is it on the same
> > bus?
> > > [2.390110] iommu: Adding device :00:00.0 to group 1
> > > [2.390274] pci :01:00.0: reg 0x20: initial BAR value 0x 
> > > invalid
> > > [2.390481] pci :01:00.0: cannot attach to SMMU, is it on the same
> > bus?
> > > [2.390496] iommu: Adding device :01:00.0 to group 1
> > > [2.390533] in pci_bridge_check_ranges io 101
> > > [2.390545] in pci_bridge_check_ranges io 2 101
> > > [2.390575] pci :00:00.0: BAR 8: assigned [mem 0xe010-
> > 0xe02f]
> > > [2.390592] pci :00:00.0: BAR 7: assigned [io  0x1000-0x1fff]
> > > [2.390609] pci :00:00.0: BAR 6: assigned [mem 0xe030-
> > 0xe03007ff pref]
> > > [2.390636] pci :01:00.0: BAR 0: assigned [mem 
> > > 0xe010-0xe01f
> > 64bit]
> > > [2.390669] pci :01:00.0: BAR 2: assigned [mem 
> > > 0xe020-0xe02f
> > 64bit]
> > > [2.390702] pci :01:00.0: BAR 4: assigned [io  0x1000-0x103f]
> > > [2.390721] pci :00:00.0: PCI bridge to [bus 01-0c]
> > > [2.390785] pci :00:00.0:   bridge window [io  0x1000-0x1fff]
> > > [2.390823] pci :00:00.0:   bridge window [mem 0xe010-
> > 0xe02f]
> > >
> Thanks a lot Loenzo for your kind and clear explanation, I will dig
> through hardware and correct my device tree.
> 
> From above log why IO space is allocated as only 4k even though I'm
> allocating 64k through device tree ?

You are not allocating anything in the device tree, you are just
defining the physical memory window at which your PCI host bridge
address decoders "map" PCI IO cycles.

PCI core code, while assigning resources, sizes the PCI bridge
IO window BAR by sizing the downstream PCI devices BARs:

See:

pbus_size_io()

PCI core won't allocate an IO window to your PCI bridge window BARs
bigger than what's necessary (according to downstream devices), keeping
alignment in mind.

Is that clear ?

> This email and any attachments are intended for the sole use of the named 
> recipient(s) and contain(s) confidential information that may be proprietary, 
> privileged or copyrighted under applicable law. If you are not the intended 
> recipient, do not read, copy, or forward this email message or any 
> attachments. Delete this email message and any attachments immediately.

This disclaimer should disappear if you want to discuss patches on
public mailing lists.

Thanks,
Lorenzo


Re: Purpose of pci_remap_iospace

2016-07-14 Thread Lorenzo Pieralisi
On Thu, Jul 14, 2016 at 05:12:01PM +0200, Arnd Bergmann wrote:
> On Thursday, July 14, 2016 3:56:24 PM CEST Lorenzo Pieralisi wrote:
> > On Thu, Jul 14, 2016 at 01:32:13PM +, Bharat Kumar Gogada wrote:
> > 
> > [...]
> > 
> > > Hi Lorenzo,
> > > 
> > > I missed something in my device tree now I corrected it.
> > > 
> > > ranges = <0x0100 0x 0xe000 0x 0xe000 0 
> > > 0x0001   //io
> > 
> > You have not missed anything, you changed the PCI bus address at
> > which your host bridge responds to IO space and it must match
> > your configuration.
> 
> I'd always recommend mapping the I/O space to PCI address zero, but
> evidently the hardware is not configured that way here.

+1 and it is a message that must be heeded by Xiling folks before
merging the host controller changes and respective DT bindings/dts.

Lorenzo


Re: [PATCH v7 7/9] acpi/arm64: Add memory-mapped timer support in GTDT driver

2016-07-14 Thread Lorenzo Pieralisi
On Thu, Jul 14, 2016 at 01:53:20AM +0800, fu@linaro.org wrote:
> From: Fu Wei 
> 
> This driver adds support for parsing memory-mapped timer in GTDT:
> provide a kernel APIs to parse GT Block Structure in GTDT,
> export all the info by filling the struct which provided
> by parameter(pointer of the struct).
> 
> By this driver, we can add ACPI support for memory-mapped timer in
> arm_arch_timer drivers, and separate the ACPI GTDT knowledge from it.
> 
> Signed-off-by: Fu Wei 
> Signed-off-by: Hanjun Guo 
> ---
>  drivers/acpi/arm64/acpi_gtdt.c   | 90 
> 
>  include/clocksource/arm_arch_timer.h | 15 ++
>  include/linux/acpi.h |  1 +
>  3 files changed, 106 insertions(+)
> 
> diff --git a/drivers/acpi/arm64/acpi_gtdt.c b/drivers/acpi/arm64/acpi_gtdt.c
> index 9ee977d..ff62953 100644
> --- a/drivers/acpi/arm64/acpi_gtdt.c
> +++ b/drivers/acpi/arm64/acpi_gtdt.c
> @@ -168,3 +168,93 @@ int __init gtdt_arch_timer_init(struct acpi_table_header 
> *table)
>  
>   return -EINVAL;
>  }
> +
> +/*
> + * Helper function for getting the pointer of a timer frame in GT block.
> + */
> +static void __init *gtdt_gt_timer_frame(struct acpi_gtdt_timer_block 
> *gt_block,
> + int index)
> +{
> + void *timer_frame = (void *)gt_block + gt_block->timer_offset +
> + sizeof(struct acpi_gtdt_timer_entry) * index;
> +
> + if (timer_frame <= (void *)gt_block + gt_block->header.length -
> +sizeof(struct acpi_gtdt_timer_entry))
> + return timer_frame;

Nit: gt_block is an array, right ? I think it would be much simpler
if you treat is as such, so that indexing into it would be done
automatically by the compiler. Actually, I do not even think you
would need this function at all if you treat gt_block as an array,
the length check could be done in gtdt_parse_gt_block() straight
away.

> +
> + return NULL;
> +}
> +
> +static int __init gtdt_parse_gt_block(void *platform_timer, int index,
> +   void *data)
> +{
> + struct acpi_gtdt_timer_block *block;
> + struct acpi_gtdt_timer_entry *frame;
> + struct gt_block_data *block_data;
> + int i, j;
> +
> + if (!platform_timer || !data)
> + return -EINVAL;
> +
> + block = platform_timer;
> + block_data = data + sizeof(struct gt_block_data) * index;

Nit: See above, data is a struct gt_block_data[] right ? These void
pointers parameters are not really great, the caller context
knows what they are and it can pass them as pointer to typed
array elements anyway unless I am missing something.

> + if (!block->block_address || !block->timer_count) {
> + pr_err(FW_BUG "invalid GT Block data.\n");
> + return -EINVAL;
> + }
> + block_data->cntctlbase_phy = (phys_addr_t)block->block_address;
> + block_data->timer_count = block->timer_count;
> +
> + /*
> +  * Get the GT timer Frame data for every GT Block Timer
> +  */
> + for (i = 0, j = 0; i < block->timer_count; i++) {

What's j needed for (ie can't you use just i instead ?) ?

> + frame = gtdt_gt_timer_frame(block, i);
> + if (!frame || !frame->base_address || !frame->timer_interrupt) {
> + pr_err(FW_BUG "invalid GT Block Timer data.\n");
> + return -EINVAL;
> + }
> + block_data->timer[j].frame_nr = frame->frame_number;
> + block_data->timer[j].cntbase_phy = frame->base_address;
> + block_data->timer[j].irq = map_generic_timer_interrupt(
> +frame->timer_interrupt,
> +frame->timer_flags);
> + if (frame->virtual_timer_interrupt)
> + block_data->timer[j].virt_irq =
> + map_generic_timer_interrupt(
> + frame->virtual_timer_interrupt,
> + frame->virtual_timer_flags);
> + j++;
> + }
> +
> + if (j)
> + return 0;
> +
> + block_data->cntctlbase_phy = (phys_addr_t)NULL;

This is wrong. NULL is not meant to be used as a physical address,
you must not do that. Is not zeroeing timer_count enough ? I have
to understand why you need this because casting NULL into it is
not safe, at all.

> + block_data->timer_count = 0;
> +
> + return -EINVAL;
> +}
> +
> +/*
> + * Get the GT block info for memory-mapped timer from GTDT table.
> + * Please make sure we have called gtdt_arch_timer_init, because it helps to
> + * init the global variables.

It is a helper function that you call once at boot, you easily
determine when it is called, it is not meant to be used in different
contexts from different subsystems; I think that this comment
is not 

Re: [RFC PATCH v3 00/13] ACPI IORT ARM SMMU v3 support

2016-07-25 Thread Lorenzo Pieralisi
On Mon, Jul 25, 2016 at 01:53:32PM +0800, Dennis Chen wrote:
> Hi
> On Wed, Jul 20, 2016 at 12:23:22PM +0100, Lorenzo Pieralisi wrote:
> > This RFC patch series is v3 of a previous posting:
> > 
> > https://lkml.org/lkml/2016/6/7/523
> > 
> > v2 -> v3
> > - Rebased on top of dependencies series [1][2][3](v4.7-rc3)
> > - Added back reliance on ACPI early probing infrastructure
> > - Patch[1-3] merged through other dependent series
> > - Added back IOMMU fwnode generalization
> > - Move SMMU v3 static functions configuration to IORT code
> > - Implemented generic IOMMU fwspec API
> > - Added code to implement fwnode platform device look-up
> > 
> > v1 -> v2:
> > - Rebased on top of dependencies series [1][2][3](v4.7-rc1)
> > - Removed IOMMU fwnode generalization
> > - Implemented ARM SMMU v3 ACPI probing instead of ARM SMMU v2
> >   owing to patch series dependencies [1]
> > - Moved platform device creation logic to IORT code to
> >   generalize its usage for ARM SMMU v1-v2-v3 components
> > - Removed reliance on ACPI early device probing
> > - Created IORT specific iommu_xlate() translation hook leaving
> >   OF code unchanged according to v1 reviews
> > 
> > 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, available through [2]:
> > 
> > this patchset enables ARM SMMU v3 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.
> > 
> > PATCH (1) adds a FWNODE_IOMMU type to the struct fwnode_handle type.
> >   It is required to attach a fwnode identifier to platform
> >   devices allocated/detected through IORT tables entries;
> >   IOMMU devices have to have an identifier to look them up
> >   eg IOMMU core layer carrying out id translation. This can be
> >   done through a fwnode_handle (ie IOMMU platform devices created
> >   out of IORT tables are not ACPI devices hence they can't be
> >   allocated as such, otherwise they would have a fwnode_handle of
> >   type FWNODE_ACPI). This patch requires discussion and it is key
> >   to the RFC.
> > 
> > PATCH (2) makes use of the ACPI early probing API to add a linker script
> >   section for probing devices via IORT ACPI kernel code.
> > 
> > PATCH (3) provides IORT support for registering IOMMU IORT node through
> >   their fwnode handle.
> > 
> > PATCH (4) implements core code fwnode based platform devices look-up.
> > 
> > PATCH (5) extends iommu_fwspec so that it can be used on ACPI based
> >   system by creating a generic IOMMU fwspec kernel layer.
> > 
> > PATCH (6) implements the of_dma_configure() API in ACPI world -
> >   acpi_dma_configure() - and patches PCI and ACPI core code to
> >   start making use of it.
> > 
> > PATCH (7) provides an IORT function to detect existence of specific type
> >   of IORT components.
> > 
> > PATCH (8) creates the kernel infrastructure required to create ARM SMMU
> >   platform devices for IORT nodes.
> > 
> > PATCH (9) refactors the ARM SMMU v3 driver so that the init functions are
> >   split in a way that groups together code that probes through DT
> >   and code that carries out HW registers FW agnostic probing, in
> >   preparation for adding the ACPI probing path.
> > 
> > PATCH (10) rework ARM SMMU v3 platform driver registration to make it work
> >on ACPI systems.
> > 
> > PATCH (11) Building on patch (8), it adds ARM SMMU v3 IORT IOMMU
> >operations to create and probe ARM SMMU v3 components.
> > 
> > PATCH (12) Extend the IORT iort_node_map_rid() to work on a type mask
> >instead of a single type so that the translation API can
> >be used on a range of components.
> > 
> > PATCH (13) provides IORT infrastructure to carry out IOMMU configuration
> >for devices and hook it u

Re: [RFC PATCH v3 05/13] drivers: iommu: make iommu_fwspec OF agnostic

2016-07-25 Thread Lorenzo Pieralisi
On Mon, Jul 25, 2016 at 10:21:10AM -0500, Rob Herring wrote:
> On Mon, Jul 25, 2016 at 10:09 AM, Robin Murphy <robin.mur...@arm.com> wrote:
> > Hi Lorenzo,
> >
> > On 20/07/16 12:23, Lorenzo Pieralisi wrote:
> >> The iommu_fwspec structure, used to hold per device iommu configuration
> >> data is not OF specific and therefore can be moved to a generic
> >> and OF independent compilation unit.
> >>
> >> In particular, the iommu_fwspec handling hinges on the device_node
> >> pointer to identify the IOMMU device associated with the iommu_fwspec
> >> structure, that is easily converted to a more generic fwnode_handle
> >> pointer that can cater for OF and non-OF (ie ACPI) systems.
> >>
> >> Create the files and related Kconfig entry to decouple iommu_fwspec
> >> structure from the OF iommu kernel layer.
> >>
> >> Given that the current iommu_fwspec implementation relies on
> >> the arch specific struct device.archdata.iommu field in its
> >> implementation, by making the code standalone and independent
> >> of the OF layer this patch makes sure that the iommu_fwspec
> >> kernel code can be selected only on arches implementing the
> >> struct device.archdata.iommu field by adding an explicit
> >> arch dependency in its config entry.
> >>
> >> Current drivers using the iommu_fwspec for streamid translation
> >> are converted to the new iommu_fwspec API by simply converting
> >> the device_node to its fwnode_handle pointer.
> >>
> >> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieral...@arm.com>
> >> Cc: Will Deacon <will.dea...@arm.com>
> >> Cc: Hanjun Guo <hanjun@linaro.org>
> >> Cc: Robin Murphy <robin.mur...@arm.com>
> >> Cc: Joerg Roedel <j...@8bytes.org>
> >> ---
> >>  drivers/iommu/Kconfig|   4 ++
> >>  drivers/iommu/Makefile   |   1 +
> >>  drivers/iommu/arm-smmu-v3.c  |  13 +++--
> >>  drivers/iommu/iommu-fwspec.c | 114 
> >> +++
> >>  drivers/iommu/of_iommu.c |  52 
> >>  include/linux/iommu-fwspec.h |  60 +++
> >>  include/linux/of_iommu.h |  24 +++--
> >>  7 files changed, 196 insertions(+), 72 deletions(-)
> >>  create mode 100644 drivers/iommu/iommu-fwspec.c
> >>  create mode 100644 include/linux/iommu-fwspec.h
> >>
> >> diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
> >> index d1c66af..2b26bfb 100644
> >> --- a/drivers/iommu/Kconfig
> >> +++ b/drivers/iommu/Kconfig
> >> @@ -67,6 +67,10 @@ config OF_IOMMU
> >> def_bool y
> >> depends on OF && IOMMU_API
> >>
> >> +config IOMMU_FWSPEC
> >> +   def_bool y
> >> +   depends on ARM64 && IOMMU_API
> >
> > I think that could be at least (ARM || ARM64).
> 
> Why any arch dependency?
> 
> Seems like OF_IOMMU (and ACPI?) should select this.

Absolutely, that's the end goal. Current issue is that the iommu_fwspec
mechanism relies on dev_archdata.iommu pointer internally to work and
since that's arch specific I can't select it on arches that do not have
that field, it would break the compilation.

I will follow up with Robin to make sure we will be able to
implement what you request above.

Thanks !
Lorenzo


Re: [RFC PATCH v3 05/13] drivers: iommu: make iommu_fwspec OF agnostic

2016-07-25 Thread Lorenzo Pieralisi
On Mon, Jul 25, 2016 at 04:09:55PM +0100, Robin Murphy wrote:
> Hi Lorenzo,
> 
> On 20/07/16 12:23, Lorenzo Pieralisi wrote:
> > The iommu_fwspec structure, used to hold per device iommu configuration
> > data is not OF specific and therefore can be moved to a generic
> > and OF independent compilation unit.
> > 
> > In particular, the iommu_fwspec handling hinges on the device_node
> > pointer to identify the IOMMU device associated with the iommu_fwspec
> > structure, that is easily converted to a more generic fwnode_handle
> > pointer that can cater for OF and non-OF (ie ACPI) systems.
> > 
> > Create the files and related Kconfig entry to decouple iommu_fwspec
> > structure from the OF iommu kernel layer.
> > 
> > Given that the current iommu_fwspec implementation relies on
> > the arch specific struct device.archdata.iommu field in its
> > implementation, by making the code standalone and independent
> > of the OF layer this patch makes sure that the iommu_fwspec
> > kernel code can be selected only on arches implementing the
> > struct device.archdata.iommu field by adding an explicit
> > arch dependency in its config entry.
> > 
> > Current drivers using the iommu_fwspec for streamid translation
> > are converted to the new iommu_fwspec API by simply converting
> > the device_node to its fwnode_handle pointer.
> > 
> > Signed-off-by: Lorenzo Pieralisi <lorenzo.pieral...@arm.com>
> > Cc: Will Deacon <will.dea...@arm.com>
> > Cc: Hanjun Guo <hanjun@linaro.org>
> > Cc: Robin Murphy <robin.mur...@arm.com>
> > Cc: Joerg Roedel <j...@8bytes.org>
> > ---
> >  drivers/iommu/Kconfig|   4 ++
> >  drivers/iommu/Makefile   |   1 +
> >  drivers/iommu/arm-smmu-v3.c  |  13 +++--
> >  drivers/iommu/iommu-fwspec.c | 114 
> > +++
> >  drivers/iommu/of_iommu.c |  52 
> >  include/linux/iommu-fwspec.h |  60 +++
> >  include/linux/of_iommu.h |  24 +++--
> >  7 files changed, 196 insertions(+), 72 deletions(-)
> >  create mode 100644 drivers/iommu/iommu-fwspec.c
> >  create mode 100644 include/linux/iommu-fwspec.h
> > 
> > diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
> > index d1c66af..2b26bfb 100644
> > --- a/drivers/iommu/Kconfig
> > +++ b/drivers/iommu/Kconfig
> > @@ -67,6 +67,10 @@ config OF_IOMMU
> > def_bool y
> > depends on OF && IOMMU_API
> >  
> > +config IOMMU_FWSPEC
> > +   def_bool y
> > +   depends on ARM64 && IOMMU_API
> 
> I think that could be at least (ARM || ARM64).

Yes agreed.

> >  # IOMMU-agnostic DMA-mapping layer
> >  config IOMMU_DMA
> > bool
> 
> [...]
> 
> > diff --git a/include/linux/of_iommu.h b/include/linux/of_iommu.h
> > index 308791f..2362232 100644
> > --- a/include/linux/of_iommu.h
> > +++ b/include/linux/of_iommu.h
> > @@ -15,13 +15,8 @@ extern void of_iommu_init(void);
> >  extern const struct iommu_ops *of_iommu_configure(struct device *dev,
> > struct device_node *master_np);
> >  
> > -struct iommu_fwspec {
> > -   const struct iommu_ops  *iommu_ops;
> > -   struct device_node  *iommu_np;
> > -   void*iommu_priv;
> > -   unsigned intnum_ids;
> > -   u32 ids[];
> > -};
> > +void of_iommu_set_ops(struct device_node *np, const struct iommu_ops *ops);
> > +const struct iommu_ops *of_iommu_get_ops(struct device_node *np);
> 
> Is there some reason we need to retain the existing definitions of
> these? I was assuming we'd be able to move the entire implementation
> over to the fwspec code and leave behind nothing more than trivial
> wrappers, e.g.:
> 
> #define of_iommu_get_ops(np) iommu_fwspec_get_ops(&(np)->fwnode_handle)

Yep, that's exactly what I did but then I was bitten by config
dependencies. If we implement of_iommu_get/set_ops() as wrappers,
we have to compile iommu_fwspec_get/set_ops() on arches that may
not have struct dev_archdata.iommu, unless we introduce yet another
config symbol to avoid compiling that code (see eg iommu_fwspec_init(),
we can't compile it on eg x86 even though we do need of_iommu_get_ops()
on it - so iommu_fwspec_get_ops(), that lives in the same compilation
unit as eg iommu_fwspec_init()).

So short answer is: there is no reason apart from dev_archdata.iommu
being arch specific, if we were able to move iommu_fwspec to generic
code (ie struct device, somehow) I would certainly get rid o

Re: [RFC PATCH v3 05/13] drivers: iommu: make iommu_fwspec OF agnostic

2016-07-25 Thread Lorenzo Pieralisi
On Mon, Jul 25, 2016 at 04:51:00PM +0100, Robin Murphy wrote:
> On 25/07/16 16:41, Lorenzo Pieralisi wrote:
> [...]
> >>> diff --git a/include/linux/of_iommu.h b/include/linux/of_iommu.h
> >>> index 308791f..2362232 100644
> >>> --- a/include/linux/of_iommu.h
> >>> +++ b/include/linux/of_iommu.h
> >>> @@ -15,13 +15,8 @@ extern void of_iommu_init(void);
> >>>  extern const struct iommu_ops *of_iommu_configure(struct device *dev,
> >>>   struct device_node *master_np);
> >>>  
> >>> -struct iommu_fwspec {
> >>> - const struct iommu_ops  *iommu_ops;
> >>> - struct device_node  *iommu_np;
> >>> - void*iommu_priv;
> >>> - unsigned intnum_ids;
> >>> - u32 ids[];
> >>> -};
> >>> +void of_iommu_set_ops(struct device_node *np, const struct iommu_ops 
> >>> *ops);
> >>> +const struct iommu_ops *of_iommu_get_ops(struct device_node *np);
> >>
> >> Is there some reason we need to retain the existing definitions of
> >> these? I was assuming we'd be able to move the entire implementation
> >> over to the fwspec code and leave behind nothing more than trivial
> >> wrappers, e.g.:
> >>
> >> #define of_iommu_get_ops(np) iommu_fwspec_get_ops(&(np)->fwnode_handle)
> > 
> > Yep, that's exactly what I did but then I was bitten by config
> > dependencies. If we implement of_iommu_get/set_ops() as wrappers,
> > we have to compile iommu_fwspec_get/set_ops() on arches that may
> > not have struct dev_archdata.iommu, unless we introduce yet another
> > config symbol to avoid compiling that code (see eg iommu_fwspec_init(),
> > we can't compile it on eg x86 even though we do need of_iommu_get_ops()
> > on it - so iommu_fwspec_get_ops(), that lives in the same compilation
> > unit as eg iommu_fwspec_init()).
> > 
> > So short answer is: there is no reason apart from dev_archdata.iommu
> > being arch specific, if we were able to move iommu_fwspec to generic
> > code (ie struct device, somehow) I would certainly get rid of this
> > stupid code duplication (or as I said I can add a config entry for
> > that, more ideas are welcome).
> 
> OK, given Rob's comment as well, I guess breaking that dependency is to
> everyone's benefit. Since it's quite closely related, how about if we
> follow the arch_setup_dma_ops() pattern with an
> arch_{get,set}_iommu_fwspec(dev) type thing?

Yes we can do that too as an intermediate step, that solves the
problem (and it makes this patch much simpler), it is cleaner
than doing it with a(nother) Kconfig entry.

Thanks,
Lorenzo

> Robin.
> 
> > 
> > Thanks,
> > Lorenzo
> > 
> >>
> >> Robin.
> >>
> >>>  #else
> >>>  
> >>> @@ -39,17 +34,14 @@ static inline const struct iommu_ops 
> >>> *of_iommu_configure(struct device *dev,
> >>>   return NULL;
> >>>  }
> >>>  
> >>> -struct iommu_fwspec;
> >>> -
> >>> -#endif   /* CONFIG_OF_IOMMU */
> >>> +static inline void of_iommu_set_ops(struct device_node *np,
> >>> + const struct iommu_ops *ops)
> >>> +{ }
> >>>  
> >>> -int iommu_fwspec_init(struct device *dev, struct device_node *iommu_np);
> >>> -void iommu_fwspec_free(struct device *dev);
> >>> -int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids);
> >>> -struct iommu_fwspec *dev_iommu_fwspec(struct device *dev);
> >>> +static inline const struct iommu_ops *
> >>> +of_iommu_get_ops(struct device_node *np) { return NULL; }
> >>>  
> >>> -void of_iommu_set_ops(struct device_node *np, const struct iommu_ops 
> >>> *ops);
> >>> -const struct iommu_ops *of_iommu_get_ops(struct device_node *np);
> >>> +#endif   /* CONFIG_OF_IOMMU */
> >>>  
> >>>  extern struct of_device_id __iommu_of_table;
> >>>  
> >>>
> >>
> > 
> 


Re: [PATCH v10 0/8] acpi, clocksource: add GTDT driver and GTDT support in arm_arch_timer

2016-08-11 Thread Lorenzo Pieralisi
On Thu, Aug 11, 2016 at 06:22:03PM +0800, Fu Wei wrote:
> Hi Hanjun, Tomasz,
> 
> On 11 August 2016 at 18:15, Hanjun Guo  wrote:
> > Hi,
> >
> > On 2016/8/11 17:37, Tomasz Nowicki wrote:
> >>
> >> Hi Fu,
> >>
> >> Do you mind if I send IORT series where new drivers/acpi/arm64 directory
> >> would be introduced in first place ? This means your GTDT set would
> >> depend on IORT.
> >
> >
> > I think it's reasonable as the IORT for ITS is the key device enablement
> > for PCI MSI. I talked to Fuwei offline and he is fine with it.
> 
> That's no problem at all, will do.
> 
> Can I do this:
> (1)apply Tomasz's v8 patchset on the master branch of upstream kernel
> (2)rebase my v10 on the top of Tomasz's v8
> (3)git format-patch as v11, repost it
> 
> Is that OK for everyone? :-)

I do not think you need a v11 just to remove the drivers/acpi/arm64
directory creation, you need to get Daniel/Thomas review/ack on
the respective patches though, I do not see the point of churning
out another series just because drivers/acpi/arm64 is now created
in the IORT patch series. If v10 is ok you will rebase it on top of
Tomasz's series and mention the dependency in the respective pull
request.

If there is need for a v11 following Daniel/Thomas review yes,
you can proceed as above.

Lorenzo


Re: [RFC PATCH v3 05/13] drivers: iommu: make iommu_fwspec OF agnostic

2016-08-11 Thread Lorenzo Pieralisi
On Mon, Jul 25, 2016 at 04:51:00PM +0100, Robin Murphy wrote:
> On 25/07/16 16:41, Lorenzo Pieralisi wrote:
> [...]
> >>> diff --git a/include/linux/of_iommu.h b/include/linux/of_iommu.h
> >>> index 308791f..2362232 100644
> >>> --- a/include/linux/of_iommu.h
> >>> +++ b/include/linux/of_iommu.h
> >>> @@ -15,13 +15,8 @@ extern void of_iommu_init(void);
> >>>  extern const struct iommu_ops *of_iommu_configure(struct device *dev,
> >>>   struct device_node *master_np);
> >>>  
> >>> -struct iommu_fwspec {
> >>> - const struct iommu_ops  *iommu_ops;
> >>> - struct device_node  *iommu_np;
> >>> - void*iommu_priv;
> >>> - unsigned intnum_ids;
> >>> - u32 ids[];
> >>> -};
> >>> +void of_iommu_set_ops(struct device_node *np, const struct iommu_ops 
> >>> *ops);
> >>> +const struct iommu_ops *of_iommu_get_ops(struct device_node *np);
> >>
> >> Is there some reason we need to retain the existing definitions of
> >> these? I was assuming we'd be able to move the entire implementation
> >> over to the fwspec code and leave behind nothing more than trivial
> >> wrappers, e.g.:
> >>
> >> #define of_iommu_get_ops(np) iommu_fwspec_get_ops(&(np)->fwnode_handle)
> > 
> > Yep, that's exactly what I did but then I was bitten by config
> > dependencies. If we implement of_iommu_get/set_ops() as wrappers,
> > we have to compile iommu_fwspec_get/set_ops() on arches that may
> > not have struct dev_archdata.iommu, unless we introduce yet another
> > config symbol to avoid compiling that code (see eg iommu_fwspec_init(),
> > we can't compile it on eg x86 even though we do need of_iommu_get_ops()
> > on it - so iommu_fwspec_get_ops(), that lives in the same compilation
> > unit as eg iommu_fwspec_init()).
> > 
> > So short answer is: there is no reason apart from dev_archdata.iommu
> > being arch specific, if we were able to move iommu_fwspec to generic
> > code (ie struct device, somehow) I would certainly get rid of this
> > stupid code duplication (or as I said I can add a config entry for
> > that, more ideas are welcome).
> 
> OK, given Rob's comment as well, I guess breaking that dependency is to
> everyone's benefit. Since it's quite closely related, how about if we
> follow the arch_setup_dma_ops() pattern with an
> arch_{get,set}_iommu_fwspec(dev) type thing?

How about this (on top of your current iommu/generic branch):

If that's ok feel free to squash it in for the next posting,
or I can add it to my IORT series (I'd argue though that the
problem it solves is not strictly related to ACPI), please
let me know.

Thanks !
Lorenzo

-- >8 --
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 2d601d7..dfd331d 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -58,6 +58,7 @@ config ARM
select HAVE_GENERIC_DMA_COHERENT
select HAVE_HW_BREAKPOINT if (PERF_EVENTS && (CPU_V6 || CPU_V6K || 
CPU_V7))
select HAVE_IDE if PCI || ISA || PCMCIA
+   select HAVE_IOMMU_FWSPEC if IOMMU_API
select HAVE_IRQ_TIME_ACCOUNTING
select HAVE_KERNEL_GZIP
select HAVE_KERNEL_LZ4
diff --git a/arch/arm/include/asm/iommu-fwspec.h 
b/arch/arm/include/asm/iommu-fwspec.h
new file mode 100644
index 000..d6581a1
--- /dev/null
+++ b/arch/arm/include/asm/iommu-fwspec.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2016 ARM Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef __ASM_IOMMU_FWSPEC_H
+#define __ASM_IOMMU_FWSPEC_H
+
+static inline void arch_set_iommu_fwspec(struct device *dev,
+struct iommu_fwspec *fwspec)
+{
+   dev->archdata.iommu = fwspec;
+}
+
+static inline struct iommu_fwspec *arch_get_iommu_fwspec(struct device *dev)
+{
+   return dev->archdata.iommu;
+}
+#endif
+
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 69c8787..90d420f 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -82,6 +82,7 @@ config ARM64
select HAVE_GCC_PLUGINS
select HAVE_GENERIC_DMA_

Re: [PATCH] ARM: cpuidle: Fix error return code

2016-08-11 Thread Lorenzo Pieralisi
On Thu, Aug 11, 2016 at 03:02:30PM +0200, Christophe JAILLET wrote:
> We know that 'ret = 0' because it has been tested a few lines above.
> So, if 'kzalloc' fails, 0 will be returned instead of an error code.
> Return -ENOMEM instead.
> 
> Fixes: a0d46a3dfdc3 ("ARM: cpuidle: Register per cpuidle device")
> 
> Signed-off-by: Christophe JAILLET <christophe.jail...@wanadoo.fr>
> ---
>  drivers/cpuidle/cpuidle-arm.c | 1 +
>  1 file changed, 1 insertion(+)

Acked-by: Lorenzo Pieralisi <lorenzo.pieral...@arm.com>


Re: [RFC PATCH v3 13/13] drivers: acpi: iort: introduce iort_iommu_configure

2016-08-11 Thread Lorenzo Pieralisi
On Wed, Aug 03, 2016 at 10:19:43AM -0400, nwatt...@codeaurora.org wrote:

[...]

> >+const struct iommu_ops *iort_iommu_configure(struct device *dev)
> >+{
> >+struct acpi_iort_node *node, *parent;
> >+struct fwnode_handle *iort_fwnode;
> >+u32 rid = 0, devid = 0;
> 
> Since this routine maps the RID space of a device to the StreamID
> space of its
> parent smmu, would you consider renaming the devid variable to some
> form of sid
> or streamid?
> 
> >+
> >+if (dev_is_pci(dev)) {
> >+struct pci_bus *bus = to_pci_dev(dev)->bus;
> >+
> >+pci_for_each_dma_alias(to_pci_dev(dev), __get_pci_rid,
> >+   );
> >+
> >+node = iort_scan_node(ACPI_IORT_NODE_PCI_ROOT_COMPLEX,
> >+  iort_match_node_callback, >dev);
> >+} else {
> >+node = iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT,
> >+  iort_match_node_callback, dev);
> >+}
> >+
> >+if (!node)
> >+return NULL;
> >+
> >+parent = iort_node_map_rid(node, rid, , IORT_IOMMU_TYPE);
> >+if (parent) {
> >+iort_fwnode = iort_get_fwnode(parent);
> >+if (iort_fwnode) {
> >+arm_smmu_iort_xlate(dev, devid, iort_fwnode);
> 
> What about named components with multiple stream ids? Since
> establishing the relationship between a named component and its parent
> smmu is already dependent on there being an appropriate mapping of rid
> 0, it stands to reason that all of the stream ids for a named
> component could be enumerated by mapping increasing rid values until
> the output parent no longer matches that returned for rid 0.

I have reworked the code since for named component it makes no
sense to carry out a mapping that depends on an input id given
that we do not have one. Instead what we will do is the same
thing DT does (ie "iommus" property), namely walk the array of
single mappings for a given named component (that do not depend
on the input rid, there is not any) and add them to the translation
as we find them.

Ergo, mappings that are not single mappings are pretty much useless
for named components (for the time being), and I won't allow them.

Thoughts ?

Lorenzo

> 
> >+return fwspec_iommu_get_ops(iort_fwnode);
> >+}
> >+}
> >+
> >+return NULL;
> >+}
> 
> It should be noted that while trying out the approach described
> above, I noticed
> that each of the smmu attached named components described in my iort
> were ending
> up with an extra stream id. The culprit appears to be that the range
> checking in
> iort_id_map() is overly permissive on the upper bounds. For example,
> mappings
> with input_base=N and id_count=1 were matching both N and N+1. The
> following
> change fixed the issue.
> 
> @@ -296,7 +296,7 @@ iort_id_map(struct acpi_iort_id_mapping *map, u8
> type, u32 rid_in, u32 *rid_out)
> }
> 
> if (rid_in < map->input_base ||
> -   (rid_in > map->input_base + map->id_count))
> +   (rid_in >= map->input_base + map->id_count))
> return -ENXIO;
> 
> *rid_out = map->output_base + (rid_in - map->input_base);
> 
> >+
> > static void acpi_smmu_v3_register_irq(int hwirq, const char *name,
> >   struct resource *res)
> > {
> >diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
> >index b4b9064..de28825 100644
> >--- a/drivers/acpi/scan.c
> >+++ b/drivers/acpi/scan.c
> >@@ -7,6 +7,7 @@
> > #include 
> > #include 
> > #include 
> >+#include 
> > #include 
> > #include 
> > #include 
> >@@ -1365,11 +1366,15 @@ enum dev_dma_attr acpi_get_dma_attr(struct
> >acpi_device *adev)
> >  */
> > void acpi_dma_configure(struct device *dev, enum dev_dma_attr attr)
> > {
> >+const struct iommu_ops *iommu;
> >+
> >+iommu = iort_iommu_configure(dev);
> >+
> > /*
> >  * Assume dma valid range starts at 0 and covers the whole
> >  * coherent_dma_mask.
> >  */
> >-arch_setup_dma_ops(dev, 0, dev->coherent_dma_mask + 1, NULL,
> >+arch_setup_dma_ops(dev, 0, dev->coherent_dma_mask + 1, iommu,
> >attr == DEV_DMA_COHERENT);
> 
> If dev has a matching named component iort entry with a non-zero
> value for
> memory_address_limit, why not use that as the size input to
> arch_setup_dma_ops?
> 
> > }
> >
> >diff --git a/include/linux/iort.h b/include/linux/iort.h
> >index 18e6836..bbe08ef 100644
> >--- a/include/linux/iort.h
> >+++ b/include/linux/iort.h
> >@@ -34,6 +34,8 @@ struct irq_domain *iort_get_device_domain(struct
> >device *dev, u32 req_id);
> > /* IOMMU interface */
> > int iort_add_smmu_platform_device(struct fwnode_handle *fwnode,
> >   struct acpi_iort_node *node);
> >+
> >+const struct iommu_ops *iort_iommu_configure(struct device *dev);
> > #else
> > static inline bool iort_node_match(u8 type) { return false; }
> > static inline void 

Re: [PATCH V8 1/8] ACPI: I/O Remapping Table (IORT) initial support

2016-08-12 Thread Lorenzo Pieralisi
Hi Tomasz,

On Thu, Aug 11, 2016 at 12:06:31PM +0200, Tomasz Nowicki wrote:
> IORT shows representation of IO topology for ARM based systems.
> It describes how various components are connected together on
> parent-child basis e.g. PCI RC -> SMMU -> ITS. Also see IORT spec.
> http://infocenter.arm.com/help/topic/com.arm.doc.den0049b/DEN0049B_IO_Remapping_Table.pdf
> 
> Initial support allows to detect IORT table presence and save its
> root pointer obtained through acpi_get_table(). The pointer validity
> depends on acpi_gbl_permanent_mmap because if acpi_gbl_permanent_mmap
> is not set while using IORT nodes we would dereference unmapped pointers.
> 
> For the aforementioned reason call iort_table_detect() from acpi_init()
> which guarantees acpi_gbl_permanent_mmap to be set at that point.

We still need to get Rafael ACK on this, keeping in mind that the
eg code parsing DMAR table relies on the same assumption.

[...]

> diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
> index 445ce28..6cef2d1 100644
> --- a/drivers/acpi/Kconfig
> +++ b/drivers/acpi/Kconfig
> @@ -521,4 +521,9 @@ config ACPI_CONFIGFS
> userspace. The configurable ACPI groups will be visible under
> /config/acpi, assuming configfs is mounted under /config.
>  
> +if ARM64
> +source "drivers/acpi/arm64/Kconfig"
> +

Just curious: Why do you need a space ?

> +endif
> +
>  endif# ACPI
> diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
> index 5ae9d85..e5ada78 100644
> --- a/drivers/acpi/Makefile
> +++ b/drivers/acpi/Makefile
> @@ -105,3 +105,5 @@ obj-$(CONFIG_ACPI_CONFIGFS)   += acpi_configfs.o
>  
>  video-objs   += acpi_video.o video_detect.o
>  obj-y+= dptf/
> +
> +obj-$(CONFIG_ARM64)  += arm64/
> diff --git a/drivers/acpi/arm64/Kconfig b/drivers/acpi/arm64/Kconfig
> new file mode 100644
> index 000..fc818dc
> --- /dev/null
> +++ b/drivers/acpi/arm64/Kconfig
> @@ -0,0 +1,6 @@
> +#
> +# ACPI Configuration for ARM64
> +#
> +
> +config IORT_TABLE
> + bool
> diff --git a/drivers/acpi/arm64/Makefile b/drivers/acpi/arm64/Makefile
> new file mode 100644
> index 000..d01be6f
> --- /dev/null
> +++ b/drivers/acpi/arm64/Makefile
> @@ -0,0 +1 @@
> +obj-$(CONFIG_IORT_TABLE) += iort.o
> diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
> new file mode 100644
> index 000..f89056e
> --- /dev/null
> +++ b/drivers/acpi/arm64/iort.c
> @@ -0,0 +1,218 @@
> +/*
> + * Copyright (C) 2016, Semihalf
> + *   Author: Tomasz Nowicki <t...@semihalf.com>
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
> + * more details.
> + *
> + * This file implements early detection/parsing of I/O mapping
> + * reported to OS through firmware via I/O Remapping Table (IORT)
> + * IORT document number: ARM DEN 0049A
> + */
> +
> +#define pr_fmt(fmt)  "ACPI: IORT: " fmt
> +
> +#include 
> +#include 
> +#include 
> +
> +typedef acpi_status (*iort_find_node_callback)
> + (struct acpi_iort_node *node, void *context);
> +
> +/* Root pointer to the mapped IORT table */
> +static struct acpi_table_header *iort_table;

See above.

[...]

> +void __init iort_table_detect(void)
> +{
> + acpi_status status;
> +
> + status = acpi_get_table(ACPI_SIG_IORT, 0, _table);
> + if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
> + const char *msg = acpi_format_exception(status);
> + pr_err("Failed to get table, %s\n", msg);
> + }
> +}
> diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
> index 85b7d07..55a84da 100644
> --- a/drivers/acpi/bus.c
> +++ b/drivers/acpi/bus.c
> @@ -36,6 +36,7 @@
>  #ifdef CONFIG_X86
>  #include 
>  #endif
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -1186,6 +1187,7 @@ static int __init acpi_init(void)
>   }
>  
>   pci_mmcfg_late_init();
> + iort_table_detect();

That's another bit we have to make sure Rafael is ok with, given
that IORT is ARM64 specific (but we stub it out if it is not
configured).

Having said that:

Reviewed-by: Lorenzo Pieralisi <lorenzo.pieral...@arm.com>

>   acpi_scan_init();
>   acpi_ec_init();
>   acpi_debugfs_i

Re: [PATCH V8 2/8] ACPI: Add new IORT functions to support MSI domain handling

2016-08-12 Thread Lorenzo Pieralisi
On Thu, Aug 11, 2016 at 12:06:32PM +0200, Tomasz Nowicki wrote:

[...]

> +/**
> + * iort_register_domain_token() - register domain token and related ITS ID
> + * to the list from where we can get it back later on.
> + * @trans_id: ITS ID.
> + * @fw_node: Domain token.
> + *
> + * Returns: 0 on success, -ENOMEM if no memory when allocating list element
> + */
> +int iort_register_domain_token(int trans_id, struct fwnode_handle *fw_node)
> +{
> + struct iort_its_msi_chip *its_msi_chip;
> +
> + its_msi_chip = kzalloc(sizeof(*its_msi_chip), GFP_KERNEL);

I spotted this while reworking my ARM SMMU series, this may sleep
and that's no good given that we call it within the acpi_probe_lock.

Same goes for irq_domain_alloc_fwnode() (that we call in
gic_v2_acpi_init()), we have got to fix this usage, I will see with
Marc what's the best way to do it.

Lorenzo

> + if (!its_msi_chip)
> + return -ENOMEM;
> +
> + its_msi_chip->fw_node = fw_node;
> + its_msi_chip->translation_id = trans_id;
> +
> + spin_lock(_msi_chip_lock);
> + list_add(_msi_chip->list, _msi_chip_list);
> + spin_unlock(_msi_chip_lock);
> +
> + return 0;
> +}
> +
> +/**
> + * iort_deregister_domain_token() - Deregister domain token based on ITS ID
> + * @trans_id: ITS ID.
> + *
> + * Returns: none.
> + */
> +void iort_deregister_domain_token(int trans_id)
> +{
> + struct iort_its_msi_chip *its_msi_chip, *t;
> +
> + spin_lock(_msi_chip_lock);
> + list_for_each_entry_safe(its_msi_chip, t, _msi_chip_list, list) {
> + if (its_msi_chip->translation_id == trans_id) {
> + list_del(_msi_chip->list);
> + kfree(its_msi_chip);
> + break;
> + }
> + }
> + spin_unlock(_msi_chip_lock);
> +}
> +
> +/**
> + * iort_find_domain_token() - Find domain token based on given ITS ID
> + * @trans_id: ITS ID.
> + *
> + * Returns: domain token when find on the list, NULL otherwise
> + */
> +struct fwnode_handle *iort_find_domain_token(int trans_id)
> +{
> + struct fwnode_handle *fw_node = NULL;
> + struct iort_its_msi_chip *its_msi_chip;
> +
> + spin_lock(_msi_chip_lock);
> + list_for_each_entry(its_msi_chip, _msi_chip_list, list) {
> + if (its_msi_chip->translation_id == trans_id) {
> + fw_node = its_msi_chip->fw_node;
> + break;
> + }
> + }
> + spin_unlock(_msi_chip_lock);
> +
> + return fw_node;
> +}
> +
>  static struct acpi_iort_node *
>  iort_scan_node(enum acpi_iort_node_type type,
>  iort_find_node_callback callback, void *context)
> @@ -206,6 +285,96 @@ iort_find_dev_node(struct device *dev)
> iort_match_node_callback, >dev);
>  }
>  
> +/**
> + * iort_msi_map_rid() - Map a MSI requester ID for a device
> + * @dev: The device for which the mapping is to be done.
> + * @req_id: The device requester ID.
> + *
> + * Returns: mapped MSI RID on success, input requester ID otherwise
> + */
> +u32 iort_msi_map_rid(struct device *dev, u32 req_id)
> +{
> + struct acpi_iort_node *node;
> + u32 dev_id;
> +
> + if (!iort_table)
> + return req_id;
> +
> + node = iort_find_dev_node(dev);
> + if (!node) {
> + dev_err(dev, "can't find related IORT node\n");
> + return req_id;
> + }
> +
> + iort_node_map_rid(node, req_id, _id, ACPI_IORT_NODE_ITS_GROUP);
> + return dev_id;
> +}
> +
> +/**
> + * iort_dev_find_its_id() - Find the ITS identifier for a device
> + * @dev: The device.
> + * @idx: Index of the ITS identifier list.
> + * @its_id: ITS identifier.
> + *
> + * Returns: 0 on success, appropriate error value otherwise
> + */
> +static int
> +iort_dev_find_its_id(struct device *dev, u32 req_id, unsigned int idx,
> +  int *its_id)
> +{
> + struct acpi_iort_its_group *its;
> + struct acpi_iort_node *node;
> +
> + node = iort_find_dev_node(dev);
> + if (!node) {
> + dev_err(dev, "can't find related IORT node\n");
> + return -ENXIO;
> + }
> +
> + node = iort_node_map_rid(node, req_id, NULL, ACPI_IORT_NODE_ITS_GROUP);
> + if (!node) {
> + dev_err(dev, "can't find related ITS node\n");
> + return -ENXIO;
> + }
> +
> + /* Move to ITS specific data */
> + its = (struct acpi_iort_its_group *)node->node_data;
> + if (idx > its->its_count) {
> + dev_err(dev, "requested ITS ID index [%d] is greater than 
> available [%d]\n",
> + idx, its->its_count);
> + return -ENXIO;
> + }
> +
> + *its_id = its->identifiers[idx];
> + return 0;
> +}
> +
> +/**
> + * iort_get_device_domain() - Find MSI domain related to a device
> + * @dev: The device.
> + * @req_id: Requester ID for the device.
> + *
> + * Returns: the MSI domain for this device, NULL otherwise
> + */
> +struct irq_domain *
> 

Re: [PATCH v8 7/9] acpi/arm64: Add memory-mapped timer support in GTDT driver

2016-07-21 Thread Lorenzo Pieralisi
On Wed, Jul 20, 2016 at 02:18:02AM +0800, fu@linaro.org wrote:
> From: Fu Wei 
> 
> This driver adds support for parsing memory-mapped timer in GTDT:
> provide a kernel APIs to parse GT Block Structure in GTDT,
> export all the info by filling the struct which provided
> by parameter(pointer of the struct).
> 
> By this driver, we can add ACPI support for memory-mapped timer in
> arm_arch_timer drivers, and separate the ACPI GTDT knowledge from it.

"On platforms booting with ACPI, architected memory timers configuration
data is provided by firmware through the ACPI GTDT static table.

The clocksource architected timer kernel driver requires a firmware
interface to collect timer configuration and configure its driver;
this infrastructure is present for device tree systems but it is
missing on systems booting with ACPI.

Implement the kernel infrastructure required to parse the static
ACPI GTDT table so that the architected timer clocksource driver can
make use of it on systems booting with ACPI, therefore enabling
the corresponding timers configuration."

> Signed-off-by: Fu Wei 
> Signed-off-by: Hanjun Guo 
> ---
>  drivers/acpi/arm64/acpi_gtdt.c   | 72 
> 
>  include/clocksource/arm_arch_timer.h | 15 
>  include/linux/acpi.h |  1 +
>  3 files changed, 88 insertions(+)
> 
> diff --git a/drivers/acpi/arm64/acpi_gtdt.c b/drivers/acpi/arm64/acpi_gtdt.c
> index e1cfc9e..b48e443 100644
> --- a/drivers/acpi/arm64/acpi_gtdt.c
> +++ b/drivers/acpi/arm64/acpi_gtdt.c
> @@ -150,3 +150,75 @@ int __init acpi_gtdt_init(struct acpi_table_header 
> *table)
>  
>   return gtdt->platform_timer_count;
>  }
> +
> +static int __init gtdt_parse_gt_block(void *platform_timer,
> +   struct gt_block_data *data)
> +{

Nit: you can directly pass a struct acpi_gtdt_timer_block* pointer.

> + struct acpi_gtdt_timer_block *block = platform_timer;
> + struct acpi_gtdt_timer_entry *frame;
> + int i;
> +
> + if (!block || !data)
> + return -EINVAL;
> +
> + if (!block->block_address || !block->timer_count)
> + goto error;

Here we jump to print an error and bail out. The only reason
why we need a goto is to print a common error message and that's
exactly what we do _not_ need, if there is a FW error we want
to understand which one is that, otherwise the information you
are printing is useless for debugging (provided we can make use
of this info, which is questionable anyway).

> + data->cntctlbase_phy = (phys_addr_t)block->block_address;
> + data->timer_count = block->timer_count;
> +
> + frame = (void *)block + block->timer_offset;
> + if (frame + block->timer_count != (void *)block + block->header.length)
> + goto error;

See above.

> + /*
> +  * Get the GT timer Frame data for every GT Block Timer
> +  */
> + for (i = 0; i < block->timer_count; i++) {
> + frame += i;

This is wrong, if you have multiple frames, pointers would add up and
that's not correct.

> + if (!frame->base_address || !frame->timer_interrupt)
> + goto error;

See above.

> + data->timer[i].frame_nr = frame->frame_number;
> + data->timer[i].cntbase_phy = frame->base_address;
> + data->timer[i].irq =
> + map_generic_timer_interrupt(frame->timer_interrupt,
> + frame->timer_flags);

AFAIK map_generic_timer_interrupt() may fail, you should cater for that.

> + if (frame->virtual_timer_interrupt)
> + data->timer[i].virt_irq =
> + map_generic_timer_interrupt(
> + frame->virtual_timer_interrupt,
> + frame->virtual_timer_flags);

Ditto.

> + }
> + return 0;
> +
> +error:
> + pr_err(FW_BUG "invalid GT Block data.\n");
> + return -EINVAL;

See above.

> +}
> +
> +/*
> + * Get the GT block info for memory-mapped timer from GTDT table.
> + * Please make sure we have called acpi_gtdt_init, because it helps to
> + * init the global variables.

I already commented on this. I think the second part of this comment
is useless (it is a function with one caller, make sure you respect
the calling sequence and be done with this).

Thanks,
Lorenzo

> + */
> +int __init gtdt_arch_timer_mem_init(struct gt_block_data *data)
> +{
> + void *platform_timer;
> + int index = 0;
> + int ret;
> +
> + for_each_platform_timer(platform_timer) {
> + if (!is_timer_block(platform_timer))
> + continue;
> + ret = gtdt_parse_gt_block(platform_timer, data + index);
> + if (ret)
> + return ret;
> + index++;
> + }
> +
> + if (index)
> + 

[RFC PATCH v3 05/13] drivers: iommu: make iommu_fwspec OF agnostic

2016-07-20 Thread Lorenzo Pieralisi
The iommu_fwspec structure, used to hold per device iommu configuration
data is not OF specific and therefore can be moved to a generic
and OF independent compilation unit.

In particular, the iommu_fwspec handling hinges on the device_node
pointer to identify the IOMMU device associated with the iommu_fwspec
structure, that is easily converted to a more generic fwnode_handle
pointer that can cater for OF and non-OF (ie ACPI) systems.

Create the files and related Kconfig entry to decouple iommu_fwspec
structure from the OF iommu kernel layer.

Given that the current iommu_fwspec implementation relies on
the arch specific struct device.archdata.iommu field in its
implementation, by making the code standalone and independent
of the OF layer this patch makes sure that the iommu_fwspec
kernel code can be selected only on arches implementing the
struct device.archdata.iommu field by adding an explicit
arch dependency in its config entry.

Current drivers using the iommu_fwspec for streamid translation
are converted to the new iommu_fwspec API by simply converting
the device_node to its fwnode_handle pointer.

Signed-off-by: Lorenzo Pieralisi <lorenzo.pieral...@arm.com>
Cc: Will Deacon <will.dea...@arm.com>
Cc: Hanjun Guo <hanjun@linaro.org>
Cc: Robin Murphy <robin.mur...@arm.com>
Cc: Joerg Roedel <j...@8bytes.org>
---
 drivers/iommu/Kconfig|   4 ++
 drivers/iommu/Makefile   |   1 +
 drivers/iommu/arm-smmu-v3.c  |  13 +++--
 drivers/iommu/iommu-fwspec.c | 114 +++
 drivers/iommu/of_iommu.c |  52 
 include/linux/iommu-fwspec.h |  60 +++
 include/linux/of_iommu.h |  24 +++--
 7 files changed, 196 insertions(+), 72 deletions(-)
 create mode 100644 drivers/iommu/iommu-fwspec.c
 create mode 100644 include/linux/iommu-fwspec.h

diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index d1c66af..2b26bfb 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -67,6 +67,10 @@ config OF_IOMMU
def_bool y
depends on OF && IOMMU_API
 
+config IOMMU_FWSPEC
+   def_bool y
+   depends on ARM64 && IOMMU_API
+
 # IOMMU-agnostic DMA-mapping layer
 config IOMMU_DMA
bool
diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index c6edb31..dd85337 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -7,6 +7,7 @@ obj-$(CONFIG_IOMMU_IO_PGTABLE_ARMV7S) += io-pgtable-arm-v7s.o
 obj-$(CONFIG_IOMMU_IO_PGTABLE_LPAE) += io-pgtable-arm.o
 obj-$(CONFIG_IOMMU_IOVA) += iova.o
 obj-$(CONFIG_OF_IOMMU) += of_iommu.o
+obj-$(CONFIG_IOMMU_FWSPEC) += iommu-fwspec.o
 obj-$(CONFIG_MSM_IOMMU) += msm_iommu.o msm_iommu_dev.o
 obj-$(CONFIG_AMD_IOMMU) += amd_iommu.o amd_iommu_init.o
 obj-$(CONFIG_AMD_IOMMU_V2) += amd_iommu_v2.o
diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
index 98e6441..052a26c 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -25,6 +25,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -1739,9 +1740,13 @@ arm_smmu_iova_to_phys(struct iommu_domain *domain, 
dma_addr_t iova)
return ret;
 }
 
-static struct arm_smmu_device *arm_smmu_get_by_node(struct device_node *np)
+static struct arm_smmu_device *
+arm_smmu_get_by_fwnode(struct fwnode_handle *handle)
 {
-   struct platform_device *smmu_pdev = of_find_device_by_node(np);
+   struct platform_device *smmu_pdev = NULL;
+
+   if (is_of_node(handle))
+   smmu_pdev = of_find_device_by_node(to_of_node(handle));
 
if (!smmu_pdev)
return NULL;
@@ -1780,7 +1785,7 @@ static int arm_smmu_add_device(struct device *dev)
master = fwspec->iommu_priv;
smmu = master->smmu;
} else {
-   smmu = arm_smmu_get_by_node(fwspec->iommu_np);
+   smmu = arm_smmu_get_by_fwnode(fwspec->iommu_fwnode);
if (!smmu)
return -ENODEV;
master = kzalloc(sizeof(*master), GFP_KERNEL);
@@ -1892,7 +1897,7 @@ out_unlock:
 
 static int arm_smmu_of_xlate(struct device *dev, struct of_phandle_args *args)
 {
-   int ret = iommu_fwspec_init(dev, args->np);
+   int ret = iommu_fwspec_init(dev, >np->fwnode);
 
if (!ret)
ret = iommu_fwspec_add_ids(dev, >args[0], 1);
diff --git a/drivers/iommu/iommu-fwspec.c b/drivers/iommu/iommu-fwspec.c
new file mode 100644
index 000..0600c17
--- /dev/null
+++ b/drivers/iommu/iommu-fwspec.c
@@ -0,0 +1,114 @@
+/*
+ * Firmware handling helpers for IOMMU
+ *
+ * Copyright (c) 2016 ARM Ltd.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it 

[RFC PATCH v3 02/13] drivers: acpi: iort: introduce linker section for IORT entries probing

2016-07-20 Thread Lorenzo Pieralisi
Since commit e647b532275b ("ACPI: Add early device probing
infrastructure") the kernel has gained the infrastructure that allows
adding linker script section entries to execute ACPI driver callbacks
(ie probe routines) for all subsystems that register a table entry
in the respective kernel section (eg clocksource, irqchip).

Since ARM IOMMU devices data is described through IORT tables when
booting with ACPI, the ARM IOMMU drivers must be made able to hook ACPI
callback routines that are called to probe IORT entries and initialize
the respective IOMMU devices.

To avoid adding driver specific hooks into IORT table initialization
code (breaking therefore code modularity - ie ACPI IORT code must be made
aware of ARM SMMU drivers ACPI init callbacks), this patch adds code
that allows ARM SMMU drivers to take advantage of the ACPI early probing
infrastructure, so that they can add linker script section entries
containing drivers callback to be executed on IORT tables detection.

Since IORT nodes are differentiated by a type, the callback routines
can easily parse the IORT table entries, check the IORT nodes and
carry out some actions whenever the IORT node type associated with
the driver specific callback is matched.

Signed-off-by: Lorenzo Pieralisi <lorenzo.pieral...@arm.com>
Cc: Tomasz Nowicki <t...@semihalf.com>
Cc: "Rafael J. Wysocki" <r...@rjwysocki.net>
Cc: Marc Zyngier <marc.zyng...@arm.com>
---
 drivers/acpi/iort.c   | 2 ++
 include/asm-generic/vmlinux.lds.h | 1 +
 include/linux/iort.h  | 3 +++
 3 files changed, 6 insertions(+)

diff --git a/drivers/acpi/iort.c b/drivers/acpi/iort.c
index 6611607..1f440d2 100644
--- a/drivers/acpi/iort.c
+++ b/drivers/acpi/iort.c
@@ -383,4 +383,6 @@ void __init iort_table_detect(void)
const char *msg = acpi_format_exception(status);
pr_err("Failed to get table, %s\n", msg);
}
+
+   acpi_probe_device_table(iort);
 }
diff --git a/include/asm-generic/vmlinux.lds.h 
b/include/asm-generic/vmlinux.lds.h
index 6a67ab9..b896ab2 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -538,6 +538,7 @@
IRQCHIP_OF_MATCH_TABLE()\
ACPI_PROBE_TABLE(irqchip)   \
ACPI_PROBE_TABLE(clksrc)\
+   ACPI_PROBE_TABLE(iort)  \
EARLYCON_TABLE()
 
 #define INIT_TEXT  \
diff --git a/include/linux/iort.h b/include/linux/iort.h
index d7daba1..9bb30c5 100644
--- a/include/linux/iort.h
+++ b/include/linux/iort.h
@@ -38,4 +38,7 @@ static inline struct irq_domain *
 iort_get_device_domain(struct device *dev, u32 req_id) { return NULL; }
 #endif
 
+#define IORT_ACPI_DECLARE(name, table_id, fn)  \
+   ACPI_DECLARE_PROBE_ENTRY(iort, name, table_id, 0, NULL, 0, fn)
+
 #endif /* __IORT_H__ */
-- 
2.6.4



[RFC PATCH v3 00/13] ACPI IORT ARM SMMU v3 support

2016-07-20 Thread Lorenzo Pieralisi
This RFC patch series is v3 of a previous posting:

https://lkml.org/lkml/2016/6/7/523

v2 -> v3
- Rebased on top of dependencies series [1][2][3](v4.7-rc3)
- Added back reliance on ACPI early probing infrastructure
- Patch[1-3] merged through other dependent series
- Added back IOMMU fwnode generalization
- Move SMMU v3 static functions configuration to IORT code
- Implemented generic IOMMU fwspec API
- Added code to implement fwnode platform device look-up

v1 -> v2:
- Rebased on top of dependencies series [1][2][3](v4.7-rc1)
- Removed IOMMU fwnode generalization
- Implemented ARM SMMU v3 ACPI probing instead of ARM SMMU v2
  owing to patch series dependencies [1]
- Moved platform device creation logic to IORT code to
  generalize its usage for ARM SMMU v1-v2-v3 components
- Removed reliance on ACPI early device probing
- Created IORT specific iommu_xlate() translation hook leaving
  OF code unchanged according to v1 reviews

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, available through [2]:

this patchset enables ARM SMMU v3 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.

PATCH (1) adds a FWNODE_IOMMU type to the struct fwnode_handle type.
  It is required to attach a fwnode identifier to platform
  devices allocated/detected through IORT tables entries;
  IOMMU devices have to have an identifier to look them up
  eg IOMMU core layer carrying out id translation. This can be
  done through a fwnode_handle (ie IOMMU platform devices created
  out of IORT tables are not ACPI devices hence they can't be
  allocated as such, otherwise they would have a fwnode_handle of
  type FWNODE_ACPI). This patch requires discussion and it is key
  to the RFC.

PATCH (2) makes use of the ACPI early probing API to add a linker script
  section for probing devices via IORT ACPI kernel code.

PATCH (3) provides IORT support for registering IOMMU IORT node through
  their fwnode handle.

PATCH (4) implements core code fwnode based platform devices look-up.

PATCH (5) extends iommu_fwspec so that it can be used on ACPI based
  system by creating a generic IOMMU fwspec kernel layer.

PATCH (6) implements the of_dma_configure() API in ACPI world -
  acpi_dma_configure() - and patches PCI and ACPI core code to
  start making use of it.

PATCH (7) provides an IORT function to detect existence of specific type
  of IORT components.

PATCH (8) creates the kernel infrastructure required to create ARM SMMU
  platform devices for IORT nodes.

PATCH (9) refactors the ARM SMMU v3 driver so that the init functions are
  split in a way that groups together code that probes through DT
  and code that carries out HW registers FW agnostic probing, in
  preparation for adding the ACPI probing path.

PATCH (10) rework ARM SMMU v3 platform driver registration to make it work
   on ACPI systems.

PATCH (11) Building on patch (8), it adds ARM SMMU v3 IORT IOMMU
   operations to create and probe ARM SMMU v3 components.

PATCH (12) Extend the IORT iort_node_map_rid() to work on a type mask
   instead of a single type so that the translation API can
   be used on a range of components.

PATCH (13) provides IORT infrastructure to carry out IOMMU configuration
   for devices and hook it up to the previously introduced ACPI
   DMA configure API.

This patchset is built on top and depends on these three patch series:

[1] R.Murphy "Generic DT bindings for PCI and ARM SMMU v3" v4
https://marc.info/?l=devicetree=146739193215518=2

[2] T.Nowicki "Introduce ACPI world to ITS irqchip" v7
https://marc.info/?l=linux-arm-kernel=146642080022289=2

[3] T.Nowicki "Support for ARM64 ACPI based PCI host controller" v8
http://marc.info/?l=linux-acpi=146462129816292=2

and is provided for early review/testing purposes here:

git://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/linux.git 
acpi/iort-smmu-v3

Tested on FVP models for ARM SMMU v3 probing path.

Lorenzo Pieralisi (13):
  drivers: iommu: add FWNODE_IOMMU fwnode type
  drivers: acpi: iort: introduce linker section for IORT entries probing
  drivers: acpi: iort: add support for IOMMU fwnode registration
  drivers: platform: add fwnode base 

[RFC PATCH v3 07/13] drivers: acpi: iort: add node match function

2016-07-20 Thread Lorenzo Pieralisi
Device drivers (eg ARM SMMU) need to know if a specific component
is part of the IORT table, so that kernel data structures are not
initialized at initcalls time if the respective component is not
part of the IORT table.

To this end, this patch adds a trivial function that allows detecting
if a given IORT node type is present or not in the ACPI table, providing
an ACPI IORT equivalent for of_find_matching_node().

Signed-off-by: Lorenzo Pieralisi <lorenzo.pieral...@arm.com>
Cc: Hanjun Guo <hanjun@linaro.org>
Cc: Tomasz Nowicki <t...@semihalf.com>
Cc: "Rafael J. Wysocki" <r...@rjwysocki.net>
---
 drivers/acpi/iort.c  | 15 +++
 include/linux/iort.h |  2 ++
 2 files changed, 17 insertions(+)

diff --git a/drivers/acpi/iort.c b/drivers/acpi/iort.c
index 86f6985..71516e8 100644
--- a/drivers/acpi/iort.c
+++ b/drivers/acpi/iort.c
@@ -205,6 +205,21 @@ iort_scan_node(enum acpi_iort_node_type type,
 }
 
 static acpi_status
+iort_match_callback(struct acpi_iort_node *node, void *context)
+{
+   return AE_OK;
+}
+
+bool iort_node_match(u8 type)
+{
+   struct acpi_iort_node *node;
+
+   node = iort_scan_node(type, iort_match_callback, NULL);
+
+   return node != NULL;
+}
+
+static acpi_status
 iort_match_node_callback(struct acpi_iort_node *node, void *context)
 {
struct device *dev = context;
diff --git a/include/linux/iort.h b/include/linux/iort.h
index 9bb30c5..ac2706a 100644
--- a/include/linux/iort.h
+++ b/include/linux/iort.h
@@ -27,10 +27,12 @@ int iort_register_domain_token(int trans_id, struct 
fwnode_handle *fw_node);
 void iort_deregister_domain_token(int trans_id);
 struct fwnode_handle *iort_find_domain_token(int trans_id);
 #ifdef CONFIG_IORT_TABLE
+bool iort_node_match(u8 type);
 void iort_table_detect(void);
 u32 iort_msi_map_rid(struct device *dev, u32 req_id);
 struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_id);
 #else
+static inline bool iort_node_match(u8 type) { return false; }
 static inline void iort_table_detect(void) { }
 static inline u32 iort_msi_map_rid(struct device *dev, u32 req_id)
 { return req_id; }
-- 
2.6.4



[RFC PATCH v3 06/13] drivers: acpi: implement acpi_dma_configure

2016-07-20 Thread Lorenzo Pieralisi
On DT based systems, the of_dma_configure() API implements DMA
configuration for a given device. On ACPI systems an API equivalent to
of_dma_configure() is missing which implies that it is currently not
possible to set-up DMA operations for devices through the ACPI generic
kernel layer.

This patch fills the gap by introducing acpi_dma_configure/deconfigure()
calls that for now are just wrappers around arch_setup_dma_ops() and
arch_teardown_dma_ops() and also updates ACPI and PCI core code to use
the newly introduced acpi_dma_configure/acpi_dma_deconfigure functions.

The DMA range size passed to arch_setup_dma_ops() is sized according
to the device coherent_dma_mask (starting at address 0x0), mirroring the
DT probing path behaviour when a dma-ranges property is not provided
for the device being probed; this changes the current arch_setup_dma_ops()
call parameters in the ACPI probing case, but since arch_setup_dma_ops()
is a NOP on all architectures but ARM/ARM64 this patch does not change
the current kernel behaviour on them.

Signed-off-by: Lorenzo Pieralisi <lorenzo.pieral...@arm.com>
Acked-by: Bjorn Helgaas <bhelg...@google.com> [pci]
Cc: Bjorn Helgaas <bhelg...@google.com>
Cc: Robin Murphy <robin.mur...@arm.com>
Cc: Tomasz Nowicki <t...@semihalf.com>
Cc: Joerg Roedel <j...@8bytes.org>
Cc: "Rafael J. Wysocki" <r...@rjwysocki.net>
---
 drivers/acpi/glue.c |  4 ++--
 drivers/acpi/scan.c | 24 
 drivers/pci/probe.c |  3 +--
 include/acpi/acpi_bus.h |  2 ++
 include/linux/acpi.h|  5 +
 5 files changed, 34 insertions(+), 4 deletions(-)

diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index 5ea5dc2..f8d6564 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -227,8 +227,7 @@ int acpi_bind_one(struct device *dev, struct acpi_device 
*acpi_dev)
 
attr = acpi_get_dma_attr(acpi_dev);
if (attr != DEV_DMA_NOT_SUPPORTED)
-   arch_setup_dma_ops(dev, 0, 0, NULL,
-  attr == DEV_DMA_COHERENT);
+   acpi_dma_configure(dev, attr);
 
acpi_physnode_link_name(physical_node_name, node_id);
retval = sysfs_create_link(_dev->dev.kobj, >kobj,
@@ -251,6 +250,7 @@ int acpi_bind_one(struct device *dev, struct acpi_device 
*acpi_dev)
return 0;
 
  err:
+   acpi_dma_deconfigure(dev);
ACPI_COMPANION_SET(dev, NULL);
put_device(dev);
put_device(_dev->dev);
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 5f28cf7..b4b9064 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1358,6 +1358,30 @@ enum dev_dma_attr acpi_get_dma_attr(struct acpi_device 
*adev)
return DEV_DMA_NON_COHERENT;
 }
 
+/**
+ * acpi_dma_configure - Set-up DMA configuration for the device.
+ * @dev: The pointer to the device
+ * @attr: device dma attributes
+ */
+void acpi_dma_configure(struct device *dev, enum dev_dma_attr attr)
+{
+   /*
+* Assume dma valid range starts at 0 and covers the whole
+* coherent_dma_mask.
+*/
+   arch_setup_dma_ops(dev, 0, dev->coherent_dma_mask + 1, NULL,
+  attr == DEV_DMA_COHERENT);
+}
+
+/**
+ * acpi_dma_deconfigure - Tear-down DMA configuration for the device.
+ * @dev: The pointer to the device
+ */
+void acpi_dma_deconfigure(struct device *dev)
+{
+   arch_teardown_dma_ops(dev);
+}
+
 static void acpi_init_coherency(struct acpi_device *adev)
 {
unsigned long long cca = 0;
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 380d46d..7ef3933 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1725,8 +1725,7 @@ static void pci_dma_configure(struct pci_dev *dev)
if (attr == DEV_DMA_NOT_SUPPORTED)
dev_warn(>dev, "DMA not supported.\n");
else
-   arch_setup_dma_ops(>dev, 0, 0, NULL,
-  attr == DEV_DMA_COHERENT);
+   acpi_dma_configure(>dev, attr);
}
 
pci_put_host_bridge_device(bridge);
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index 788c6c35..8b5039a 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -566,6 +566,8 @@ struct acpi_pci_root {
 
 bool acpi_dma_supported(struct acpi_device *adev);
 enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev);
+void acpi_dma_configure(struct device *dev, enum dev_dma_attr attr);
+void acpi_dma_deconfigure(struct device *dev);
 
 struct acpi_device *acpi_find_child_device(struct acpi_device *parent,
   u64 address, bool check_children);
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 288fac5..135a452 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -676,6 +676,11 @@ static inline enum dev_dma_attr acpi_get_dma_attr(struct 
acpi_device *adev)
 

[RFC PATCH v3 03/13] drivers: acpi: iort: add support for IOMMU fwnode registration

2016-07-20 Thread Lorenzo Pieralisi
The ACPI IORT table provide entries for IOMMU (aka SMMU in ARM world)
components that allow creating the kernel data structures required to
probe and initialize the IOMMU devices.

This patch provides support in the IORT kernel code to register IOMMU
components and their respective fwnode.

Signed-off-by: Lorenzo Pieralisi <lorenzo.pieral...@arm.com>
Cc: Hanjun Guo <hanjun@linaro.org>
Cc: Tomasz Nowicki <t...@semihalf.com>
Cc: "Rafael J. Wysocki" <r...@rjwysocki.net>
---
 drivers/acpi/iort.c | 65 +
 1 file changed, 65 insertions(+)

diff --git a/drivers/acpi/iort.c b/drivers/acpi/iort.c
index 1f440d2..86f6985 100644
--- a/drivers/acpi/iort.c
+++ b/drivers/acpi/iort.c
@@ -20,7 +20,9 @@
 
 #include 
 #include 
+#include 
 #include 
+#include 
 
 struct iort_its_msi_chip {
struct list_headlist;
@@ -28,6 +30,69 @@ struct iort_its_msi_chip {
u32 translation_id;
 };
 
+struct iort_fwnode {
+   struct list_head list;
+   struct acpi_iort_node *iort_node;
+   struct fwnode_handle *fwnode;
+};
+static LIST_HEAD(iort_fwnode_list);
+static DEFINE_SPINLOCK(iort_fwnode_lock);
+
+/**
+ * iort_set_fwnode() - Create iort_fwnode and use it to register
+ *iommu data in the iort_fwnode_list
+ *
+ * @node: IORT table node associated with the IOMMU
+ * @fwnode: fwnode associated with the IORT node
+ *
+ * Returns: 0 on success
+ *  -ENOMEM on failure
+ */
+static inline int iort_set_fwnode(struct acpi_iort_node *iort_node,
+ struct fwnode_handle *fwnode)
+{
+   struct iort_fwnode *np;
+
+   np = kzalloc(sizeof(struct iort_fwnode), GFP_KERNEL);
+
+   if (WARN_ON(!np))
+   return -ENOMEM;
+
+   INIT_LIST_HEAD(>list);
+   np->iort_node = iort_node;
+   np->fwnode = fwnode;
+
+   spin_lock(_fwnode_lock);
+   list_add_tail(>list, _fwnode_list);
+   spin_unlock(_fwnode_lock);
+
+   return 0;
+}
+
+/**
+ * iort_get_fwnode() - Retrieve fwnode associated with an IORT node
+ *
+ * @node: IORT table node to be looked-up
+ *
+ * Returns: fwnode_handle pointer on success NULL on failure
+*/
+static inline struct fwnode_handle *
+iort_get_fwnode(struct acpi_iort_node *node)
+{
+   struct iort_fwnode *curr, *iommu_fwnode = NULL;
+
+   spin_lock(_fwnode_lock);
+   list_for_each_entry(curr, _fwnode_list, list) {
+   if (curr->iort_node == node) {
+   iommu_fwnode = curr;
+   break;
+   }
+   }
+   spin_unlock(_fwnode_lock);
+
+   return iommu_fwnode ? iommu_fwnode->fwnode : NULL;
+}
+
 typedef acpi_status (*iort_find_node_callback)
(struct acpi_iort_node *node, void *context);
 
-- 
2.6.4



[RFC PATCH v3 11/13] drivers: iommu: arm-smmu-v3: add IORT platform device creation

2016-07-20 Thread Lorenzo Pieralisi
In ACPI bases systems, in order to be able to create platform
devices and initialize them for ARM SMMU v3 components, the IORT
kernel implementation requires a set of static functions to be
used by the IORT kernel layer to configure platform devices for
ARM SMMU v3 components.

Add static configuration functions to the IORT kernel layer for
the ARM SMMU v3 components, so that the ARM SMMU v3 driver can
initialize its respective platform device by relying on the IORT
kernel infrastructure and by adding a corresponding ACPI device
early probe section entry.

Signed-off-by: Lorenzo Pieralisi <lorenzo.pieral...@arm.com>
Cc: Will Deacon <will.dea...@arm.com>
Cc: Robin Murphy <robin.mur...@arm.com>
Cc: Joerg Roedel <j...@8bytes.org>
---
 drivers/acpi/iort.c | 98 -
 drivers/iommu/arm-smmu-v3.c | 58 +++
 2 files changed, 155 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/iort.c b/drivers/acpi/iort.c
index 23c80c7..c91e45d 100644
--- a/drivers/acpi/iort.c
+++ b/drivers/acpi/iort.c
@@ -455,6 +455,90 @@ iort_get_device_domain(struct device *dev, u32 req_id)
return irq_find_matching_fwnode(handle, DOMAIN_BUS_PCI_MSI);
 }
 
+static void acpi_smmu_v3_register_irq(int hwirq, const char *name,
+ struct resource *res)
+{
+   int irq = acpi_register_gsi(NULL, hwirq, ACPI_EDGE_SENSITIVE,
+   ACPI_ACTIVE_HIGH);
+
+   if (irq < 0) {
+   pr_err("could not register gsi hwirq %d name [%s]\n", hwirq,
+ name);
+   return;
+   }
+
+   res->start = irq;
+   res->end = irq;
+   res->flags = IORESOURCE_IRQ;
+   res->name = name;
+}
+
+static int arm_smmu_v3_count_resources(struct acpi_iort_node *node)
+{
+   struct acpi_iort_smmu_v3 *smmu;
+   /* Always present mem resource */
+   int num_res = 1;
+
+   /* Retrieve SMMUv3 specific data */
+   smmu = (struct acpi_iort_smmu_v3 *)node->node_data;
+
+   if (smmu->event_gsiv)
+   num_res++;
+
+   if (smmu->pri_gsiv)
+   num_res++;
+
+   if (smmu->gerr_gsiv)
+   num_res++;
+
+   if (smmu->sync_gsiv)
+   num_res++;
+
+   return num_res;
+}
+
+static void arm_smmu_v3_init_resources(struct resource *res,
+  struct acpi_iort_node *node)
+{
+   struct acpi_iort_smmu_v3 *smmu;
+   int num_res = 0;
+
+   /* Retrieve SMMUv3 specific data */
+   smmu = (struct acpi_iort_smmu_v3 *)node->node_data;
+
+   res[num_res].start = smmu->base_address;
+   res[num_res].end = smmu->base_address + SZ_128K - 1;
+   res[num_res].flags = IORESOURCE_MEM;
+
+   num_res++;
+
+   if (smmu->event_gsiv)
+   acpi_smmu_v3_register_irq(smmu->event_gsiv, "eventq",
+ [num_res++]);
+
+   if (smmu->pri_gsiv)
+   acpi_smmu_v3_register_irq(smmu->pri_gsiv, "priq",
+  [num_res++]);
+
+   if (smmu->gerr_gsiv)
+   acpi_smmu_v3_register_irq(smmu->gerr_gsiv, "gerror",
+ [num_res++]);
+
+   if (smmu->sync_gsiv)
+   acpi_smmu_v3_register_irq(smmu->sync_gsiv, "cmdq-sync",
+ [num_res++]);
+}
+
+static bool arm_smmu_v3_is_coherent(struct acpi_iort_node *node)
+{
+   struct acpi_iort_smmu_v3 *smmu;
+
+   /* Retrieve SMMUv3 specific data */
+   smmu = (struct acpi_iort_smmu_v3 *)node->node_data;
+
+   return smmu->flags & ACPI_IORT_SMMU_V3_COHACC_OVERRIDE;
+}
+
 struct iort_iommu_config {
const char *name;
int (*iommu_init)(struct acpi_iort_node *node);
@@ -464,10 +548,22 @@ struct iort_iommu_config {
 struct acpi_iort_node *node);
 };
 
+const struct iort_iommu_config iort_arm_smmu_v3_cfg = {
+   .name = "arm-smmu-v3",
+   .iommu_is_coherent = arm_smmu_v3_is_coherent,
+   .iommu_count_resources = arm_smmu_v3_count_resources,
+   .iommu_init_resources = arm_smmu_v3_init_resources
+};
+
 static inline const struct iort_iommu_config *
 iort_get_iommu_config(struct acpi_iort_node *node)
 {
-   return NULL;
+   switch (node->type) {
+   case ACPI_IORT_NODE_SMMU_V3:
+   return _arm_smmu_v3_cfg;
+   default:
+   return NULL;
+   }
 }
 
 /**
diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
index 1a4e9ce..294ed5e 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -1749,6 +1749,8 @@ arm_smmu_get_by_fwnode(struct fwnode_handle *handle)
 
if 

[RFC PATCH v3 09/13] drivers: iommu: arm-smmu-v3: split probe functions into DT/generic portions

2016-07-20 Thread Lorenzo Pieralisi
Current ARM SMMUv3 probe functions intermingle HW and DT probing in the
initialization functions to detect and programme the ARM SMMU v3 driver
features. In order to allow probing the ARM SMMUv3 with other firmwares
than DT, this patch splits the ARM SMMUv3 init functions into DT and HW
specific portions so that other FW interfaces (ie ACPI) can reuse the HW
probing functions and skip the DT portion accordingly.

This patch implements no functional change, only code reshuffling.

Signed-off-by: Lorenzo Pieralisi <lorenzo.pieral...@arm.com>
Acked-by: Will Deacon <will.dea...@arm.com>
Cc: Will Deacon <will.dea...@arm.com>
Cc: Hanjun Guo <hanjun@linaro.org>
Cc: Robin Murphy <robin.mur...@arm.com>
Cc: Joerg Roedel <j...@8bytes.org>
---
 drivers/iommu/arm-smmu-v3.c | 63 +
 1 file changed, 52 insertions(+), 11 deletions(-)

diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
index 052a26c..15e74da 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -20,6 +20,7 @@
  * This driver is powered by bad coffee and bombay mix.
  */
 
+#include 
 #include 
 #include 
 #include 
@@ -27,6 +28,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -2377,10 +2379,10 @@ static int arm_smmu_device_reset(struct arm_smmu_device 
*smmu)
return 0;
 }
 
-static int arm_smmu_device_probe(struct arm_smmu_device *smmu)
+static int arm_smmu_device_hw_probe(struct arm_smmu_device *smmu)
 {
u32 reg;
-   bool coherent;
+   bool coherent = smmu->features & ARM_SMMU_FEAT_COHERENCY;
 
/* IDR0 */
reg = readl_relaxed(smmu->base + ARM_SMMU_IDR0);
@@ -2432,13 +2434,9 @@ static int arm_smmu_device_probe(struct arm_smmu_device 
*smmu)
smmu->features |= ARM_SMMU_FEAT_HYP;
 
/*
-* The dma-coherent property is used in preference to the ID
+* The coherency feature as set by FW is used in preference to the ID
 * register, but warn on mismatch.
 */
-   coherent = of_dma_is_coherent(smmu->dev->of_node);
-   if (coherent)
-   smmu->features |= ARM_SMMU_FEAT_COHERENCY;
-
if (!!(reg & IDR0_COHACC) != coherent)
dev_warn(smmu->dev, "IDR0.COHACC overridden by dma-coherent 
property (%s)\n",
 coherent ? "true" : "false");
@@ -2559,7 +2557,44 @@ static int arm_smmu_device_probe(struct arm_smmu_device 
*smmu)
return 0;
 }
 
-static int arm_smmu_device_dt_probe(struct platform_device *pdev)
+#ifdef CONFIG_ACPI
+static int arm_smmu_device_acpi_probe(struct platform_device *pdev,
+ struct arm_smmu_device *smmu)
+{
+   struct acpi_iort_smmu_v3 *iort_smmu;
+   struct device *dev = smmu->dev;
+   struct acpi_iort_node *node;
+
+   node = *(struct acpi_iort_node **)dev_get_platdata(dev);
+
+   /* Retrieve SMMUv3 specific data */
+   iort_smmu = (struct acpi_iort_smmu_v3 *)node->node_data;
+
+   if (iort_smmu->flags & ACPI_IORT_SMMU_V3_COHACC_OVERRIDE)
+   smmu->features |= ARM_SMMU_FEAT_COHERENCY;
+
+   return 0;
+}
+#else
+static int arm_smmu_device_acpi_probe(struct platform_device *pdev,
+ struct arm_smmu_device *smmu)
+{
+   return -ENODEV;
+}
+#endif
+
+static int arm_smmu_device_dt_probe(struct platform_device *pdev,
+   struct arm_smmu_device *smmu)
+{
+   parse_driver_options(smmu);
+
+   if (of_dma_is_coherent(smmu->dev->of_node))
+   smmu->features |= ARM_SMMU_FEAT_COHERENCY;
+
+   return 0;
+}
+
+static int arm_smmu_device_probe(struct platform_device *pdev)
 {
int irq, ret;
struct resource *res;
@@ -2601,10 +2636,16 @@ static int arm_smmu_device_dt_probe(struct 
platform_device *pdev)
if (irq > 0)
smmu->gerr_irq = irq;
 
-   parse_driver_options(smmu);
+   if (acpi_disabled)
+   ret = arm_smmu_device_dt_probe(pdev, smmu);
+   else
+   ret = arm_smmu_device_acpi_probe(pdev, smmu);
+
+   if (ret)
+   return ret;
 
/* Probe the h/w */
-   ret = arm_smmu_device_probe(smmu);
+   ret = arm_smmu_device_hw_probe(smmu);
if (ret)
return ret;
 
@@ -2639,7 +2680,7 @@ static struct platform_driver arm_smmu_driver = {
.name   = "arm-smmu-v3",
.of_match_table = of_match_ptr(arm_smmu_of_match),
},
-   .probe  = arm_smmu_device_dt_probe,
+   .probe  = arm_smmu_device_probe,
.remove = arm_smmu_device_remove,
 };
 
-- 
2.6.4



[RFC PATCH v3 12/13] drivers: acpi: iort: replace rid map type with type mask

2016-07-20 Thread Lorenzo Pieralisi
IORT tables provide data that allow the kernel to carry out
device ID mappings between endpoints and system components
(eg interrupt controllers, IOMMUs). When the mapping for a
given device ID is carried out, the translation mechanism
is done on a per-subsystem basis rather than a component
subtype (ie the IOMMU kernel layer will look for mappings
from a device to all IORT node types corresponding to IOMMU
components), therefore the corresponding mapping API should
work on a range (ie mask) of IORT node types corresponding
to a common set of components (eg IOMMUs) rather than a
specific node type.

Upgrade the IORT iort_node_map_rid() API to work with a
type mask instead of a single node type so that it can
be used for mappings that span multiple components types
(ie IOMMUs).

Signed-off-by: Lorenzo Pieralisi <lorenzo.pieral...@arm.com>
Cc: Hanjun Guo <hanjun@linaro.org>
Cc: Tomasz Nowicki <t...@semihalf.com>
Cc: "Rafael J. Wysocki" <r...@rjwysocki.net>
---
 drivers/acpi/iort.c | 11 +++
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/acpi/iort.c b/drivers/acpi/iort.c
index c91e45d..c116b68 100644
--- a/drivers/acpi/iort.c
+++ b/drivers/acpi/iort.c
@@ -25,6 +25,9 @@
 #include 
 #include 
 
+#define IORT_TYPE_MASK(type)   (1 << (type))
+#define IORT_MSI_TYPE  (1 << ACPI_IORT_NODE_ITS_GROUP)
+
 struct iort_its_msi_chip {
struct list_headlist;
struct fwnode_handle*fw_node;
@@ -299,7 +302,7 @@ iort_id_map(struct acpi_iort_id_mapping *map, u8 type, u32 
rid_in, u32 *rid_out)
 
 static struct acpi_iort_node *
 iort_node_map_rid(struct acpi_iort_node *node, u32 rid_in,
- u32 *rid_out, u8 type)
+ u32 *rid_out, u8 type_mask)
 {
u32 rid = rid_in;
 
@@ -308,7 +311,7 @@ iort_node_map_rid(struct acpi_iort_node *node, u32 rid_in,
struct acpi_iort_id_mapping *map;
int i;
 
-   if (node->type == type) {
+   if (IORT_TYPE_MASK(node->type) & type_mask) {
if (rid_out)
*rid_out = rid;
return node;
@@ -386,7 +389,7 @@ u32 iort_msi_map_rid(struct device *dev, u32 req_id)
return req_id;
}
 
-   iort_node_map_rid(node, req_id, _id, ACPI_IORT_NODE_ITS_GROUP);
+   iort_node_map_rid(node, req_id, _id, IORT_MSI_TYPE);
return dev_id;
 }
 
@@ -411,7 +414,7 @@ iort_dev_find_its_id(struct device *dev, u32 req_id, 
unsigned int idx,
return -ENXIO;
}
 
-   node = iort_node_map_rid(node, req_id, NULL, ACPI_IORT_NODE_ITS_GROUP);
+   node = iort_node_map_rid(node, req_id, NULL, IORT_MSI_TYPE);
if (!node) {
dev_err(dev, "can't find related ITS node\n");
return -ENXIO;
-- 
2.6.4



[RFC PATCH v3 10/13] drivers: iommu: arm-smmu-v3: enable ACPI driver initialization

2016-07-20 Thread Lorenzo Pieralisi
On systems booting with ACPI that enable the ARM SMMU components
in the kernel config options, the ARM SMMU v3 init function
(ie arm_smmu_init(), that registers the driver and sets-up bus
iommu operations) does not run only because the device tree interface
(of_find_matching_node()) fails to find the respective device tree
nodes for ARM SMMU devices.

This works as long as there are no ARM SMMU devices to be probed
with ACPI. If ARM SMMU v3 components are part of the IORT tables,
for them to be instantiated and probed the function registering
the ARM SMMU v3 driver must be able to register the driver and
initialize the bus IOMMU operations accordingly.

This patch changes the logic in arm-smmu-v3 init call to allow
for it to be probed in ACPI systems.

Signed-off-by: Lorenzo Pieralisi <lorenzo.pieral...@arm.com>
Acked-by: Will Deacon <will.dea...@arm.com>
Cc: Will Deacon <will.dea...@arm.com>
Cc: Robin Murphy <robin.mur...@arm.com>
Cc: Joerg Roedel <j...@8bytes.org>
---
 drivers/iommu/arm-smmu-v3.c | 13 +
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
index 15e74da..1a4e9ce 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -2689,11 +2689,16 @@ static int __init arm_smmu_init(void)
struct device_node *np;
int ret;
 
-   np = of_find_matching_node(NULL, arm_smmu_of_match);
-   if (!np)
-   return 0;
+   if (acpi_disabled) {
+   np = of_find_matching_node(NULL, arm_smmu_of_match);
+   if (!np)
+   return 0;
 
-   of_node_put(np);
+   of_node_put(np);
+   } else {
+   if (!iort_node_match(ACPI_IORT_NODE_SMMU_V3))
+   return 0;
+   }
 
ret = platform_driver_register(_smmu_driver);
if (ret)
-- 
2.6.4



[RFC PATCH v3 13/13] drivers: acpi: iort: introduce iort_iommu_configure

2016-07-20 Thread Lorenzo Pieralisi
DT based systems have a generic kernel API to configure IOMMUs
for devices (ie of_iommu_configure()).

On ARM based ACPI systems, the of_iommu_configure() equivalent can
be implemented atop ACPI IORT kernel API, with the corresponding
functions to map device identifiers to IOMMUs and retrieve the
corresponding IOMMU operations necessary for DMA operations set-up.

By relying on the iommu_fwspec generic kernel infrastructure,
implement the IORT based IOMMU configuration for ARM ACPI systems
and hook it up in the ACPI kernel layer that implements DMA
configuration for a device.

Signed-off-by: Lorenzo Pieralisi <lorenzo.pieral...@arm.com>
Cc: Hanjun Guo <hanjun@linaro.org>
Cc: Tomasz Nowicki <t...@semihalf.com>
Cc: "Rafael J. Wysocki" <r...@rjwysocki.net>
---
 drivers/acpi/iort.c  | 64 
 drivers/acpi/scan.c  |  7 +-
 include/linux/iort.h |  4 
 3 files changed, 74 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/iort.c b/drivers/acpi/iort.c
index c116b68..a12a4ff 100644
--- a/drivers/acpi/iort.c
+++ b/drivers/acpi/iort.c
@@ -18,6 +18,7 @@
 
 #define pr_fmt(fmt)"ACPI: IORT: " fmt
 
+#include 
 #include 
 #include 
 #include 
@@ -27,6 +28,8 @@
 
 #define IORT_TYPE_MASK(type)   (1 << (type))
 #define IORT_MSI_TYPE  (1 << ACPI_IORT_NODE_ITS_GROUP)
+#define IORT_IOMMU_TYPE((1 << ACPI_IORT_NODE_SMMU) |   \
+   (1 << ACPI_IORT_NODE_SMMU_V3))
 
 struct iort_its_msi_chip {
struct list_headlist;
@@ -458,6 +461,67 @@ iort_get_device_domain(struct device *dev, u32 req_id)
return irq_find_matching_fwnode(handle, DOMAIN_BUS_PCI_MSI);
 }
 
+static int __get_pci_rid(struct pci_dev *pdev, u16 alias, void *data)
+{
+   u32 *rid = data;
+
+   *rid = alias;
+   return 0;
+}
+
+static int arm_smmu_iort_xlate(struct device *dev, u32 streamid,
+  struct fwnode_handle *fwnode)
+{
+   int ret = iommu_fwspec_init(dev, fwnode);
+
+   if (!ret)
+   ret = iommu_fwspec_add_ids(dev, , 1);
+
+   return 0;
+}
+
+/**
+ * iort_iommu_configure - Set-up IOMMU configuration for a device.
+ *
+ * @dev: device to configure
+ *
+ * Returns: iommu_ops pointer on configuration success
+ *  NULL on configuration failure
+ */
+const struct iommu_ops *iort_iommu_configure(struct device *dev)
+{
+   struct acpi_iort_node *node, *parent;
+   struct fwnode_handle *iort_fwnode;
+   u32 rid = 0, devid = 0;
+
+   if (dev_is_pci(dev)) {
+   struct pci_bus *bus = to_pci_dev(dev)->bus;
+
+   pci_for_each_dma_alias(to_pci_dev(dev), __get_pci_rid,
+  );
+
+   node = iort_scan_node(ACPI_IORT_NODE_PCI_ROOT_COMPLEX,
+ iort_match_node_callback, >dev);
+   } else {
+   node = iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT,
+ iort_match_node_callback, dev);
+   }
+
+   if (!node)
+   return NULL;
+
+   parent = iort_node_map_rid(node, rid, , IORT_IOMMU_TYPE);
+   if (parent) {
+   iort_fwnode = iort_get_fwnode(parent);
+   if (iort_fwnode) {
+   arm_smmu_iort_xlate(dev, devid, iort_fwnode);
+   return fwspec_iommu_get_ops(iort_fwnode);
+   }
+   }
+
+   return NULL;
+}
+
 static void acpi_smmu_v3_register_irq(int hwirq, const char *name,
  struct resource *res)
 {
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index b4b9064..de28825 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -7,6 +7,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -1365,11 +1366,15 @@ enum dev_dma_attr acpi_get_dma_attr(struct acpi_device 
*adev)
  */
 void acpi_dma_configure(struct device *dev, enum dev_dma_attr attr)
 {
+   const struct iommu_ops *iommu;
+
+   iommu = iort_iommu_configure(dev);
+
/*
 * Assume dma valid range starts at 0 and covers the whole
 * coherent_dma_mask.
 */
-   arch_setup_dma_ops(dev, 0, dev->coherent_dma_mask + 1, NULL,
+   arch_setup_dma_ops(dev, 0, dev->coherent_dma_mask + 1, iommu,
   attr == DEV_DMA_COHERENT);
 }
 
diff --git a/include/linux/iort.h b/include/linux/iort.h
index 18e6836..bbe08ef 100644
--- a/include/linux/iort.h
+++ b/include/linux/iort.h
@@ -34,6 +34,8 @@ struct irq_domain *iort_get_device_domain(struct device *dev, 
u32 req_id);
 /* IOMMU interface */
 int iort_add_smmu_platform_device(struct fwnode_handle *fwnode,
  struct acpi_iort_node *node);
+
+const struct iommu_ops *iort_iommu_configure(struct device *dev);
 #else
 static inline bool iort_node_match(u8 type) 

[RFC PATCH v3 01/13] drivers: iommu: add FWNODE_IOMMU fwnode type

2016-07-20 Thread Lorenzo Pieralisi
On systems booting with a device tree, every struct device is
associated with a struct device_node, that represents its DT
representation. The device node can be used in generic kernel
contexts (eg IRQ translation, IOMMU streamid mapping), to
retrieve the properties associated with the device and carry
out kernel operation accordingly. Owing to the 1:1 relationship
between the device and its device_node, the device_node can also
be used as a look-up token for the device (eg looking up a device
through its device_node), to retrieve the device in kernel paths
where the device_node is available.

On systems booting with ACPI, the same abstraction provided by
the device_node is required to provide look-up functionality.

Therefore, mirroring the approach implemented in the IRQ domain
kernel layer, this patch adds an additional fwnode type FWNODE_IOMMU.

This patch also implements a glue kernel layer that allows to
allocate/free FWNODE_IOMMU fwnode_handle structures and associate
them with IOMMU devices.

Signed-off-by: Lorenzo Pieralisi <lorenzo.pieral...@arm.com>
Cc: Joerg Roedel <j...@8bytes.org>
Cc: "Rafael J. Wysocki" <r...@rjwysocki.net>
---
 include/linux/fwnode.h |  1 +
 include/linux/iommu.h  | 25 +
 2 files changed, 26 insertions(+)

diff --git a/include/linux/fwnode.h b/include/linux/fwnode.h
index 8516717..6e10050 100644
--- a/include/linux/fwnode.h
+++ b/include/linux/fwnode.h
@@ -19,6 +19,7 @@ enum fwnode_type {
FWNODE_ACPI_DATA,
FWNODE_PDATA,
FWNODE_IRQCHIP,
+   FWNODE_IOMMU,
 };
 
 struct fwnode_handle {
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 664683a..298328a 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -38,6 +38,7 @@ struct bus_type;
 struct device;
 struct iommu_domain;
 struct notifier_block;
+struct fwnode_handle;
 
 /* iommu fault flags */
 #define IOMMU_FAULT_READ   0x0
@@ -540,4 +541,28 @@ static inline void iommu_device_unlink(struct device *dev, 
struct device *link)
 
 #endif /* CONFIG_IOMMU_API */
 
+/* IOMMU fwnode handling */
+static inline bool is_fwnode_iommu(struct fwnode_handle *fwnode)
+{
+   return fwnode && fwnode->type == FWNODE_IOMMU;
+}
+
+static inline struct fwnode_handle *iommu_alloc_fwnode(void)
+{
+   struct fwnode_handle *fwnode;
+
+   fwnode = kzalloc(sizeof(struct fwnode_handle), GFP_KERNEL);
+   fwnode->type = FWNODE_IOMMU;
+
+   return fwnode;
+}
+
+static inline void iommu_free_fwnode(struct fwnode_handle *fwnode)
+{
+   if (WARN_ON(!is_fwnode_iommu(fwnode)))
+   return;
+
+   kfree(fwnode);
+}
+
 #endif /* __LINUX_IOMMU_H */
-- 
2.6.4



[RFC PATCH v3 08/13] drivers: acpi: iort: add support for ARM SMMU platform devices creation

2016-07-20 Thread Lorenzo Pieralisi
In ARM ACPI systems, IOMMU components are specified through static
IORT table entries. In order to create platform devices for the
corresponding ARM SMMU components, IORT kernel code should be made
able to parse IORT table entries and create platform devices
dynamically.

This patch adds the generic IORT infrastructure required to create
platform devices for ARM SMMUs.

ARM SMMU versions have different resources requirement therefore this
patch also introduces an IORT specific structure (ie iort_iommu_config)
that contains hooks (to be defined when the corresponding ARM SMMU
driver support is added to the kernel) to be used to define the
platform devices names, init the IOMMUs, count their resources and
finally initialize them.

Signed-off-by: Lorenzo Pieralisi <lorenzo.pieral...@arm.com>
Cc: Hanjun Guo <hanjun@linaro.org>
Cc: Tomasz Nowicki <t...@semihalf.com>
Cc: "Rafael J. Wysocki" <r...@rjwysocki.net>
---
 drivers/acpi/iort.c  | 107 +++
 include/linux/iort.h |  10 +
 2 files changed, 117 insertions(+)

diff --git a/drivers/acpi/iort.c b/drivers/acpi/iort.c
index 71516e8..23c80c7 100644
--- a/drivers/acpi/iort.c
+++ b/drivers/acpi/iort.c
@@ -22,6 +22,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 struct iort_its_msi_chip {
@@ -454,6 +455,112 @@ iort_get_device_domain(struct device *dev, u32 req_id)
return irq_find_matching_fwnode(handle, DOMAIN_BUS_PCI_MSI);
 }
 
+struct iort_iommu_config {
+   const char *name;
+   int (*iommu_init)(struct acpi_iort_node *node);
+   bool (*iommu_is_coherent)(struct acpi_iort_node *node);
+   int (*iommu_count_resources)(struct acpi_iort_node *node);
+   void (*iommu_init_resources)(struct resource *res,
+struct acpi_iort_node *node);
+};
+
+static inline const struct iort_iommu_config *
+iort_get_iommu_config(struct acpi_iort_node *node)
+{
+   return NULL;
+}
+
+/**
+ * iort_add_smmu_platform_device() - Allocate a platform device for SMMU
+ * @fwnode: Pointer to SMMU firmware node
+ * @node: Pointer to SMMU ACPI IORT node
+ *
+ * Returns: 0 on success, <0 failure
+ */
+int iort_add_smmu_platform_device(struct fwnode_handle *fwnode,
+ struct acpi_iort_node *node)
+{
+   struct platform_device *pdev;
+   struct resource *r;
+   enum dev_dma_attr attr;
+   int ret, count;
+   const struct iort_iommu_config *ops =
+   iort_get_iommu_config(node);
+
+   if (!ops)
+   return -ENODEV;
+
+   pdev = platform_device_alloc(ops->name, PLATFORM_DEVID_AUTO);
+   if (!pdev)
+   return PTR_ERR(pdev);
+
+   count = ops->iommu_count_resources(node);
+
+   r = kcalloc(count, sizeof(*r), GFP_KERNEL);
+   if (!r) {
+   ret = -ENOMEM;
+   goto dev_put;
+   }
+
+   ops->iommu_init_resources(r, node);
+
+   ret = platform_device_add_resources(pdev, r, count);
+   /*
+* Resources are duplicated in platform_device_add_resources,
+* free their allocated memory
+*/
+   kfree(r);
+
+   if (ret)
+   goto dev_put;
+
+   /*
+* Add a copy of IORT node pointer to platform_data to
+* be used to retrieve IORT data information.
+*/
+   ret = platform_device_add_data(pdev, , sizeof(node));
+   if (ret)
+   goto dev_put;
+
+   pdev->dev.dma_mask = kmalloc(sizeof(*pdev->dev.dma_mask), GFP_KERNEL);
+   if (!pdev->dev.dma_mask) {
+   ret = -ENOMEM;
+   goto dev_put;
+   }
+
+   pdev->dev.fwnode = fwnode;
+
+   /*
+* Set default dma mask value for the table walker,
+* to be overridden on probing with correct value.
+*/
+   *pdev->dev.dma_mask = DMA_BIT_MASK(32);
+   pdev->dev.coherent_dma_mask = *pdev->dev.dma_mask;
+
+   attr = ops->iommu_is_coherent(node) ?
+DEV_DMA_COHERENT : DEV_DMA_NON_COHERENT;
+
+   /* Configure DMA for the page table walker */
+   acpi_dma_configure(>dev, attr);
+
+   ret = platform_device_add(pdev);
+   if (ret)
+   goto dma_deconfigure;
+
+   iort_set_fwnode(node, pdev->dev.fwnode);
+
+   return 0;
+
+dma_deconfigure:
+   acpi_dma_deconfigure(>dev);
+   kfree(pdev->dev.dma_mask);
+
+dev_put:
+   platform_device_put(pdev);
+
+   return ret;
+}
+
 void __init iort_table_detect(void)
 {
acpi_status status;
diff --git a/include/linux/iort.h b/include/linux/iort.h
index ac2706a..18e6836 100644
--- a/include/linux/iort.h
+++ b/include/linux/iort.h
@@ -31,6 +31,9 @@ bool iort_node_match(u8 type);
 void iort_table_detect(void);
 u32 iort_msi_map_rid(struct device *dev, u32 req_id);
 struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_i

[RFC PATCH v3 04/13] drivers: platform: add fwnode base platform devices retrieval

2016-07-20 Thread Lorenzo Pieralisi
The platform device kernel API does not provide functions to
retrieve a platform device through the corresponding struct
device fwnode pointer.

Implement the fwnode platform_device look-up in drivers core
code by using the bus_find_device() API and a corresponding
matching function. The OF equivalent (eg of_find_device_by_node())
will reuse the newly introduced function when OF code will
take care of setting up the device->fwnode value that is
currently left dangling for platform devices instantiated out
of device tree nodes.

Signed-off-by: Lorenzo Pieralisi <lorenzo.pieral...@arm.com>
Cc: Greg Kroah-Hartman <gre...@linuxfoundation.org>
Cc: "Rafael J. Wysocki" <r...@rjwysocki.net>
---
 drivers/base/platform.c | 23 +++
 include/linux/platform_device.h |  3 +++
 2 files changed, 26 insertions(+)

diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 6482d47..3ef150d 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -760,6 +760,29 @@ err_out:
 }
 EXPORT_SYMBOL_GPL(__platform_create_bundle);
 
+static int fwnode_dev_match(struct device *dev, void *data)
+{
+   return dev->fwnode == data;
+}
+
+/**
+ * platform_find_device_by_fwnode() - Find the platform_device associated
+ *   with a fwnode
+ * @fwnode: Pointer to firmware node
+ *
+ * Returns platform_device pointer, or NULL if not found
+ */
+struct platform_device *
+platform_find_device_by_fwnode(struct fwnode_handle *fwnode)
+{
+   struct device *dev;
+
+   dev = bus_find_device(_bus_type, NULL, fwnode,
+ fwnode_dev_match);
+   return dev ? to_platform_device(dev) : NULL;
+}
+EXPORT_SYMBOL(platform_find_device_by_fwnode);
+
 /**
  * __platform_register_drivers - register an array of platform drivers
  * @drivers: an array of drivers to register
diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
index 98c2a7c..01a3eb2 100644
--- a/include/linux/platform_device.h
+++ b/include/linux/platform_device.h
@@ -276,6 +276,9 @@ extern struct platform_device *__platform_create_bundle(
struct resource *res, unsigned int n_res,
const void *data, size_t size, struct module *module);
 
+extern struct platform_device *
+platform_find_device_by_fwnode(struct fwnode_handle *fwnode);
+
 int __platform_register_drivers(struct platform_driver * const *drivers,
unsigned int count, struct module *owner);
 void platform_unregister_drivers(struct platform_driver * const *drivers,
-- 
2.6.4



Re: Purpose of pci_remap_iospace

2016-07-13 Thread Lorenzo Pieralisi
On Wed, Jul 13, 2016 at 12:30:44PM +, Bharat Kumar Gogada wrote:

[...]

> err = of_pci_get_host_bridge_resources(node, 0, 0xff, , );
> if (err) {
> pr_err("Getting bridge resources failed\n");
> return err;
> }
> resource_list_for_each_entry(window, ) {//code for io resource
> struct resource *res = window->res;
> u64 restype = resource_type(res);
> 
> switch (restype) {
> case IORESOURCE_IO:
> err = pci_remap_iospace(res, iobase);
> if(err)
> pr_info("FAILED TO IPREMAP RESOURCE\n");
> break;
> default:
> dev_err(pcie->dev, "invalid resource %pR\n", res);
> 
> }
> }
> 
> Other than above code I haven't done any change in driver.
> 
> Here is the printk added boot log:
> [2.308680] nwl-pcie fd0e.pcie: Link is UP
> [2.308724] PCI host bridge /amba/pcie@fd0e ranges:
> [2.308741]   No bus range found for /amba/pcie@fd0e, using [bus 00-ff]
> [2.308755] in pci_add_resource_offset res->start 0   offset 0
> [2.308774]IO 0xe000..0xe00f -> 0x
> [2.308795] in pci_add_resource_offset res->start 0   offset 0
> [2.308805]   MEM 0xe010..0xeeff -> 0xe010
> [2.308824] in pci_add_resource_offset res->start e010offset 0
> [2.308834] nwl-pcie fd0e.pcie: invalid resource [bus 00-ff]
> [2.308870] nwl-pcie fd0e.pcie: invalid resource [mem 
> 0xe010-0xeeff]
> [2.308979] nwl-pcie fd0e.pcie: PCI host bridge to bus :00
> [2.308998] pci_bus :00: root bus resource [bus 00-ff]
> [2.309014] pci_bus :00: root bus resource [io  0x-0xf]
> [2.309030] pci_bus :00: root bus resource [mem 0xe010-0xeeff]
> [2.309253] pci :00:00.0: cannot attach to SMMU, is it on the same bus?
> [2.309269] iommu: Adding device :00:00.0 to group 1
> [2.309625] pci :01:00.0: cannot attach to SMMU, is it on the same bus?
> [2.309641] iommu: Adding device :01:00.0 to group 1
> [2.309697] pci :00:00.0: BAR 8: assigned [mem 0xe010-0xe02f]

Here is your PCI bridge mem space window assignment. I do not see
an IO window assignment which makes me think that IO cycles and
relative IO window is not enabled through the bridge, that's the
reason you can't assign IO space to the endpoint, because it has
no parent IO window enabled IIUC.

You can add some debug info into pci_bridge_check_ranges() in
particular to the reading of PCI_IO_BASE resources to confirm
what I am saying above, thanks.

Lorenzo

> [2.309718] pci :01:00.0: BAR 0: assigned [mem 0xe010-0xe01f 
> 64bit]
> [2.309752] pci :01:00.0: BAR 2: assigned [mem 0xe020-0xe02f 
> 64bit]
> [2.309784] pci :01:00.0: BAR 4: no space for [io  size 0x0040]
> [2.309800] pci :01:00.0: BAR 4: failed to assign [io  size 0x0040]
> [2.309816] pci :00:00.0: PCI bridge to [bus 01-0c]
> [2.309833] pci :00:00.0:   bridge window [mem 0xe010-0xe02f]
> 
> Here is the output of ioports and iomem:
> 
> root@:~# cat /proc/iomem
> -7fff : System RAM
>   0008-00a76fff : Kernel code
>   01c72000-01d4bfff : Kernel data
> fd0c-fd0c1fff : /amba/ahci@fd0c
> fd0e-fd0e0fff : breg
> fd48-fd480fff : pcireg
> ff00-ff000fff : xuartps
> ff01-ff010fff : xuartps
> ff02-ff020fff : /amba/i2c@ff02
> ff03-ff030fff : /amba/i2c@ff03
> ff07-ff070fff : /amba/can@ff07
> ff0a-ff0a0fff : /amba/gpio@ff0a
> ff0f-ff0f0fff : /amba/spi@ff0f
> ff17-ff170fff : mmc0
> ffa6-ffa600ff : /amba/rtc@ffa6
> 80-8000ff : cfg
> root@:~# cat /proc/ioports
> root@:~#
> 
> /proc/ioports is empty.
> 
> Thanks & Regards,
> Bharat
> 
> 
> This email and any attachments are intended for the sole use of the named 
> recipient(s) and contain(s) confidential information that may be proprietary, 
> privileged or copyrighted under applicable law. If you are not the intended 
> recipient, do not read, copy, or forward this email message or any 
> attachments. Delete this email message and any attachments immediately.
> 


Re: [PATCH v6 00/10] acpi, clocksource: add GTDT driver and GTDT support in arm_arch_timer

2016-07-07 Thread Lorenzo Pieralisi
[+Sudeep]

On Thu, Jul 07, 2016 at 02:03:17PM +0200, Rafael J. Wysocki wrote:

[...]

> > >> So is this a documentation issue in which case Fu Wei can add that to
> > >> the file to explain its limited to ARM64. Or we could even rename the
> > >> file acpi_arm64_gtdt.c
> > >>
> > >> It seems a pity as the comment on this series were minors to block
> > >> things on a filename/location.
> > >
> > > Let me repeat what I said above:
> > >
> > > I'm mostly concerned about how (and by whom) that code is going to be
> > > maintained going forward.
> > >
> > > This is not about documentation, it is about responsibility.
> > >
> > > Honestly, I don't think I'm the right maintainer to apply the patch
> > > introducing this code and then handle bug reports regarding it and so
> > > on.  That has to be done by somebody else.
> > 
> > I'm working on ACPI for years and upstreamed the ARM64 ACPI core
> > support (with lots of people's help), I'm willing to maintain the ARM64
> > ACPI code under drivers/acpi/ if no objections.
> 
> OK

I would ask you please to add Sudeep and myself for the ARM64 specific
ACPI code maintainership too.

> Can the ARM64-specific code go under drivers/acpi/arm64/ then, for clarity?

It can, but I do not understand why x86 should not have a separate
directory for all x86 specific stuff too then.

Anyway let's avoid these petty arguments, I agree there must be some
sort of ARM64 ACPI maintainership for the reasons you mentioned above.

> > > That's one thing.
> > >
> > > Another one is the question I asked a few messages ago: Why having the
> > > GTDT code in drivers/acpi/ is actually useful to anyone?  It
> > > definitely would not be useful to me as the maintainer of
> > > drivers/acpi/, but maybe it would be useful to somebody for a specific
> > > practical reason.  Or is it just "let's put this into drivers/acpi/
> > > for the lack of a better place"?

The same logic applies to eg ioapic.c but anyway, see above, if it
can help having a separate subdirectory let's do it.

> > Having GTDT code in drivers/acpi/ is useful as it is code that is used
> > by two different subsystems, clocksource and watchdog,and where people
> > look by default for utility ACPI code.
> > 
> > If the mostly concerned thing (maintainer ship) is settled down, the
> > second question would be easily solved.

See above.

Thanks,
Lorenzo


Re: [PATCH v6 00/10] acpi, clocksource: add GTDT driver and GTDT support in arm_arch_timer

2016-07-08 Thread Lorenzo Pieralisi
On Thu, Jul 07, 2016 at 03:58:04PM +0200, Rafael J. Wysocki wrote:

[...]

> > Anyway let's avoid these petty arguments, I agree there must be some
> > sort of ARM64 ACPI maintainership for the reasons you mentioned above.
> 
> To avoid confusion on who's going to push stuff to Linus, I can do
> that, but it must be clear whose ACKs are needed for that to happen.
> That may be one person or all of you, whatever you decide.

I think the reasoning is the same, to avoid confusion and avoid stepping
on each other toes it is best to have a single gatekeeper (still
multiple maintainer entries to keep patches reviewed correctly), if no
one complains I will do that and a) provide ACKs (I will definitely
require and request Hanjun and Sudeep ones too appropriately on a per
patch basis) and b) send you pull requests.

Having a maintainer per file would be farcical, I really do not
expect that amount of traffic for drivers/acpi/arm64 therefore I
really doubt there is any risk of me slowing things down.

Does this sound reasonable ? Comments/complaints welcome, please
manifest yourselves.

Thanks,
Lorenzo


Re: [PATCH v8 0/6] ACPI / processor_idle: Add ACPI v6.0 LPI support

2016-07-08 Thread Lorenzo Pieralisi
On Fri, Jul 08, 2016 at 12:04:40PM +0100, Sudeep Holla wrote:
> 
> 
> On 07/07/16 22:02, Rafael J. Wysocki wrote:
> >On Thu, Jul 7, 2016 at 7:10 PM, Sudeep Holla  wrote:
> >>ACPI 6.0 introduced LPI(Low Power Idle) states that provides an alternate
> >>method to describe processor idle states. It extends the specification
> >>to allow the expression of idle states like C-states selectable by the
> >>OSPM when a processor goes idle, but may affect more than one processor,
> >>and may affect other system components.
> >>
> >>LPI extensions leverages the processor container device(again introduced
> >>in ACPI 6.0) allowing to express which parts of the system are affected
> >>by a given LPI state. It defines the local power states for each node
> >>in a hierarchical processor topology. The OSPM can use _LPI object to
> >>select a local power state for each level of processor hierarchy in the
> >>system. They used to produce a composite power state request that is
> >>presented to the platform by the OSPM.
> >>
> >>Since multiple processors affect the idle state for any non-leaf hierarchy
> >>node, coordination of idle state requests between the processors is
> >>required. ACPI supports two different coordination schemes: Platform
> >>coordinated and  OS initiated.
> >>
> >>This series aims at providing basic and initial support for platform
> >>coordinated LPI states.
> >>
> >>v7[7]->v8:
> >> - Replaced HAVE_GENERIC_CPUIDLE_ENTER with CPU_IDLE_ENTER_WRAPPED
> >>   macro, which is more cleaner and definately less confusing :)
> >>   (Thanks to Rafael for the suggestion)
> >
> >Patches [3-6/6] definitely look a lot cleaner to me now. :-)
> >
> >That said, the name of the macro I suggested was just an example, so
> >if people don't like this one, it'd be fine to change it as far as I'm
> >concerned.
> >
> 
> I can think of addition to indicate it's pm notifiers wrapper.
> i.e. CPU_IDLE_ENTER_PM_NOTIFIERS_WRAPPED. Is it too long ? I am happy
> with the way it is too.

CPU_PM_CPU_IDLE_ENTER() ? Anyway, that's really not a problem IMO,
it makes sense to at least mention CPU PM in it given that's what
the CPUIDLE enter function is wrapped within.

Lorenzo


Re: [PATCH v8 5/6] arm64: add support for ACPI Low Power Idle(LPI)

2016-07-08 Thread Lorenzo Pieralisi
On Thu, Jul 07, 2016 at 06:10:50PM +0100, Sudeep Holla wrote:
> This patch adds appropriate callbacks to support ACPI Low Power Idle
> (LPI) on ARM64.
> 
> Cc: Lorenzo Pieralisi <lorenzo.pieral...@arm.com>
> Cc: Mark Rutland <mark.rutl...@arm.com>
> Cc: Daniel Lezcano <daniel.lezc...@linaro.org>
> Cc: "Rafael J. Wysocki" <r...@rjwysocki.net>
> Signed-off-by: Sudeep Holla <sudeep.ho...@arm.com>
> ---
>  arch/arm64/kernel/cpuidle.c |  18 +++
>  drivers/firmware/psci.c | 122 
> 

I would split this patch in two (ARM64 cpuidle and PSCI) and for
the PSCI code (apologies, blame taken, it is entirely my fault) I
think that the code in v6 was better, I asked you to factor out
DT/ACPI idle states count and parameter retrieval but the end result
is much more complicated than what it was in v6, so for PSCI ACPI
idle states parsing I would revert to v6, apologies.

With changes above:

Acked-by: Lorenzo Pieralisi <lorenzo.pieral...@arm.com>

>  2 files changed, 118 insertions(+), 22 deletions(-)
> 
> diff --git a/arch/arm64/kernel/cpuidle.c b/arch/arm64/kernel/cpuidle.c
> index 06786fdaadeb..7f16df7d7b23 100644
> --- a/arch/arm64/kernel/cpuidle.c
> +++ b/arch/arm64/kernel/cpuidle.c
> @@ -9,6 +9,9 @@
>   * published by the Free Software Foundation.
>   */
>  
> +#include 
> +#include 
> +#include 
>  #include 
>  #include 
>  
> @@ -39,3 +42,18 @@ int arm_cpuidle_suspend(int index)
>  
>   return cpu_ops[cpu]->cpu_suspend(index);
>  }
> +
> +#ifdef CONFIG_ACPI
> +
> +#include 
> +
> +int acpi_processor_ffh_lpi_probe(unsigned int cpu)
> +{
> + return arm_cpuidle_init(cpu);
> +}
> +
> +int acpi_processor_ffh_lpi_enter(struct acpi_lpi_state *lpi)
> +{
> + return CPU_IDLE_ENTER_WRAPPED(arm_cpuidle_suspend, lpi->index);
> +}
> +#endif
> diff --git a/drivers/firmware/psci.c b/drivers/firmware/psci.c
> index 03e04582791c..edd83c884a1d 100644
> --- a/drivers/firmware/psci.c
> +++ b/drivers/firmware/psci.c
> @@ -13,6 +13,7 @@
>  
>  #define pr_fmt(fmt) "psci: " fmt
>  
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -250,12 +251,84 @@ static int __init psci_features(u32 psci_func_id)
>  #ifdef CONFIG_CPU_IDLE
>  static DEFINE_PER_CPU_READ_MOSTLY(u32 *, psci_power_state);
>  
> -static int psci_dt_cpu_init_idle(struct device_node *cpu_node, int cpu)
> +static int psci_dt_get_state_count(struct device_node *cpu_dn)
>  {
> - int i, ret, count = 0;
> - u32 *psci_states;
> + int count = 0;
>   struct device_node *state_node;
>  
> + /* Count idle states */
> + while ((state_node = of_parse_phandle(cpu_dn, "cpu-idle-states",
> +   count))) {
> + count++;
> + of_node_put(state_node);
> + }
> +
> + return count;
> +}
> +
> +static int psci_dt_get_idle_state(struct device_node *node, int idx, u32 
> *state)
> +{
> + int ret;
> + struct device_node *state_node;
> +
> + state_node = of_parse_phandle(node, "cpu-idle-states", idx);
> +
> + ret = of_property_read_u32(state_node, "arm,psci-suspend-param",
> +state);
> + if (ret)
> + pr_warn(" * %s missing arm,psci-suspend-param property\n",
> + state_node->full_name);
> +
> + of_node_put(state_node);
> +
> + return ret;
> +}
> +
> +#ifdef CONFIG_ACPI
> +#include 
> +
> +static int psci_acpi_get_state_count(unsigned int cpu)
> +{
> + struct acpi_processor *pr = per_cpu(processors, cpu);
> +
> + if (unlikely(!pr || !pr->flags.has_lpi))
> + return -EINVAL;
> +
> + return pr->power.count - 1;
> +}
> +
> +static int psci_acpi_get_idle_state(unsigned int cpu, int idx, u32 *state)
> +{
> + struct acpi_processor *pr = per_cpu(processors, cpu);
> + struct acpi_lpi_state *lpi = >power.lpi_states[idx + 1];
> +
> + if (!lpi)
> + return -EINVAL;
> +
> + /*
> +  * Only bits[31:0] represent a PSCI power_state while
> +  * bits[63:32] must be 0x0 as per ARM ACPI FFH Specification
> +  */
> + *state = lpi->address;
> + return 0;
> +}
> +#else
> +static int psci_acpi_get_state_count(unsigned int cpu)
> +{
> + return -EINVAL;
> +}
> +
> +static int psci_acpi_get_idle_state(unsigned int cpu, int idx, u32 *state)
> +{
> + return -EINVAL;
> +}
> +#endif
> +
> +static int __psci_cpu_init_idle(struct device_node *cpu_dn, int cpu, bool 
>

Re: [RFC PATCH v3 13/13] drivers: acpi: iort: introduce iort_iommu_configure

2016-08-08 Thread Lorenzo Pieralisi
Hi Nate,

thanks for having a look.

On Wed, Aug 03, 2016 at 10:19:43AM -0400, nwatt...@codeaurora.org wrote:
> On 2016-07-20 07:23, Lorenzo Pieralisi wrote:
> >DT based systems have a generic kernel API to configure IOMMUs
> >for devices (ie of_iommu_configure()).
> >
> >On ARM based ACPI systems, the of_iommu_configure() equivalent can
> >be implemented atop ACPI IORT kernel API, with the corresponding
> >functions to map device identifiers to IOMMUs and retrieve the
> >corresponding IOMMU operations necessary for DMA operations set-up.
> >
> >By relying on the iommu_fwspec generic kernel infrastructure,
> >implement the IORT based IOMMU configuration for ARM ACPI systems
> >and hook it up in the ACPI kernel layer that implements DMA
> >configuration for a device.
> >
> >Signed-off-by: Lorenzo Pieralisi <lorenzo.pieral...@arm.com>
> >Cc: Hanjun Guo <hanjun@linaro.org>
> >Cc: Tomasz Nowicki <t...@semihalf.com>
> >Cc: "Rafael J. Wysocki" <r...@rjwysocki.net>
> >---
> > drivers/acpi/iort.c  | 64
> >
> > drivers/acpi/scan.c  |  7 +-
> > include/linux/iort.h |  4 
> > 3 files changed, 74 insertions(+), 1 deletion(-)
> >
> >diff --git a/drivers/acpi/iort.c b/drivers/acpi/iort.c
> >index c116b68..a12a4ff 100644
> >--- a/drivers/acpi/iort.c
> >+++ b/drivers/acpi/iort.c
> >@@ -18,6 +18,7 @@
> >
> > #define pr_fmt(fmt) "ACPI: IORT: " fmt
> >
> >+#include 
> > #include 
> > #include 
> > #include 
> >@@ -27,6 +28,8 @@
> >
> > #define IORT_TYPE_MASK(type)(1 << (type))
> > #define IORT_MSI_TYPE   (1 << ACPI_IORT_NODE_ITS_GROUP)
> >+#define IORT_IOMMU_TYPE ((1 << ACPI_IORT_NODE_SMMU) |   \
> >+(1 << ACPI_IORT_NODE_SMMU_V3))
> >
> > struct iort_its_msi_chip {
> > struct list_headlist;
> >@@ -458,6 +461,67 @@ iort_get_device_domain(struct device *dev,
> >u32 req_id)
> > return irq_find_matching_fwnode(handle, DOMAIN_BUS_PCI_MSI);
> > }
> >
> >+static int __get_pci_rid(struct pci_dev *pdev, u16 alias, void *data)
> >+{
> >+u32 *rid = data;
> >+
> >+*rid = alias;
> >+return 0;
> >+}
> >+
> >+static int arm_smmu_iort_xlate(struct device *dev, u32 streamid,
> >+   struct fwnode_handle *fwnode)
> >+{
> >+int ret = iommu_fwspec_init(dev, fwnode);
> >+
> >+if (!ret)
> >+ret = iommu_fwspec_add_ids(dev, , 1);
> >+
> >+return 0;
> 
> Are you intentionally returning 0 instead of ret? How about doing
> this instead?
> 
>   return ret ? ret : iommu_fwspec_add_ids(dev, , 1);

No, that's a bug, I will return ret as the of_xlate() function in
the ARM SMMU v3 driver does, thanks.

> >+}
> >+
> >+/**
> >+ * iort_iommu_configure - Set-up IOMMU configuration for a device.
> >+ *
> >+ * @dev: device to configure
> >+ *
> >+ * Returns: iommu_ops pointer on configuration success
> >+ *  NULL on configuration failure
> >+ */
> >+const struct iommu_ops *iort_iommu_configure(struct device *dev)
> >+{
> >+struct acpi_iort_node *node, *parent;
> >+struct fwnode_handle *iort_fwnode;
> >+u32 rid = 0, devid = 0;
> 
> Since this routine maps the RID space of a device to the StreamID
> space of its parent smmu, would you consider renaming the devid
> variable to some form of sid or streamid?

Yes, I will do.

> >+if (dev_is_pci(dev)) {
> >+struct pci_bus *bus = to_pci_dev(dev)->bus;
> >+
> >+pci_for_each_dma_alias(to_pci_dev(dev), __get_pci_rid,
> >+   );
> >+
> >+node = iort_scan_node(ACPI_IORT_NODE_PCI_ROOT_COMPLEX,
> >+  iort_match_node_callback, >dev);
> >+} else {
> >+node = iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT,
> >+  iort_match_node_callback, dev);
> >+}
> >+
> >+if (!node)
> >+return NULL;
> >+
> >+parent = iort_node_map_rid(node, rid, , IORT_IOMMU_TYPE);
> >+if (parent) {
> >+iort_fwnode = iort_get_fwnode(parent);
> >+if (iort_fwnode) {
> >+arm_smmu_iort_xlate(dev, devid, iort_fwnode);
> 
> What about named components with multiple stream ids? Since
> establishing the relationsh

Re: [PATCH v7 4/4] nmi_backtrace: generate one-line reports for idle cpus

2016-08-09 Thread Lorenzo Pieralisi
On Mon, Aug 08, 2016 at 05:48:28PM +0100, Mark Rutland wrote:
> Hi,
> 
> [adding Lorenzo]
> 
> On Mon, Aug 08, 2016 at 12:03:38PM -0400, Chris Metcalf wrote:
> > When doing an nmi backtrace of many cores, most of which are idle,
> > the output is a little overwhelming and very uninformative.  Suppress
> > messages for cpus that are idling when they are interrupted and just
> > emit one line, "NMI backtrace for N skipped: idling at pc 0xNNN".
> > 
> > We do this by grouping all the cpuidle code together into a new
> > .cpuidle.text section, and then checking the address of the
> > interrupted PC to see if it lies within that section.
> > 
> > This commit suitably tags x86, arm64, and tile idle routines,
> > and only adds in the minimal framework for other architectures.
> 
> > diff --git a/arch/arm64/kernel/vmlinux.lds.S 
> > b/arch/arm64/kernel/vmlinux.lds.S
> > index 659963d40bb4..fe7f93b7b11b 100644
> > --- a/arch/arm64/kernel/vmlinux.lds.S
> > +++ b/arch/arm64/kernel/vmlinux.lds.S
> > @@ -122,6 +122,7 @@ SECTIONS
> > ENTRY_TEXT
> > TEXT_TEXT
> > SCHED_TEXT
> > +   CPUIDLE_TEXT
> > LOCK_TEXT
> > KPROBES_TEXT
> > HYPERVISOR_TEXT
> > diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
> > index 5bb61de23201..64f088ca3192 100644
> > --- a/arch/arm64/mm/proc.S
> > +++ b/arch/arm64/mm/proc.S
> > @@ -48,11 +48,13 @@
> >   *
> >   * Idle the processor (wait for interrupt).
> >   */
> > +   .pushsection ".cpuidle.text","ax"
> >  ENTRY(cpu_do_idle)
> > dsb sy  // WFI may enter a low-power 
> > mode
> > wfi
> > ret
> >  ENDPROC(cpu_do_idle)
> > +   .popsection
> 
> From a quick scan it looks like we only call this with interrupts
> disabled, and we have no NMI. So shouldn't we be annotating
> arch_cpu_idle(), which calls this and subsequently enables interrupts?
> 
> I'm also not sure what you need to do for PSCI, which is the preferred
> (FW-backed) idle mechanism for arm64. The infrastrucure for that is
> spread over a few files:
> 
>   arch/arm64/kernel/sleep.S
>   arch/arm64/kernel/smccc-call.S
>   arch/arm64/kernel/suspend.c
>   drivers/cpuidle/cpuidle-arm.c
>   drivers/firmware/psci.c
> 
> I'm not sure where we'd be an an interruptible state, and therefore I'm
> not immediately sure what we should annotate.

I am probably missing something here, but let me add that I am not
sure I understand how this patch can be used on ARM/ARM64 systems
so ARM platform idle back-end code annotation is basically useless
given that it is code that can't be preempted anyway (and even if
it could PC range check can even fail given that we may execute some
code with MMU off so out of physical addresses).

What's the purpose of this cpu idle tracking ? Can't it be implemented
in a simpler way (ie RCU API) ?

Lorenzo


[PATCH v4 12/15] drivers: iommu: arm-smmu-v3: add IORT configuration

2016-08-15 Thread Lorenzo Pieralisi
In ACPI bases systems, in order to be able to create platform
devices and initialize them for ARM SMMU v3 components, the IORT
kernel implementation requires a set of static functions to be
used by the IORT kernel layer to configure platform devices for
ARM SMMU v3 components.

Add static configuration functions to the IORT kernel layer for
the ARM SMMU v3 components, so that the ARM SMMU v3 driver can
initialize its respective platform device by relying on the IORT
kernel infrastructure and by adding a corresponding ACPI device
early probe section entry.

Signed-off-by: Lorenzo Pieralisi <lorenzo.pieral...@arm.com>
Cc: Will Deacon <will.dea...@arm.com>
Cc: Robin Murphy <robin.mur...@arm.com>
Cc: Joerg Roedel <j...@8bytes.org>
---
 drivers/acpi/arm64/iort.c   | 103 +++-
 drivers/iommu/arm-smmu-v3.c |  61 ++
 2 files changed, 163 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index 4043071..f42cff8 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -455,6 +455,95 @@ iort_get_device_domain(struct device *dev, u32 req_id)
return irq_find_matching_fwnode(handle, DOMAIN_BUS_PCI_MSI);
 }
 
+static void __init acpi_iort_register_irq(int hwirq, const char *name,
+ int trigger,
+ struct resource *res)
+{
+   int irq = acpi_register_gsi(NULL, hwirq, trigger,
+   ACPI_ACTIVE_HIGH);
+
+   if (irq < 0) {
+   pr_err("could not register gsi hwirq %d name [%s]\n", hwirq,
+ name);
+   return;
+   }
+
+   res->start = irq;
+   res->end = irq;
+   res->flags = IORESOURCE_IRQ;
+   res->name = name;
+}
+
+static int __init arm_smmu_v3_count_resources(struct acpi_iort_node *node)
+{
+   struct acpi_iort_smmu_v3 *smmu;
+   /* Always present mem resource */
+   int num_res = 1;
+
+   /* Retrieve SMMUv3 specific data */
+   smmu = (struct acpi_iort_smmu_v3 *)node->node_data;
+
+   if (smmu->event_gsiv)
+   num_res++;
+
+   if (smmu->pri_gsiv)
+   num_res++;
+
+   if (smmu->gerr_gsiv)
+   num_res++;
+
+   if (smmu->sync_gsiv)
+   num_res++;
+
+   return num_res;
+}
+
+static void __init arm_smmu_v3_init_resources(struct resource *res,
+ struct acpi_iort_node *node)
+{
+   struct acpi_iort_smmu_v3 *smmu;
+   int num_res = 0;
+
+   /* Retrieve SMMUv3 specific data */
+   smmu = (struct acpi_iort_smmu_v3 *)node->node_data;
+
+   res[num_res].start = smmu->base_address;
+   res[num_res].end = smmu->base_address + SZ_128K - 1;
+   res[num_res].flags = IORESOURCE_MEM;
+
+   num_res++;
+
+   if (smmu->event_gsiv)
+   acpi_iort_register_irq(smmu->event_gsiv, "eventq",
+  ACPI_EDGE_SENSITIVE,
+  [num_res++]);
+
+   if (smmu->pri_gsiv)
+   acpi_iort_register_irq(smmu->pri_gsiv, "priq",
+  ACPI_EDGE_SENSITIVE,
+  [num_res++]);
+
+   if (smmu->gerr_gsiv)
+   acpi_iort_register_irq(smmu->gerr_gsiv, "gerror",
+  ACPI_EDGE_SENSITIVE,
+  [num_res++]);
+
+   if (smmu->sync_gsiv)
+   acpi_iort_register_irq(smmu->sync_gsiv, "cmdq-sync",
+  ACPI_EDGE_SENSITIVE,
+  [num_res++]);
+}
+
+static bool __init arm_smmu_v3_is_coherent(struct acpi_iort_node *node)
+{
+   struct acpi_iort_smmu_v3 *smmu;
+
+   /* Retrieve SMMUv3 specific data */
+   smmu = (struct acpi_iort_smmu_v3 *)node->node_data;
+
+   return smmu->flags & ACPI_IORT_SMMU_V3_COHACC_OVERRIDE;
+}
+
 struct iort_iommu_config {
const char *name;
int (*iommu_init)(struct acpi_iort_node *node);
@@ -464,10 +553,22 @@ struct iort_iommu_config {
 struct acpi_iort_node *node);
 };
 
+const struct iort_iommu_config iort_arm_smmu_v3_cfg __initconst = {
+   .name = "arm-smmu-v3",
+   .iommu_is_coherent = arm_smmu_v3_is_coherent,
+   .iommu_count_resources = arm_smmu_v3_count_resources,
+   .iommu_init_resources = arm_smmu_v3_init_resources
+};
+
 static const struct iort_iommu_config * __init
 iort_get_iommu_config(struct acpi_iort_node *node)
 {
-   return NULL;
+   switch (node->type) {
+   case ACPI_IORT_NODE_SMMU_V3:
+   return _arm_smmu_v3_cfg;
+ 

[PATCH v4 15/15] drivers: acpi: iort: introduce iort_iommu_configure

2016-08-15 Thread Lorenzo Pieralisi
DT based systems have a generic kernel API to configure IOMMUs
for devices (ie of_iommu_configure()).

On ARM based ACPI systems, the of_iommu_configure() equivalent can
be implemented atop ACPI IORT kernel API, with the corresponding
functions to map device identifiers to IOMMUs and retrieve the
corresponding IOMMU operations necessary for DMA operations set-up.

By relying on the iommu_fwspec generic kernel infrastructure,
implement the IORT based IOMMU configuration for ARM ACPI systems
and hook it up in the ACPI kernel layer that implements DMA
configuration for a device.

Signed-off-by: Lorenzo Pieralisi <lorenzo.pieral...@arm.com>
Cc: Hanjun Guo <hanjun@linaro.org>
Cc: Tomasz Nowicki <t...@semihalf.com>
Cc: "Rafael J. Wysocki" <r...@rjwysocki.net>
---
 drivers/acpi/arm64/iort.c | 96 +++
 drivers/acpi/scan.c   |  7 +++-
 include/linux/iort.h  |  5 +++
 3 files changed, 107 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index e68ed2c..c231629 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -18,6 +18,7 @@
 
 #define pr_fmt(fmt)"ACPI: IORT: " fmt
 
+#include 
 #include 
 #include 
 #include 
@@ -27,6 +28,8 @@
 
 #define IORT_TYPE_MASK(type)   (1 << (type))
 #define IORT_MSI_TYPE  (1 << ACPI_IORT_NODE_ITS_GROUP)
+#define IORT_IOMMU_TYPE((1 << ACPI_IORT_NODE_SMMU) |   \
+   (1 << ACPI_IORT_NODE_SMMU_V3))
 
 struct iort_its_msi_chip {
struct list_headlist;
@@ -496,6 +499,99 @@ iort_get_device_domain(struct device *dev, u32 req_id)
return irq_find_matching_fwnode(handle, DOMAIN_BUS_PCI_MSI);
 }
 
+static int __get_pci_rid(struct pci_dev *pdev, u16 alias, void *data)
+{
+   u32 *rid = data;
+
+   *rid = alias;
+   return 0;
+}
+
+static int arm_smmu_iort_xlate(struct device *dev, u32 streamid,
+  struct fwnode_handle *fwnode)
+{
+   int ret = iommu_fwspec_init(dev, fwnode);
+
+   if (!ret)
+   ret = iommu_fwspec_add_ids(dev, , 1);
+
+   return ret;
+}
+
+static const struct iommu_ops *
+iort_iommu_xlate(struct device *dev, struct acpi_iort_node *node,
+u32 streamid)
+{
+   struct fwnode_handle *iort_fwnode = NULL;
+   int ret;
+
+   if (node) {
+   iort_fwnode = iort_get_fwnode(node);
+   if (!iort_fwnode)
+   return NULL;
+
+   ret = arm_smmu_iort_xlate(dev, streamid,
+ iort_fwnode);
+   if (!ret)
+   return fwspec_iommu_get_ops(iort_fwnode);
+   }
+
+   return NULL;
+}
+
+/**
+ * iort_iommu_configure - Set-up IOMMU configuration for a device.
+ *
+ * @dev: device to configure
+ *
+ * Returns: iommu_ops pointer on configuration success
+ *  NULL on configuration failure
+ */
+const struct iommu_ops *iort_iommu_configure(struct device *dev)
+{
+   struct acpi_iort_node *node, *parent;
+   const struct iommu_ops *ops = NULL;
+   u32 streamid = 0;
+
+   if (dev_is_pci(dev)) {
+   struct pci_bus *bus = to_pci_dev(dev)->bus;
+   u32 rid;
+
+   pci_for_each_dma_alias(to_pci_dev(dev), __get_pci_rid,
+  );
+
+   node = iort_scan_node(ACPI_IORT_NODE_PCI_ROOT_COMPLEX,
+ iort_match_node_callback, >dev);
+   if (!node)
+   return NULL;
+
+   parent = iort_node_map_rid(node, rid, ,
+  IORT_IOMMU_TYPE);
+
+   ops = iort_iommu_xlate(dev, parent, streamid);
+
+   } else {
+   int i = 0;
+
+   node = iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT,
+ iort_match_node_callback, dev);
+   if (!node)
+   return NULL;
+
+   parent = iort_node_get_id(node, ,
+ IORT_IOMMU_TYPE, i++);
+
+   while (parent) {
+   ops = iort_iommu_xlate(dev, parent, streamid);
+
+   parent = iort_node_get_id(node, ,
+ IORT_IOMMU_TYPE, i++);
+   }
+   }
+
+   return ops;
+}
+
 static void __init acpi_iort_register_irq(int hwirq, const char *name,
  int trigger,
  struct resource *res)
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 0bdc98e..e875537 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -7,6 +7,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -1377,11 +1378,15 @@ enum dev_dma_attr acpi_get_dma_attr(s

<    1   2   3   4   5   6   7   8   9   10   >