Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH V3 8/8] arm64: dma-mapping: Remove the notifier trick to handle early setting of dma_ops
From: Robin Murphy @ 2016-10-26 15:34 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1475600632-21289-9-git-send-email-sricharan@codeaurora.org>

On 04/10/16 18:03, Sricharan R wrote:
> With arch_setup_dma_ops now being called late during device's probe after the
> device's iommu is probed, the notifier trick required to handle the early
> setup of dma_ops before the iommu group gets created is not required.
> So removing the notifier's here.

Hooray!

> Signed-off-by: Sricharan R <sricharan@codeaurora.org>
> ---
>  arch/arm64/mm/dma-mapping.c | 100 ++------------------------------------------
>  1 file changed, 3 insertions(+), 97 deletions(-)
> 
> diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
> index faf4b92..eb593af 100644
> --- a/arch/arm64/mm/dma-mapping.c
> +++ b/arch/arm64/mm/dma-mapping.c
> @@ -799,24 +799,6 @@ static struct dma_map_ops iommu_dma_ops = {
>  	.mapping_error = iommu_dma_mapping_error,
>  };
>  
> -/*
> - * TODO: Right now __iommu_setup_dma_ops() gets called too early to do
> - * everything it needs to - the device is only partially created and the
> - * IOMMU driver hasn't seen it yet, so it can't have a group. Thus we
> - * need this delayed attachment dance. Once IOMMU probe ordering is sorted
> - * to move the arch_setup_dma_ops() call later, all the notifier bits below
> - * become unnecessary, and will go away.
> - */
> -struct iommu_dma_notifier_data {
> -	struct list_head list;
> -	struct device *dev;
> -	const struct iommu_ops *ops;
> -	u64 dma_base;
> -	u64 size;
> -};
> -static LIST_HEAD(iommu_dma_masters);
> -static DEFINE_MUTEX(iommu_dma_notifier_lock);
> -
>  static bool do_iommu_attach(struct device *dev, const struct iommu_ops *ops,
>  			   u64 dma_base, u64 size)

This should go as well...

>  {
> @@ -837,79 +819,9 @@ static bool do_iommu_attach(struct device *dev, const struct iommu_ops *ops,
>  	return true;
>  }
>  
> -static void queue_iommu_attach(struct device *dev, const struct iommu_ops *ops,
> -			      u64 dma_base, u64 size)
> -{
> -	struct iommu_dma_notifier_data *iommudata;
> -
> -	iommudata = kzalloc(sizeof(*iommudata), GFP_KERNEL);
> -	if (!iommudata)
> -		return;
> -
> -	iommudata->dev = dev;
> -	iommudata->ops = ops;
> -	iommudata->dma_base = dma_base;
> -	iommudata->size = size;
> -
> -	mutex_lock(&iommu_dma_notifier_lock);
> -	list_add(&iommudata->list, &iommu_dma_masters);
> -	mutex_unlock(&iommu_dma_notifier_lock);
> -}
> -
> -static int __iommu_attach_notifier(struct notifier_block *nb,
> -				   unsigned long action, void *data)
> -{
> -	struct iommu_dma_notifier_data *master, *tmp;
> -
> -	if (action != BUS_NOTIFY_BIND_DRIVER)
> -		return 0;
> -
> -	mutex_lock(&iommu_dma_notifier_lock);
> -	list_for_each_entry_safe(master, tmp, &iommu_dma_masters, list) {
> -		if (data == master->dev && do_iommu_attach(master->dev,
> -				master->ops, master->dma_base, master->size)) {
> -			list_del(&master->list);
> -			kfree(master);
> -			break;
> -		}
> -	}
> -	mutex_unlock(&iommu_dma_notifier_lock);
> -	return 0;
> -}
> -
> -static int __init register_iommu_dma_ops_notifier(struct bus_type *bus)
> -{
> -	struct notifier_block *nb = kzalloc(sizeof(*nb), GFP_KERNEL);
> -	int ret;
> -
> -	if (!nb)
> -		return -ENOMEM;
> -
> -	nb->notifier_call = __iommu_attach_notifier;
> -
> -	ret = bus_register_notifier(bus, nb);
> -	if (ret) {
> -		pr_warn("Failed to register DMA domain notifier; IOMMU DMA ops unavailable on bus '%s'\n",
> -			bus->name);
> -		kfree(nb);
> -	}
> -	return ret;
> -}
> -
>  static int __init __iommu_dma_init(void)
>  {
> -	int ret;
> -
> -	ret = iommu_dma_init();
> -	if (!ret)
> -		ret = register_iommu_dma_ops_notifier(&platform_bus_type);
> -	if (!ret)
> -		ret = register_iommu_dma_ops_notifier(&amba_bustype);
> -#ifdef CONFIG_PCI
> -	if (!ret)
> -		ret = register_iommu_dma_ops_notifier(&pci_bus_type);
> -#endif
> -	return ret;
> +	return iommu_dma_init();
>  }
>  arch_initcall(__iommu_dma_init);
>  
> @@ -920,18 +832,12 @@ static void __iommu_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
>  
>  	if (!ops)
>  		return;
> -	/*
> -	 * TODO: As a concession to the future, we're ready to handle being
> -	 * called both early and late (i.e. after bus_add_device). Once all
> -	 * the platform bus code is reworked to call us late and the notifier
> -	 * junk above goes away, move the body of do_iommu_attach here.

...per this commment. It has no need to be a separate function once this
is the only call site (plus it has a misleadingly inaccurate name anyway).

> -	 */
> +
>  	group = iommu_group_get(dev);
> +
>  	if (group) {
>  		do_iommu_attach(dev, ops, dma_base, size);
>  		iommu_group_put(group);
> -	} else {
> -		queue_iommu_attach(dev, ops, dma_base, size);
>  	}
>  }

I overlooked it in the last patch as the relevant context was in the
cover letter, so I'll just add the comment here; the domain check and
WARN_ON() in arch_teardown_dma_ops() is mostly a left-over from the
'fake default domain' bodge that was already gone from the final version
of the arm64 dma_ops series. It's based on the assumption that
arch_teardown_dma_ops() is called after the device is removed from the
bus - I'm not convinced that assumption was ever actually true, it now
doesn't necessarily do anything anyway (since detach_device is
deprecated). I'll spin a cleanup patch for that myself...

Robin.

^ permalink raw reply

* [PATCH v14 7/9] clocksource/drivers/arm_arch_timer: Refactor the timer init code to prepare for GTDT
From: Fu Wei @ 2016-10-26 15:24 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161021113213.GD16630@leverpostej>

Hi Mark,

On 21 October 2016 at 19:32, Mark Rutland <mark.rutland@arm.com> wrote:
> On Thu, Sep 29, 2016 at 02:17:15AM +0800, fu.wei at linaro.org wrote:
>> From: Fu Wei <fu.wei@linaro.org>
>>
>> The patch refactor original memory-mapped timer init code:
>> (1) extract some subfunction for reusing some common code
>>     a. get_cnttidr
>>     b. is_best_frame
>> (2) move base address and irq code for arch_timer_mem to
>> arch_timer_mem_register
>>
>> Signed-off-by: Fu Wei <fu.wei@linaro.org>
>> ---
>>  drivers/clocksource/arm_arch_timer.c | 159 +++++++++++++++++++++--------------
>>  1 file changed, 96 insertions(+), 63 deletions(-)
>>
>> diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
>> index c7b0040..e78095f 100644
>> --- a/drivers/clocksource/arm_arch_timer.c
>> +++ b/drivers/clocksource/arm_arch_timer.c
>> @@ -57,6 +57,7 @@
>>  static unsigned arch_timers_present __initdata;
>>
>>  static void __iomem *arch_counter_base;
>> +static void __iomem *cntctlbase __initdata;
>>
>>  struct arch_timer {
>>       void __iomem *base;
>> @@ -656,15 +657,49 @@ out:
>>       return err;
>>  }
>>
>> -static int __init arch_timer_mem_register(void __iomem *base, unsigned int irq)
>> +static int __init arch_timer_mem_register(struct device_node *np, void *frame)
>>  {
>> -     int ret;
>> -     irq_handler_t func;
>> +     struct device_node *frame_node = NULL;
>>       struct arch_timer *t;
>> +     void __iomem *base;
>> +     irq_handler_t func;
>> +     unsigned int irq;
>> +     int ret;
>> +
>> +     if (!frame)
>> +             return -EINVAL;
>
> Why would we call this without a frame?

Sorry, I just verify it , make sure frame is not NULL,
Because it is a "static" function, so we do need this check?

>
>> +
>> +     if (np) {
>
> ... or without a node?

For "np", for now, we just  just verify it, but it is just paperation
for GTDT support,
Because in next patch, if np == NULL, that means we call this function
from GTDT, but not DT.

>
>> +             frame_node = (struct device_node *)frame;
>> +             base = of_iomap(frame_node, 0);
>> +             arch_timer_detect_rate(base, np);
>
> ... BANG! (we check base too late, below).
>
> Please as Marc requested several versions ago: split the FW parsing
> (ACPI and DT) so that happens first, *then* once we have the data in a
> common format, use that to drive poking the HW, requesting IRQs, etc,
> completely independent of the source.
>
> In patches, do this by:
>
> (1) adding the data structures
> (2) splitting the existing DT probing to use them
> (3) Adding ACPI functionality atop

this patch is a preparation for GTDT support, I have splitted some
functions for reusing them in next patch(GTDT support)

if np == NULL, that means we call this function from GTDT, but
if np != NULL, that means we call this function from DT


>
>> -static int __init arch_timer_mem_init(struct device_node *np)
>> +static int __init get_cnttidr(struct device_node *np, u32 *cnttidr)
>>  {
>> -     struct device_node *frame, *best_frame = NULL;
>> -     void __iomem *cntctlbase, *base;
>> -     unsigned int irq, ret = -EINVAL;
>> -     u32 cnttidr;
>> +     if (!cnttidr)
>> +             return -EINVAL;
>> +
>> +     if (np)
>> +             cntctlbase = of_iomap(np, 0);
>> +     else
>> +             return -EINVAL;
>
> We want to check this for ACPI too, no?

just like I said above, this is a preparation for GTDT support,

So please correct me if I am doing this in the wrong way, thanks :-)

>
> Thanks,
> Mark.



-- 
Best regards,

Fu Wei
Software Engineer
Red Hat

^ permalink raw reply

* [PATCH v2] clocksource/arm_arch_timer: Map frame with of_io_request_and_map()
From: Daniel Lezcano @ 2016-10-26 15:22 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161026073550.22918-1-sboyd@codeaurora.org>

On 26/10/2016 09:35, Stephen Boyd wrote:
> Let's use the of_io_request_and_map() API so that the frame
> region is protected and shows up in /proc/iomem.
> 
> Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
> ---

Applied for 4.10.

Thanks!

  -- Daniel


-- 
 <http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply

* [PATCH v3] drivers: psci: PSCI checker module
From: Paul E. McKenney @ 2016-10-26 15:18 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161026131752.GA15478@red-moon>

On Wed, Oct 26, 2016 at 02:17:52PM +0100, Lorenzo Pieralisi wrote:
> On Tue, Oct 25, 2016 at 11:34:36AM -0700, Paul E. McKenney wrote:
> 
> [...]
> 
> > > > +static int __init psci_checker(void)
> > > > +{
> > > > +	int ret;
> > > > +
> > > > +	/*
> > > > +	 * Since we're in an initcall, we assume that all the CPUs that all
> > > > +	 * CPUs that can be onlined have been onlined.
> > > > +	 *
> > > > +	 * The tests assume that hotplug is enabled but nobody else is using it,
> > > > +	 * otherwise the results will be unpredictable. However, since there
> > > > +	 * is no userspace yet in initcalls, that should be fine.
> > > 
> > > I do not think it is. If you run a kernel with, say,
> > > CONFIG_LOCK_TORTURE_TEST, cpus may disappear from the radar while
> > > running the PSCI checker test itself; that at least would confuse the
> > > checker, and that's just an example.
> > > 
> > > I added Paul to check what are the assumptions behind the torture test
> > > hotplug tests, in particular if there are any implicit assumptions for
> > > it to work (ie it is the only kernel test hotplugging cpus in and out
> > > (?)), what I know is that the PSCI checker assumptions are not correct.
> > 
> > Both CONFIG_LOCK_TORTURE_TEST and CONFIG_RCU_TORTURE_TEST can and will
> > hotplug CPUs.  The locktorture.onoff_holdoff and rcutorture.onoff_holdoff
> > kernel parameters can delay the start of CPU-hotplug testing, and in
> > my testing I set this delay to 30 seconds after boot.
> > 
> > One approach would be to make your test refuse to run if either of
> > the lock/RCU torture tests was running.  Or do what Lorenzo suggests
> > below.  The torture tests aren't crazy enough to offline the last CPU.
> > Though they do try, just for effect, in cases where the last CPU is
> > marked cpu_is_hotpluggable().  ;-)
> 
> Thank you Paul. I have an additional question though. Is there any
> implicit assumption in LOCK/RCU torture tests whereby nothing else
> in the kernel is hotplugging cpus in/out (through cpu_down()/up())
> while they are running ?
> 
> I am asking because that's the main reason behind my query. Those tests
> hotplug cpus in and out through cpu_down/up() but AFAICS nothing
> prevents another piece of code in the kernel to call those functions and
> the tests may just fail in that case (ie trying to cpu_down() a cpu
> that is not online).
> 
> Are false negatives contemplated (or I am missing something) ?

The current code assumes nothing else doing CPU-hotplug operations,
and will therefore print "RCU_HOTPLUG" error (or "LOCK_HOTPLUG" for
locktorture) if any of the hotplug operations failed.

> I just would like to understand if what this patch currently does
> is safe and sound. I think that calling cpu_down() and cpu_up()
> is always safe, but the test can result in false negatives if
> other kernel subsystems (eg LOCK torture test) are calling those
> APIs in parallel (because cpu_down()/cpu_up() calls can fail - eg
> trying to cpu_down() a cpu that is not online any longer, since it
> was taken down by another kernel control path), that's the question
> I have.

I am assuming that these added calls to cpu_down() and cpu_up() aren't
enabled by default.  If they are, rcutorture and locktorture need some
way to turn the off.

So maybe we need to have some sort of API that detects concurrent
CPU-hotplug torturing?  Maybe something like the following?

	static atomic_t n_cpu_hotplug_torturers;
	static atomic_t cpu_hotplug_concurrent_torture;

	void torture_start_cpu_hotplug(void)
	{
		if (atomic_inc_return(&n_cpu_hotplug_torturers) > 1)
			atomic_inc(&cpu_hotplug_concurrent_torture);
	}

	void torture_end_cpu_hotplug(void)
	{
		atomic_dec(&n_cpu_hotplug_torturers);
	}

	bool torture_cpu_hotplug_was_concurrent(void)
	{
		return !!atomic_read(&cpu_hotplug_concurrent_torture);
	}

The locktorture and rcutorture code could then ignore CPU-hotplug
errors that could be caused by concurrent access.  And complain
bitterly about the concurrent access, of course!  ;-)

Or am I missing your point?

							Thanx, Paul

> Thanks !
> Lorenzo
> 
> > 
> > 						Thanx, Paul
> > 
> > > There is something simple you can do to get this "fixed".
> > > 
> > > You can use the new API James implemented for hibernate,
> > > that allows you to disable (ie PSCI CPU OFF) all "secondary" cpus
> > > other than the primary one passed in as parameter:
> > > 
> > > freeze_secondary_cpus(int primary);
> > > 
> > > that function will _cpu_down() all online cpus other than "primary"
> > > in one go, without any interference allowed from other bits of the
> > > kernel. It requires an enable_nonboot_cpus() counterpart, and you
> > > can do that for every online cpus you detect (actually you can even
> > > avoid using the online cpu mask and use the present mask to carry
> > > out the test). If there is a resident trusted OS you can just
> > > trigger the test with primary == tos_resident_cpu, since all
> > > others are bound to fail (well, you can run them and check they
> > > do fail, it is a checker after all).
> > > 
> > > You would lose the capability of hotplugging a "cluster" at a time, but
> > > I do not think it is a big problem, the test above would cover it
> > > and more importantly, it is safe to execute.
> > > 
> > > Or we can augment the torture test API to restrict the cpumask
> > > it actually uses to offline/online cpus (I am referring to
> > > torture_onoff(), kernel/torture.c).
> > > 
> > > Further comments appreciated since I am not sure I grokked the
> > > assumption the torture tests make about hotplugging cpus in and out,
> > > I will go through the commits logs again to find more info.
> > > 
> > > Thanks !
> > > Lorenzo
> > > 
> > > > +	 */
> > > > +	nb_available_cpus = num_online_cpus();
> > > > +
> > > > +	/* Check PSCI operations are set up and working. */
> > > > +	ret = psci_ops_check();
> > > > +	if (ret)
> > > > +		return ret;
> > > > +
> > > > +	pr_info("PSCI checker started using %u CPUs\n", nb_available_cpus);
> > > > +
> > > > +	pr_info("Starting hotplug tests\n");
> > > > +	ret = hotplug_tests();
> > > > +	if (ret == 0)
> > > > +		pr_info("Hotplug tests passed OK\n");
> > > > +	else if (ret > 0)
> > > > +		pr_err("%d error(s) encountered in hotplug tests\n", ret);
> > > > +	else {
> > > > +		pr_err("Out of memory\n");
> > > > +		return ret;
> > > > +	}
> > > > +
> > > > +	pr_info("Starting suspend tests (%d cycles per state)\n",
> > > > +		NUM_SUSPEND_CYCLE);
> > > > +	ret = suspend_tests();
> > > > +	if (ret == 0)
> > > > +		pr_info("Suspend tests passed OK\n");
> > > > +	else if (ret > 0)
> > > > +		pr_err("%d error(s) encountered in suspend tests\n", ret);
> > > > +	else {
> > > > +		switch (ret) {
> > > > +		case -ENOMEM:
> > > > +			pr_err("Out of memory\n");
> > > > +			break;
> > > > +		case -ENODEV:
> > > > +			pr_warn("Could not start suspend tests on any CPU\n");
> > > > +			break;
> > > > +		}
> > > > +	}
> > > > +
> > > > +	pr_info("PSCI checker completed\n");
> > > > +	return ret < 0 ? ret : 0;
> > > > +}
> > > > +late_initcall(psci_checker);
> > > > -- 
> > > > 2.10.0
> > > > 
> > > 
> > 
> 

^ permalink raw reply

* [PATCH 3/4] mfd: altr-a10sr: Add Arria10 SR Monitor
From: Thor Thayer @ 2016-10-26 15:18 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161026125233.GL11267@dell>



On 10/26/2016 07:52 AM, Lee Jones wrote:
> On Thu, 13 Oct 2016, tthayer at opensource.altera.com wrote:
>
>> From: Thor Thayer <tthayer@opensource.altera.com>
>>
>> Add the Altera Arria10 DevKit System Resource Monitor functionality
>> to the MFD device.
>>
>> Signed-off-by: Thor Thayer <tthayer@opensource.altera.com>
>> ---
>>  drivers/mfd/altera-a10sr.c |    4 ++++
>>  1 file changed, 4 insertions(+)
>>
>> diff --git a/drivers/mfd/altera-a10sr.c b/drivers/mfd/altera-a10sr.c
>> index 06e1f7f..0942d7d 100644
>> --- a/drivers/mfd/altera-a10sr.c
>> +++ b/drivers/mfd/altera-a10sr.c
>> @@ -33,6 +33,10 @@
>>  		.name = "altr_a10sr_gpio",
>>  		.of_compatible = "altr,a10sr-gpio",
>>  	},
>> +	{
>> +		.name = "altr_a10sr_mon",
>> +		.of_compatible = "altr,a10sr-mon",
>
> "-monitor" would be better in my opinion.
>

OK. I'm flexible and it is clearer. I'll make the changes and resubmit.
Thanks for reviewing!

>> +	},
>>  };
>>
>>  static bool altr_a10sr_reg_readable(struct device *dev, unsigned int reg)
>

^ permalink raw reply

* [PATCH 5/5] ARM: OMAP5: Enable minimal cpuidle for omap5 retention
From: Tony Lindgren @ 2016-10-26 15:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161026151703.24730-1-tony@atomide.com>

This allows the CPUs to enter retention during idle and takes the idle
power consumption down quite a bit. On omap5-uevm, the power consumption
eventually settles down to about 920mW with ehci-omap and ohci-omap3
unloaded compared to about 1.7W without these patches. Note that it
seems to take few minutes after booting for the idle power to go down
to 920mW from 1.3W, no idea so far what might be causing that.

Note that the TI kernel supports more modes in the v3.8 kernel, but
the omap5 specific states can be added later.

Signed-off-by: Tony Lindgren <tony@atomide.com>
---
 arch/arm/mach-omap2/cpuidle44xx.c | 2 +-
 arch/arm/mach-omap2/pm44xx.c      | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c
--- a/arch/arm/mach-omap2/cpuidle44xx.c
+++ b/arch/arm/mach-omap2/cpuidle44xx.c
@@ -300,7 +300,7 @@ int __init omap4_idle_init(void)
 {
 	struct cpuidle_driver *idle_driver;
 
-	if (soc_is_dra7xx()) {
+	if (soc_is_dra7xx() || soc_is_omap54xx()) {
 		state_ptr = &dra7_idle_data[0];
 		idle_driver = &dra7_idle_driver;
 	} else {
diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c
--- a/arch/arm/mach-omap2/pm44xx.c
+++ b/arch/arm/mach-omap2/pm44xx.c
@@ -287,7 +287,7 @@ int __init omap4_pm_init(void)
 	/* Overwrite the default cpu_do_idle() */
 	arm_pm_idle = omap_default_idle;
 
-	if (cpu_is_omap44xx() || soc_is_dra7xx())
+	if (cpu_is_omap44xx() || soc_is_omap54xx() || soc_is_dra7xx())
 		omap4_idle_init();
 
 err2:
-- 
2.9.3

^ permalink raw reply

* [PATCH 4/5] ARM: DRA7: PM: cpuidle MPU CSWR support
From: Tony Lindgren @ 2016-10-26 15:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161026151703.24730-1-tony@atomide.com>

From: Santosh Shilimkar <santosh.shilimkar@ti.com>

Add DRA74/72 CPUIDLE support.

This patch adds MPUSS low power states in cpuidle.

        C1 - CPU0 WFI + CPU1 WFI + MPU ON
        C2 - CPU0 RET + CPU1 RET + MPU CSWR

Tested on DRA74/72-EVM for C1 and C2 states.

NOTE: DRA7 does not do voltage scaling as part of retention transition
and has Mercury which speeds up transition paths - Latency numbers are
based on measurements done by toggling GPIOs.

Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
[ j-keerthy at ti.com rework on 3.14]
Signed-off-by: Keerthy <j-keerthy@ti.com>
[nm at ti.com: updates based on profiling]
[tony at atomide.com: dropped CPUIDLE_FLAG_TIME_VALID no longer used]
Signed-off-by: Nishanth Menon <nm@ti.com>
---
 arch/arm/mach-omap2/cpuidle44xx.c | 80 ++++++++++++++++++++++++++++++++++++++-
 arch/arm/mach-omap2/pm44xx.c      |  2 +-
 2 files changed, 80 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c
--- a/arch/arm/mach-omap2/cpuidle44xx.c
+++ b/arch/arm/mach-omap2/cpuidle44xx.c
@@ -21,6 +21,7 @@
 #include "common.h"
 #include "pm.h"
 #include "prm.h"
+#include "soc.h"
 #include "clockdomain.h"
 
 #define MAX_CPUS	2
@@ -30,6 +31,7 @@ struct idle_statedata {
 	u32 cpu_state;
 	u32 mpu_logic_state;
 	u32 mpu_state;
+	u32 mpu_state_vote;
 };
 
 static struct idle_statedata omap4_idle_data[] = {
@@ -50,12 +52,26 @@ static struct idle_statedata omap4_idle_data[] = {
 	},
 };
 
+static struct idle_statedata dra7_idle_data[] = {
+	{
+		.cpu_state = PWRDM_POWER_ON,
+		.mpu_state = PWRDM_POWER_ON,
+		.mpu_logic_state = PWRDM_POWER_ON,
+	},
+	{
+		.cpu_state = PWRDM_POWER_RET,
+		.mpu_state = PWRDM_POWER_RET,
+		.mpu_logic_state = PWRDM_POWER_RET,
+	},
+};
+
 static struct powerdomain *mpu_pd, *cpu_pd[MAX_CPUS];
 static struct clockdomain *cpu_clkdm[MAX_CPUS];
 
 static atomic_t abort_barrier;
 static bool cpu_done[MAX_CPUS];
 static struct idle_statedata *state_ptr = &omap4_idle_data[0];
+static DEFINE_RAW_SPINLOCK(mpu_lock);
 
 /* Private functions */
 
@@ -77,6 +93,32 @@ static int omap_enter_idle_simple(struct cpuidle_device *dev,
 	return index;
 }
 
+static int omap_enter_idle_smp(struct cpuidle_device *dev,
+			       struct cpuidle_driver *drv,
+			       int index)
+{
+	struct idle_statedata *cx = state_ptr + index;
+	unsigned long flag;
+
+	raw_spin_lock_irqsave(&mpu_lock, flag);
+	cx->mpu_state_vote++;
+	if (cx->mpu_state_vote == num_online_cpus()) {
+		pwrdm_set_logic_retst(mpu_pd, cx->mpu_logic_state);
+		omap_set_pwrdm_state(mpu_pd, cx->mpu_state);
+	}
+	raw_spin_unlock_irqrestore(&mpu_lock, flag);
+
+	omap4_enter_lowpower(dev->cpu, cx->cpu_state);
+
+	raw_spin_lock_irqsave(&mpu_lock, flag);
+	if (cx->mpu_state_vote == num_online_cpus())
+		omap_set_pwrdm_state(mpu_pd, PWRDM_POWER_ON);
+	cx->mpu_state_vote--;
+	raw_spin_unlock_irqrestore(&mpu_lock, flag);
+
+	return index;
+}
+
 static int omap_enter_idle_coupled(struct cpuidle_device *dev,
 			struct cpuidle_driver *drv,
 			int index)
@@ -220,6 +262,32 @@ static struct cpuidle_driver omap4_idle_driver = {
 	.safe_state_index = 0,
 };
 
+static struct cpuidle_driver dra7_idle_driver = {
+	.name				= "dra7_idle",
+	.owner				= THIS_MODULE,
+	.states = {
+		{
+			/* C1 - CPU0 ON + CPU1 ON + MPU ON */
+			.exit_latency = 2 + 2,
+			.target_residency = 5,
+			.enter = omap_enter_idle_simple,
+			.name = "C1",
+			.desc = "CPUx WFI, MPUSS ON"
+		},
+		{
+			/* C2 - CPU0 RET + CPU1 RET + MPU CSWR */
+			.exit_latency = 48 + 60,
+			.target_residency = 100,
+			.flags = CPUIDLE_FLAG_TIMER_STOP,
+			.enter = omap_enter_idle_smp,
+			.name = "C2",
+			.desc = "CPUx CSWR, MPUSS CSWR",
+		},
+	},
+	.state_count = ARRAY_SIZE(dra7_idle_data),
+	.safe_state_index = 0,
+};
+
 /* Public functions */
 
 /**
@@ -230,6 +298,16 @@ static struct cpuidle_driver omap4_idle_driver = {
  */
 int __init omap4_idle_init(void)
 {
+	struct cpuidle_driver *idle_driver;
+
+	if (soc_is_dra7xx()) {
+		state_ptr = &dra7_idle_data[0];
+		idle_driver = &dra7_idle_driver;
+	} else {
+		state_ptr = &omap4_idle_data[0];
+		idle_driver = &omap4_idle_driver;
+	}
+
 	mpu_pd = pwrdm_lookup("mpu_pwrdm");
 	cpu_pd[0] = pwrdm_lookup("cpu0_pwrdm");
 	cpu_pd[1] = pwrdm_lookup("cpu1_pwrdm");
@@ -244,5 +322,5 @@ int __init omap4_idle_init(void)
 	/* Configure the broadcast timer on each cpu */
 	on_each_cpu(omap_setup_broadcast_timer, NULL, 1);
 
-	return cpuidle_register(&omap4_idle_driver, cpu_online_mask);
+	return cpuidle_register(idle_driver, cpu_online_mask);
 }
diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c
--- a/arch/arm/mach-omap2/pm44xx.c
+++ b/arch/arm/mach-omap2/pm44xx.c
@@ -287,7 +287,7 @@ int __init omap4_pm_init(void)
 	/* Overwrite the default cpu_do_idle() */
 	arm_pm_idle = omap_default_idle;
 
-	if (cpu_is_omap44xx())
+	if (cpu_is_omap44xx() || soc_is_dra7xx())
 		omap4_idle_init();
 
 err2:
-- 
2.9.3

^ permalink raw reply

* [PATCH 3/5] ARM: OMAP4+: Fix bad fallthrough for cpuidle
From: Tony Lindgren @ 2016-10-26 15:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161026151703.24730-1-tony@atomide.com>

We don't want to fall through to a bunch of errors for retention
if PM_OMAP4_CPU_OSWR_DISABLE is not configured for a SoC.

Fixes: 6099dd37c669 ("ARM: OMAP5 / DRA7: Enable CPU RET on suspend")
Signed-off-by: Tony Lindgren <tony@atomide.com>
---
 arch/arm/mach-omap2/omap-mpuss-lowpower.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
--- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
+++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
@@ -244,10 +244,9 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
 		save_state = 1;
 		break;
 	case PWRDM_POWER_RET:
-		if (IS_PM44XX_ERRATUM(PM_OMAP4_CPU_OSWR_DISABLE)) {
+		if (IS_PM44XX_ERRATUM(PM_OMAP4_CPU_OSWR_DISABLE))
 			save_state = 0;
-			break;
-		}
+		break;
 	default:
 		/*
 		 * CPUx CSWR is invalid hardware state. Also CPUx OSWR
-- 
2.9.3

^ permalink raw reply

* [PATCH 2/5] ARM: OMAP5: Fix mpuss_early_init
From: Tony Lindgren @ 2016-10-26 15:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161026151703.24730-1-tony@atomide.com>

We need to properly initialize mpuss also on omap5 like we do on omap4.
Otherwise we run into similar kexec problems like we had on omap4 when
trying to kexec from a kernel with PM initialized.

Fixes: 0573b957fc21 ("ARM: OMAP4+: Prevent CPU1 related hang with kexec")
Signed-off-by: Tony Lindgren <tony@atomide.com>
---
 arch/arm/mach-omap2/io.c                  |  3 ++-
 arch/arm/mach-omap2/omap-mpuss-lowpower.c | 28 +++++++++++++++++++++-------
 arch/arm/mach-omap2/omap4-sar-layout.h    |  2 ++
 3 files changed, 25 insertions(+), 8 deletions(-)

diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -717,10 +717,11 @@ void __init omap5_init_early(void)
 			      OMAP2_L4_IO_ADDRESS(OMAP54XX_SCM_BASE));
 	omap2_set_globals_prcm_mpu(OMAP2_L4_IO_ADDRESS(OMAP54XX_PRCM_MPU_BASE));
 	omap2_control_base_init();
-	omap4_pm_init_early();
 	omap2_prcm_base_init();
 	omap5xxx_check_revision();
 	omap4_sar_ram_init();
+	omap4_mpuss_early_init();
+	omap4_pm_init_early();
 	omap54xx_voltagedomains_init();
 	omap54xx_powerdomains_init();
 	omap54xx_clockdomains_init();
diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
--- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
+++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
@@ -371,8 +371,12 @@ int __init omap4_mpuss_init(void)
 	pm_info = &per_cpu(omap4_pm_info, 0x0);
 	if (sar_base) {
 		pm_info->scu_sar_addr = sar_base + SCU_OFFSET0;
-		pm_info->wkup_sar_addr = sar_base +
-					CPU0_WAKEUP_NS_PA_ADDR_OFFSET;
+		if (cpu_is_omap44xx())
+			pm_info->wkup_sar_addr = sar_base +
+				CPU0_WAKEUP_NS_PA_ADDR_OFFSET;
+		else
+			pm_info->wkup_sar_addr = sar_base +
+				OMAP5_CPU0_WAKEUP_NS_PA_ADDR_OFFSET;
 		pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET0;
 	}
 	pm_info->pwrdm = pwrdm_lookup("cpu0_pwrdm");
@@ -391,8 +395,12 @@ int __init omap4_mpuss_init(void)
 	pm_info = &per_cpu(omap4_pm_info, 0x1);
 	if (sar_base) {
 		pm_info->scu_sar_addr = sar_base + SCU_OFFSET1;
-		pm_info->wkup_sar_addr = sar_base +
-					CPU1_WAKEUP_NS_PA_ADDR_OFFSET;
+		if (cpu_is_omap44xx())
+			pm_info->wkup_sar_addr = sar_base +
+				CPU1_WAKEUP_NS_PA_ADDR_OFFSET;
+		else
+			pm_info->wkup_sar_addr = sar_base +
+				OMAP5_CPU1_WAKEUP_NS_PA_ADDR_OFFSET;
 		pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET1;
 	}
 
@@ -453,15 +461,21 @@ void __init omap4_mpuss_early_init(void)
 {
 	unsigned long startup_pa;
 
-	if (!cpu_is_omap44xx())
+	if (!(cpu_is_omap44xx() || soc_is_omap54xx()))
 		return;
 
 	sar_base = omap4_get_sar_ram_base();
 
 	if (cpu_is_omap443x())
 		startup_pa = virt_to_phys(omap4_secondary_startup);
-	else
+	else if (cpu_is_omap446x())
 		startup_pa = virt_to_phys(omap4460_secondary_startup);
+	else
+		startup_pa = virt_to_phys(omap5_secondary_startup);
 
-	writel_relaxed(startup_pa, sar_base + CPU1_WAKEUP_NS_PA_ADDR_OFFSET);
+	if (cpu_is_omap44xx())
+		writel_relaxed(startup_pa, sar_base + CPU1_WAKEUP_NS_PA_ADDR_OFFSET);
+	else
+		writel_relaxed(startup_pa, sar_base +
+			       OMAP5_CPU1_WAKEUP_NS_PA_ADDR_OFFSET);
 }
diff --git a/arch/arm/mach-omap2/omap4-sar-layout.h b/arch/arm/mach-omap2/omap4-sar-layout.h
--- a/arch/arm/mach-omap2/omap4-sar-layout.h
+++ b/arch/arm/mach-omap2/omap4-sar-layout.h
@@ -31,6 +31,8 @@
 /* CPUx Wakeup Non-Secure Physical Address offsets in SAR_BANK3 */
 #define CPU0_WAKEUP_NS_PA_ADDR_OFFSET		0xa04
 #define CPU1_WAKEUP_NS_PA_ADDR_OFFSET		0xa08
+#define OMAP5_CPU0_WAKEUP_NS_PA_ADDR_OFFSET	0xe00
+#define OMAP5_CPU1_WAKEUP_NS_PA_ADDR_OFFSET	0xe04
 
 #define SAR_BACKUP_STATUS_OFFSET		(SAR_BANK3_OFFSET + 0x500)
 #define SAR_SECURE_RAM_SIZE_OFFSET		(SAR_BANK3_OFFSET + 0x504)
-- 
2.9.3

^ permalink raw reply

* [PATCH 1/5] ARM: OMAP5: Fix build for PM code
From: Tony Lindgren @ 2016-10-26 15:16 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161026151703.24730-1-tony@atomide.com>

It's CONFIG_SOC_OMAP5, not CONFIG_ARCH_OMAP5. Looks like make randconfig
builds have not hit this one yet.

Fixes: b3bf289c1c45 ("ARM: OMAP2+: Fix build with CONFIG_SMP and CONFIG_PM
is not set")
Signed-off-by: Tony Lindgren <tony@atomide.com>
---
 arch/arm/mach-omap2/Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -80,7 +80,7 @@ endif
 # Power Management
 omap-4-5-pm-common			= omap-mpuss-lowpower.o
 obj-$(CONFIG_ARCH_OMAP4)		+= $(omap-4-5-pm-common)
-obj-$(CONFIG_ARCH_OMAP5)		+= $(omap-4-5-pm-common)
+obj-$(CONFIG_SOC_OMAP5)			+= $(omap-4-5-pm-common)
 obj-$(CONFIG_OMAP_PM_NOOP)		+= omap-pm-noop.o
 
 ifeq ($(CONFIG_PM),y)
-- 
2.9.3

^ permalink raw reply

* [PATCH 0/5] Minimal cpuidle fixes for omap5 and dra7
From: Tony Lindgren @ 2016-10-26 15:16 UTC (permalink / raw)
  To: linux-arm-kernel

Hi all,

Here are some fixes to get minimal cpuidle support working with omap5
and dra7. Not sure if there are still some unsorted issues on enabling
this on dra7, but at least omap5 has been behving for me for few
weeks with these.

Regards,

Tony


Santosh Shilimkar (1):
  ARM: DRA7: PM: cpuidle MPU CSWR support

Tony Lindgren (4):
  ARM: OMAP5: Fix build for PM code
  ARM: OMAP5: Fix mpuss_early_init
  ARM: OMAP4+: Fix bad fallthrough for cpuidle
  ARM: OMAP5: Enable minimal cpuidle for omap5 retention

 arch/arm/mach-omap2/Makefile              |  2 +-
 arch/arm/mach-omap2/cpuidle44xx.c         | 80 ++++++++++++++++++++++++++++++-
 arch/arm/mach-omap2/io.c                  |  3 +-
 arch/arm/mach-omap2/omap-mpuss-lowpower.c | 33 +++++++++----
 arch/arm/mach-omap2/omap4-sar-layout.h    |  2 +
 arch/arm/mach-omap2/pm44xx.c              |  2 +-
 6 files changed, 108 insertions(+), 14 deletions(-)

-- 
2.9.3

^ permalink raw reply

* [PATCH V3 7/8] arm/arm64: dma-mapping: Call iommu's remove_device callback during device detach
From: Robin Murphy @ 2016-10-26 15:16 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1475600632-21289-8-git-send-email-sricharan@codeaurora.org>

On 04/10/16 18:03, Sricharan R wrote:
> dma_deconfigure calls arch_teardown_dma_ops in the device_detach path,
> which is called when the device gets detached from the driver.
> When the device was added, iommu's add_device callback was used to
> add the device in to its iommu_group and setup the device to be ready
> to use its iommu. Similarly, call remove_device callback to remove the
> device from the group and reset any other device's iommu configurations.
> 
> Signed-off-by: Sricharan R <sricharan@codeaurora.org>
> ---
>  arch/arm/mm/dma-mapping.c   | 8 ++++++++
>  arch/arm64/mm/dma-mapping.c | 7 +++++++
>  2 files changed, 15 insertions(+)
> 
> diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
> index b9191f0..cbe22de 100644
> --- a/arch/arm/mm/dma-mapping.c
> +++ b/arch/arm/mm/dma-mapping.c
> @@ -2289,11 +2289,19 @@ static bool arm_setup_iommu_dma_ops(struct device *dev, u64 dma_base, u64 size,
>  static void arm_teardown_iommu_dma_ops(struct device *dev)
>  {
>  	struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
> +	const struct iommu_ops *ops;
>  
>  	if (!mapping)
>  		return;
>  
>  	__arm_iommu_detach_device(dev);
> +
> +	if (dev->iommu_fwspec) {
> +		ops = dev->iommu_fwspec->ops;
> +		if (ops->remove_device)
> +			ops->remove_device(dev);
> +	}
> +

Yuck. It's a little unfortunate that we have to do this at all, but I
see why. Still, it should be done in common code, not duplicated across
arch code, not least for symmetry with where the matching add_device
happened (although I think of_dma_deconfigure() would suffice, I'm not
sure we really need to add an of_iommu_deconfigure() just for this).

It's also broken for IOMMU drivers which rely on the
of_iommu_configure() mechanism but have not yet been converted to use
iommu_fwspec (Exynos, MSM, etc.)

Robin.

>  	arm_iommu_release_mapping(mapping);
>  	set_dma_ops(dev, NULL);
>  }
> diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
> index 610d8e5..faf4b92 100644
> --- a/arch/arm64/mm/dma-mapping.c
> +++ b/arch/arm64/mm/dma-mapping.c
> @@ -938,6 +938,13 @@ static void __iommu_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
>  void arch_teardown_dma_ops(struct device *dev)
>  {
>  	struct iommu_domain *domain = iommu_get_domain_for_dev(dev);
> +	const struct iommu_ops *ops;
> +
> +	if (dev->iommu_fwspec) {
> +		ops = dev->iommu_fwspec->ops;
> +		if (ops->remove_device)
> +			ops->remove_device(dev);
> +	}
>  
>  	if (WARN_ON(domain))
>  		iommu_detach_device(domain, dev);
> 

^ permalink raw reply

* [PATCH 5/5] ARM: configs: Add new config fragment to change RAM size
From: Alexandre TORGUE @ 2016-10-26 15:11 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477494683-29890-1-git-send-email-alexandre.torgue@st.com>

Signed-off-by: Alexandre TORGUE <alexandre.torgue@st.com>

diff --git a/arch/arm/configs/dram_size_0x2000000.config b/arch/arm/configs/dram_size_0x2000000.config
new file mode 100644
index 0000000..e66430d
--- /dev/null
+++ b/arch/arm/configs/dram_size_0x2000000.config
@@ -0,0 +1 @@
+CONFIG_DRAM_SIZE=0x002000000
-- 
1.9.1

^ permalink raw reply related

* [PATCH 4/5] ARM: configs: Add new config fragment to change RAM start point
From: Alexandre TORGUE @ 2016-10-26 15:11 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477494683-29890-1-git-send-email-alexandre.torgue@st.com>

Signed-off-by: Alexandre TORGUE <alexandre.torgue@st.com>

diff --git a/arch/arm/configs/dram_0xc0000000.config b/arch/arm/configs/dram_0xc0000000.config
new file mode 100644
index 0000000..343d533
--- /dev/null
+++ b/arch/arm/configs/dram_0xc0000000.config
@@ -0,0 +1 @@
+CONFIG_DRAM_BASE=0xc0000000
-- 
1.9.1

^ permalink raw reply related

* [PATCH 3/5] ARM: dts: Add STM32F746 MCU and STM32746g-EVAL board
From: Alexandre TORGUE @ 2016-10-26 15:11 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477494683-29890-1-git-send-email-alexandre.torgue@st.com>

The STMicrolectornics's STM32F746 MCU has the following main features:
 - Cortex-M7 core running up to @216MHz
 - 1MB internal flash, 320KBytes internal RAM (+4KB of backup SRAM)
 - FMC controller to connect SDRAM, NOR and NAND memories
 - Dual mode QSPI
 - SD/MMC/SDIO support
 - Ethernet controller
 - USB OTFG FS & HS controllers
 - I2C, SPI, CAN busses support
 - Several 16 & 32 bits general purpose timers
 - Serial Audio interface
 - LCD controller
 - HDMI-CEC
 - SPDIFRX

Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
Signed-off-by: Alexandre TORGUE <alexandre.torgue@st.com>

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index befcd26..343dda2 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -721,7 +721,8 @@ dtb-$(CONFIG_ARCH_STI) += \
 dtb-$(CONFIG_ARCH_STM32)+= \
 	stm32f429-disco.dtb \
 	stm32f469-disco.dtb \
-	stm32429i-eval.dtb
+	stm32429i-eval.dtb \
+	stm32746g-eval.dtb
 dtb-$(CONFIG_MACH_SUN4I) += \
 	sun4i-a10-a1000.dtb \
 	sun4i-a10-ba10-tvbox.dtb \
diff --git a/arch/arm/boot/dts/stm32746g-eval.dts b/arch/arm/boot/dts/stm32746g-eval.dts
new file mode 100644
index 0000000..aa03fac
--- /dev/null
+++ b/arch/arm/boot/dts/stm32746g-eval.dts
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2015 - Maxime Coquelin <mcoquelin.stm32@gmail.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This file 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.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "stm32f746.dtsi"
+#include <dt-bindings/input/input.h>
+
+/ {
+	model = "STMicroelectronics STM32746g-EVAL board";
+	compatible = "st,stm32746g-eval", "st,stm32f746";
+
+	chosen {
+		bootargs = "root=/dev/ram";
+		stdout-path = "serial0:115200n8";
+	};
+
+	memory {
+		reg = <0xc0000000 0x2000000>;
+	};
+
+	aliases {
+		serial0 = &usart1;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+		green {
+			gpios = <&gpiof 10 1>;
+			linux,default-trigger = "heartbeat";
+		};
+		red {
+			gpios = <&gpiob 7 1>;
+		};
+	};
+
+	gpio_keys {
+		compatible = "gpio-keys";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		autorepeat;
+		button at 0 {
+			label = "Wake up";
+			linux,code = <KEY_WAKEUP>;
+			gpios = <&gpioc 13 0>;
+		};
+	};
+};
+
+&clk_hse {
+	clock-frequency = <25000000>;
+};
+
+&usart1 {
+	pinctrl-0 = <&usart1_pins_a>;
+	pinctrl-names = "default";
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/stm32f746.dtsi b/arch/arm/boot/dts/stm32f746.dtsi
new file mode 100644
index 0000000..f321ffe
--- /dev/null
+++ b/arch/arm/boot/dts/stm32f746.dtsi
@@ -0,0 +1,304 @@
+/*
+ * Copyright 2015 - Maxime Coquelin <mcoquelin.stm32@gmail.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This file 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.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "skeleton.dtsi"
+#include "armv7-m.dtsi"
+#include <dt-bindings/pinctrl/stm32f746-pinfunc.h>
+
+/ {
+	clocks {
+		clk_hse: clk-hse {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <0>;
+		};
+	};
+
+	soc {
+		timer2: timer at 40000000 {
+			compatible = "st,stm32-timer";
+			reg = <0x40000000 0x400>;
+			interrupts = <28>;
+			clocks = <&rcc 0 128>;
+			status = "disabled";
+		};
+
+		timer3: timer at 40000400 {
+			compatible = "st,stm32-timer";
+			reg = <0x40000400 0x400>;
+			interrupts = <29>;
+			clocks = <&rcc 0 129>;
+			status = "disabled";
+		};
+
+		timer4: timer at 40000800 {
+			compatible = "st,stm32-timer";
+			reg = <0x40000800 0x400>;
+			interrupts = <30>;
+			clocks = <&rcc 0 130>;
+			status = "disabled";
+		};
+
+		timer5: timer at 40000c00 {
+			compatible = "st,stm32-timer";
+			reg = <0x40000c00 0x400>;
+			interrupts = <50>;
+			clocks = <&rcc 0 131>;
+		};
+
+		timer6: timer at 40001000 {
+			compatible = "st,stm32-timer";
+			reg = <0x40001000 0x400>;
+			interrupts = <54>;
+			clocks = <&rcc 0 132>;
+			status = "disabled";
+		};
+
+		timer7: timer at 40001400 {
+			compatible = "st,stm32-timer";
+			reg = <0x40001400 0x400>;
+			interrupts = <55>;
+			clocks = <&rcc 0 133>;
+			status = "disabled";
+		};
+
+		usart2: serial at 40004400 {
+			compatible = "st,stm32f7-usart", "st,stm32f7-uart";
+			reg = <0x40004400 0x400>;
+			interrupts = <38>;
+			clocks =  <&rcc 0 145>;
+			status = "disabled";
+		};
+
+		usart3: serial at 40004800 {
+			compatible = "st,stm32f7-usart", "st,stm32f7-uart";
+			reg = <0x40004800 0x400>;
+			interrupts = <39>;
+			clocks = <&rcc 0 146>;
+			status = "disabled";
+		};
+
+		usart4: serial at 40004c00 {
+			compatible = "st,stm32f7-uart";
+			reg = <0x40004c00 0x400>;
+			interrupts = <52>;
+			clocks = <&rcc 0 147>;
+			status = "disabled";
+		};
+
+		usart5: serial at 40005000 {
+			compatible = "st,stm32f7-uart";
+			reg = <0x40005000 0x400>;
+			interrupts = <53>;
+			clocks = <&rcc 0 148>;
+			status = "disabled";
+		};
+
+		usart7: serial at 40007800 {
+			compatible = "st,stm32f7-usart", "st,stm32f7-uart";
+			reg = <0x40007800 0x400>;
+			interrupts = <82>;
+			clocks = <&rcc 0 158>;
+			status = "disabled";
+		};
+
+		usart8: serial at 40007c00 {
+			compatible = "st,stm32f7-usart", "st,stm32f7-uart";
+			reg = <0x40007c00 0x400>;
+			interrupts = <83>;
+			clocks = <&rcc 0 159>;
+			status = "disabled";
+		};
+
+		usart1: serial at 40011000 {
+			compatible = "st,stm32f7-usart", "st,stm32f7-uart";
+			reg = <0x40011000 0x400>;
+			interrupts = <37>;
+			clocks = <&rcc 0 164>;
+			status = "disabled";
+		};
+
+		usart6: serial at 40011400 {
+			compatible = "st,stm32f7-usart", "st,stm32f7-uart";
+			reg = <0x40011400 0x400>;
+			interrupts = <71>;
+			clocks = <&rcc 0 165>;
+			status = "disabled";
+		};
+
+		syscfg: system-config at 40013800 {
+			compatible = "syscon";
+			reg = <0x40013800 0x400>;
+		};
+
+		exti: interrupt-controller at 40013c00 {
+			compatible = "st,stm32-exti";
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			reg = <0x40013C00 0x400>;
+			interrupts = <1>, <2>, <3>, <6>, <7>, <8>, <9>, <10>, <23>, <40>, <41>, <42>, <62>, <76>;
+		};
+
+		pin-controller {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "st,stm32f746-pinctrl";
+			ranges = <0 0x40020000 0x3000>;
+			interrupt-parent = <&exti>;
+			st,syscfg = <&syscfg 0x8>;
+			pins-are-numbered;
+
+			gpioa: gpio at 40020000 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				reg = <0x0 0x400>;
+				clocks = <&rcc 0 256>;
+				st,bank-name = "GPIOA";
+			};
+
+			gpiob: gpio at 40020400 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				reg = <0x400 0x400>;
+				clocks = <&rcc 0 257>;
+				st,bank-name = "GPIOB";
+			};
+
+			gpioc: gpio at 40020800 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				reg = <0x800 0x400>;
+				clocks = <&rcc 0 258>;
+				st,bank-name = "GPIOC";
+			};
+
+			gpiod: gpio at 40020c00 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				reg = <0xc00 0x400>;
+				clocks = <&rcc 0 259>;
+				st,bank-name = "GPIOD";
+			};
+
+			gpioe: gpio at 40021000 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				reg = <0x1000 0x400>;
+				clocks = <&rcc 0 260>;
+				st,bank-name = "GPIOE";
+			};
+
+			gpiof: gpio at 40021400 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				reg = <0x1400 0x400>;
+				clocks = <&rcc 0 261>;
+				st,bank-name = "GPIOF";
+			};
+
+			gpiog: gpio at 40021800 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				reg = <0x1800 0x400>;
+				clocks = <&rcc 0 262>;
+				st,bank-name = "GPIOG";
+			};
+
+			gpioh: gpio at 40021c00 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				reg = <0x1c00 0x400>;
+				clocks = <&rcc 0 263>;
+				st,bank-name = "GPIOH";
+			};
+
+			gpioi: gpio at 40022000 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				reg = <0x2000 0x400>;
+				clocks = <&rcc 0 264>;
+				st,bank-name = "GPIOI";
+			};
+
+			gpioj: gpio at 40022400 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				reg = <0x2400 0x400>;
+				clocks = <&rcc 0 265>;
+				st,bank-name = "GPIOJ";
+			};
+
+			gpiok: gpio at 40022800 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				reg = <0x2800 0x400>;
+				clocks = <&rcc 0 266>;
+				st,bank-name = "GPIOK";
+			};
+
+			usart1_pins_a: usart1 at 0 {
+				pins1 {
+					pinmux = <STM32F746_PA9_FUNC_USART1_TX>;
+					bias-disable;
+					drive-push-pull;
+					slew-rate = <0>;
+				};
+				pins2 {
+					pinmux = <STM32F746_PA10_FUNC_USART1_RX>;
+					bias-disable;
+				};
+			};
+		};
+
+		rcc: rcc at 40023800 {
+			#clock-cells = <2>;
+			compatible = "st,stm32f42xx-rcc", "st,stm32-rcc";
+			reg = <0x40023800 0x400>;
+			clocks = <&clk_hse>;
+		};
+	};
+};
+
+&systick {
+	clocks = <&rcc 1 0>;
+	status = "okay";
+};
-- 
1.9.1

^ permalink raw reply related

* [PATCH 2/5] ARM: Kconfig: Introduce MACH_STM32F746 flag
From: Alexandre TORGUE @ 2016-10-26 15:11 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477494683-29890-1-git-send-email-alexandre.torgue@st.com>

This patch introduces the MACH_STM32F746 to make possible to only select
STM32F746 pinctrl driver

By default, all the MACH_STM32Fxxx flags will be set with STM32 defconfig.

Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
Signed-off-by: Alexandre TORGUE <alexandre.torgue@st.com>

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index b5d529f..4353765 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -887,6 +887,11 @@ config MACH_STM32F429
 	depends on ARCH_STM32
 	default y
 
+config MACH_STM32F746
+	bool "STMicrolectronics STM32F746"
+	depends on ARCH_STM32
+	default y
+
 config ARCH_MPS2
 	bool "ARM MPS2 platform"
 	depends on ARM_SINGLE_ARMV7M
-- 
1.9.1

^ permalink raw reply related

* [PATCH 1/5] ARM: mach-stm32: Add a new SOC - STM32F746
From: Alexandre TORGUE @ 2016-10-26 15:11 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477494683-29890-1-git-send-email-alexandre.torgue@st.com>

Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
Signed-off-by: Alexandre TORGUE <alexandre.torgue@st.com>

diff --git a/Documentation/arm/stm32/overview.txt b/Documentation/arm/stm32/overview.txt
index 09aed55..a03b035 100644
--- a/Documentation/arm/stm32/overview.txt
+++ b/Documentation/arm/stm32/overview.txt
@@ -5,7 +5,8 @@ Introduction
 ------------
 
   The STMicroelectronics family of Cortex-M based MCUs are supported by the
-  'STM32' platform of ARM Linux. Currently only the STM32F429 is supported.
+  'STM32' platform of ARM Linux. Currently only the STM32F429 (Cortex-M4)
+  and STM32F746 (Cortex-M7) are supported.
 
 
 Configuration
diff --git a/Documentation/arm/stm32/stm32f746-overview.txt b/Documentation/arm/stm32/stm32f746-overview.txt
new file mode 100644
index 0000000..cffd2b1
--- /dev/null
+++ b/Documentation/arm/stm32/stm32f746-overview.txt
@@ -0,0 +1,34 @@
+			STM32F746 Overview
+			==================
+
+  Introduction
+  ------------
+	The STM32F746 is a Cortex-M7 MCU aimed at various applications.
+	It features:
+	- Cortex-M7 core running up to @216MHz
+	- 1MB internal flash, 320KBytes internal RAM (+4KB of backup SRAM)
+	- FMC controller to connect SDRAM, NOR and NAND memories
+	- Dual mode QSPI
+	- SD/MMC/SDIO support
+	- Ethernet controller
+	- USB OTFG FS & HS controllers
+	- I2C, SPI, CAN busses support
+	- Several 16 & 32 bits general purpose timers
+	- Serial Audio interface
+	- LCD controller
+	- HDMI-CEC
+	- SPDIFRX
+
+  Resources
+  ---------
+	Datasheet and reference manual are publicly available on ST website:
+	- http://www.st.com/content/st_com/en/products/microcontrollers/stm32-32-bit-arm-cortex-mcus/stm32f7-series/stm32f7x6/stm32f746ng.html
+
+  Document Author
+  ---------------
+	Alexandre Torgue <alexandre.torgue@st.com>
+
+
+
+
+
diff --git a/arch/arm/mach-stm32/board-dt.c b/arch/arm/mach-stm32/board-dt.c
index ceee477..c354222 100644
--- a/arch/arm/mach-stm32/board-dt.c
+++ b/arch/arm/mach-stm32/board-dt.c
@@ -11,6 +11,7 @@
 static const char *const stm32_compat[] __initconst = {
 	"st,stm32f429",
 	"st,stm32f469",
+	"st,stm32f746",
 	NULL
 };
 
-- 
1.9.1

^ permalink raw reply related

* [PATCH 0/5] ADD STM32F746 MCU and STM32746G-Eval board supports
From: Alexandre TORGUE @ 2016-10-26 15:11 UTC (permalink / raw)
  To: linux-arm-kernel

This series adds basic support for STM32F746 MCU and stm32746g-eval board.
With it, you can boot stm32746g-eval board successfully.
In this series timer, usart/uart, exti, rng, basic rcc IPs are supported.
Other Ips (Ethernet, dma, ...) will come later.

For your information:

The STMicrolectornics's STM32F746 MCU has the following main features:
 - Cortex-M7 core running up to @216MHz
 - 1MB internal flash, 320KBytes internal RAM (+4KB of backup SRAM)
 - FMC controller to connect SDRAM, NOR and NAND memories
 - Dual mode QSPI
 - SD/MMC/SDIO support
 - Ethernet controller
 - USB OTFG FS & HS controllers
 - I2C, SPI, CAN busses support
 - Several 16 & 32 bits general purpose timers
 - Serial Audio interface
 - LCD controller
 - HDMI-CEC
 - SPDIFRX 

Regards

Alex

Alexandre TORGUE (5):
  ARM: mach-stm32: Add a new SOC - STM32F746
  ARM: Kconfig: Introduce MACH_STM32F746 flag
  ARM: dts: Add STM32F746 MCU and STM32746g-EVAL board
  ARM: configs: Add new config fragment to change RAM start point
  ARM: configs: Add new config fragment to change RAM size

 Documentation/arm/stm32/overview.txt           |   3 +-
 Documentation/arm/stm32/stm32f746-overview.txt |  34 +++
 arch/arm/Kconfig                               |   5 +
 arch/arm/boot/dts/Makefile                     |   3 +-
 arch/arm/boot/dts/stm32746g-eval.dts           |  96 ++++++++
 arch/arm/boot/dts/stm32f746.dtsi               | 304 +++++++++++++++++++++++++
 arch/arm/configs/dram_0xc0000000.config        |   1 +
 arch/arm/configs/dram_size_0x2000000.config    |   1 +
 arch/arm/mach-stm32/board-dt.c                 |   1 +
 9 files changed, 446 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/arm/stm32/stm32f746-overview.txt
 create mode 100644 arch/arm/boot/dts/stm32746g-eval.dts
 create mode 100644 arch/arm/boot/dts/stm32f746.dtsi
 create mode 100644 arch/arm/configs/dram_0xc0000000.config
 create mode 100644 arch/arm/configs/dram_size_0x2000000.config

-- 
1.9.1

^ permalink raw reply

* [PATCH] mfd: qcom-pm8xxx: Clean up PM8XXX namespace
From: Andy Gross @ 2016-10-26 15:10 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477487453-15801-1-git-send-email-linus.walleij@linaro.org>

On Wed, Oct 26, 2016 at 03:10:53PM +0200, Linus Walleij wrote:
> The Kconfig and file naming for the PM8xxx driver is totally
> confusing:
> 
> - Kconfig options MFD_PM8XXX and MFD_PM8921_CORE, some in-kernel
>   users depending on or selecting either at random.
> - A driver file named pm8921-core.c even if it is indeed
>   used by the whole PM8xxx family of chips.
> - An irqchip named pm8xxx since it was (I guess) realized that
>   the driver was generic for all pm8xxx PMICs.
> 
> As I may want to add support for PM8901 this is starting to get
> really messy. Fix this situation by:
> 
> - Remove the MFD_PM8921_CORE symbol and rely solely on MFD_PM8XXX
>   and convert all users, including LEDs Kconfig and ARM defconfigs
>   for qcom and multi_v7 to use that single symbol.
> - Renaming the driver to qcom-pm8xxx.c to fit along the two
>   other qcom* prefixed drivers.
> - Rename functions withing the driver from 8921 to 8xxx to
>   indicate it is generic.
> - Just drop the =m config from the pxa_defconfig, I have no clue
>   why it is even there, it is not a Qualcomm platform. (Possibly
>   older Kconfig noise from saveconfig.)
> 
> Cc: Stephen Boyd <sboyd@codeaurora.org>
> Cc: Bjorn Andersson <bjorn.andersson@linaro.org>
> Cc: Neil Armstrong <narmstrong@baylibre.com>
> Cc: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>


Reviewed-by: Andy Gross <andy.gross@linaro.org>

^ permalink raw reply

* [PATCH V3 6/8] arm: dma-mapping: Reset the device's dma_ops
From: Robin Murphy @ 2016-10-26 15:07 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1475600632-21289-7-git-send-email-sricharan@codeaurora.org>

On 04/10/16 18:03, Sricharan R wrote:
> The dma_ops for the device is not getting set to NULL in
> arch_tear_down_dma_ops and this causes an issue when the
> device's probe gets deferred and retried. So reset the
> dma_ops to NULL.

Reviewed-by: Robin Murphy <robin.murphy@arm.com>

This seems like it could stand independently from the rest of the series
- might be worth rewording the commit message to more general terms,
i.e. arch_teardown_dma_ops() being the inverse of arch_setup_dma_ops()
thus clearing the ops set by the latter, and sending it to Russell as a
fix in its own right.

Robin.

> Signed-off-by: Sricharan R <sricharan@codeaurora.org>
> ---
>  arch/arm/mm/dma-mapping.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
> index dde6514..b9191f0 100644
> --- a/arch/arm/mm/dma-mapping.c
> +++ b/arch/arm/mm/dma-mapping.c
> @@ -2295,6 +2295,7 @@ static void arm_teardown_iommu_dma_ops(struct device *dev)
>  
>  	__arm_iommu_detach_device(dev);
>  	arm_iommu_release_mapping(mapping);
> +	set_dma_ops(dev, NULL);
>  }
>  
>  #else
> 

^ permalink raw reply

* [PATCH V3 4/8] drivers: platform: Configure dma operations at probe time
From: Sricharan @ 2016-10-26 15:04 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <a77ab9da-1347-49e8-6c55-071bd712729a@arm.com>

Hi Robin,

>On 04/10/16 18:03, Sricharan R wrote:
>> Configuring DMA ops at probe time will allow deferring device probe when
>> the IOMMU isn't available yet. The dma_configure for the device is now called
>> from the generic device_attach callback just before the bus/driver probe
>> is called. This way, configuring the dma ops for the device would be called
>> at the same place for all bus_types, hence the deferred probing mechanism
>> should work for all buses as well.
>>
>> pci_bus_add_devices    (platform/amba)(_device_create/driver_register)
>>        |                         |
>> pci_bus_add_device     (device_add/driver_register)
>>        |                         |
>> device_attach           device_initial_probe
>>        |                         |
>> __device_attach_driver    __device_attach_driver
>>        |
>> driver_probe_device
>>        |
>> really_probe
>>        |
>> dma_configure
>>
>>  Similarly on the device/driver_unregister path __device_release_driver is
>>  called which inturn calls dma_deconfigure.
>>
>> Signed-off-by: Sricharan R <sricharan@codeaurora.org>
>> ---
>>  drivers/base/dd.c           | 10 ++++++++++
>>  drivers/base/dma-mapping.c  | 11 +++++++++++
>>  drivers/of/platform.c       |  4 ----
>>  drivers/pci/probe.c         |  5 +----
>>  include/linux/dma-mapping.h |  3 +++
>>  5 files changed, 25 insertions(+), 8 deletions(-)
>>
>> diff --git a/drivers/base/dd.c b/drivers/base/dd.c
>> index 16688f5..cfebd48 100644
>> --- a/drivers/base/dd.c
>> +++ b/drivers/base/dd.c
>> @@ -19,6 +19,7 @@
>>
>>  #include <linux/device.h>
>>  #include <linux/delay.h>
>> +#include <linux/dma-mapping.h>
>>  #include <linux/module.h>
>>  #include <linux/kthread.h>
>>  #include <linux/wait.h>
>> @@ -353,6 +354,10 @@ static int really_probe(struct device *dev, struct device_driver *drv)
>>  	if (ret)
>>  		goto pinctrl_bind_failed;
>>
>> +	ret = dma_configure(dev);
>> +	if (ret)
>> +		goto dma_failed;
>> +
>>  	if (driver_sysfs_add(dev)) {
>>  		printk(KERN_ERR "%s: driver_sysfs_add(%s) failed\n",
>>  			__func__, dev_name(dev));
>> @@ -395,6 +400,8 @@ static int really_probe(struct device *dev, struct device_driver *drv)
>>  	goto done;
>>
>>  probe_failed:
>> +	dma_deconfigure(dev);
>> +dma_failed:
>>  	if (dev->bus)
>>  		blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
>>  					     BUS_NOTIFY_DRIVER_NOT_BOUND, dev);
>> @@ -780,6 +787,9 @@ static void __device_release_driver(struct device *dev)
>>  			dev->bus->remove(dev);
>>  		else if (drv->remove)
>>  			drv->remove(dev);
>> +
>> +		dma_deconfigure(dev);
>> +
>>  		devres_release_all(dev);
>>  		dev->driver = NULL;
>>  		dev_set_drvdata(dev, NULL);
>> diff --git a/drivers/base/dma-mapping.c b/drivers/base/dma-mapping.c
>> index d799662..54e87f5 100644
>> --- a/drivers/base/dma-mapping.c
>> +++ b/drivers/base/dma-mapping.c
>> @@ -10,6 +10,7 @@
>>  #include <linux/dma-mapping.h>
>>  #include <linux/export.h>
>>  #include <linux/gfp.h>
>> +#include <linux/of_device.h>
>>  #include <linux/slab.h>
>>  #include <linux/vmalloc.h>
>>
>> @@ -166,6 +167,16 @@ void dmam_free_noncoherent(struct device *dev, size_t size, void *vaddr,
>>  }
>>  EXPORT_SYMBOL(dmam_free_noncoherent);
>>
>> +int dma_configure(struct device *dev)
>> +{
>> +	return of_dma_configure(dev, dev->of_node);
>> +}
>> +
>> +void dma_deconfigure(struct device *dev)
>> +{
>> +	of_dma_deconfigure(dev);
>> +}
>> +
>>  #ifdef CONFIG_HAVE_GENERIC_DMA_COHERENT
>>
>>  static void dmam_coherent_decl_release(struct device *dev, void *res)
>> diff --git a/drivers/of/platform.c b/drivers/of/platform.c
>> index 9cb7090..adbd77c 100644
>> --- a/drivers/of/platform.c
>> +++ b/drivers/of/platform.c
>> @@ -181,11 +181,9 @@ static struct platform_device *of_platform_device_create_pdata(
>>
>>  	dev->dev.bus = &platform_bus_type;
>>  	dev->dev.platform_data = platform_data;
>> -	of_dma_configure(&dev->dev, dev->dev.of_node);
>>  	of_msi_configure(&dev->dev, dev->dev.of_node);
>>
>>  	if (of_device_add(dev) != 0) {
>> -		of_dma_deconfigure(&dev->dev);
>>  		platform_device_put(dev);
>>  		goto err_clear_flag;
>>  	}
>> @@ -242,7 +240,6 @@ static struct amba_device *of_amba_device_create(struct device_node *node,
>>  		dev_set_name(&dev->dev, "%s", bus_id);
>>  	else
>>  		of_device_make_bus_id(&dev->dev);
>> -	of_dma_configure(&dev->dev, dev->dev.of_node);
>>
>>  	/* Allow the HW Peripheral ID to be overridden */
>>  	prop = of_get_property(node, "arm,primecell-periphid", NULL);
>> @@ -536,7 +533,6 @@ static int of_platform_device_destroy(struct device *dev, void *data)
>>  		amba_device_unregister(to_amba_device(dev));
>>  #endif
>>
>> -	of_dma_deconfigure(dev);
>>  	of_node_clear_flag(dev->of_node, OF_POPULATED);
>>  	of_node_clear_flag(dev->of_node, OF_POPULATED_BUS);
>>  	return 0;
>> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
>> index 93f280d..85c9553 100644
>> --- a/drivers/pci/probe.c
>> +++ b/drivers/pci/probe.c
>> @@ -1724,10 +1724,7 @@ static void pci_dma_configure(struct pci_dev *dev)
>>  {
>>  	struct device *bridge = pci_get_host_bridge_device(dev);
>>
>> -	if (IS_ENABLED(CONFIG_OF) &&
>> -		bridge->parent && bridge->parent->of_node) {
>> -			of_dma_configure(&dev->dev, bridge->parent->of_node);
>> -	} else if (has_acpi_companion(bridge)) {
>> +	if (has_acpi_companion(bridge)) {
>>  		struct acpi_device *adev = to_acpi_device_node(bridge->fwnode);
>>  		enum dev_dma_attr attr = acpi_get_dma_attr(adev);
>
>It seems a bit awkward leaving pci_dma_configure here, doing DMA
>configuration at device add, after we've allegedly moved DMA
>configuration to driver probe. Lorenzo, do you foresee any issues if
>this probe-time of_dma_configure() path were to also multiplex
>acpi_dma_configure() in future, such that everything would be back in
>the same place eventually?
>
>Conversely, is there actually any issue with leaving pci_dma_configure()
>unchanged, and simply moving the call from pci_device_add() into
>dma_configure()?

Ya i removed only the CONFIG_OF part out of this, and was hoping that
the acpi configure can also be called from the dma_configure during
probe later. I did not have an ACPI based platform though.
 As you said, if that looks right to the ACPI world, it can be
moved out from here. I can try mergin series (after fixing the vfio errors
 part) with the ACPI IO port and see how it behaves.

Regards,
 Sricharan
  

^ permalink raw reply

* [PATCH v2 4/4] ARM: dts: da850: Add the usb otg device node
From: Alexandre Bailon @ 2016-10-26 15:03 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477494237-22831-1-git-send-email-abailon@baylibre.com>

This adds the device tree node for the usb otg
controller present in the da850 family of SoC's.
This also enables the otg usb controller for the lcdk board.

Signed-off-by: Alexandre Bailon <abailon@baylibre.com>
---
 arch/arm/boot/dts/da850-lcdk.dts |  8 ++++++++
 arch/arm/boot/dts/da850.dtsi     | 15 +++++++++++++++
 2 files changed, 23 insertions(+)

diff --git a/arch/arm/boot/dts/da850-lcdk.dts b/arch/arm/boot/dts/da850-lcdk.dts
index 7b8ab21..9f5040c 100644
--- a/arch/arm/boot/dts/da850-lcdk.dts
+++ b/arch/arm/boot/dts/da850-lcdk.dts
@@ -158,6 +158,14 @@
 	rx-num-evt = <32>;
 };
 
+&usb_phy {
+	status = "okay";
+	};
+
+&usb0 {
+	status = "okay";
+};
+
 &aemif {
 	pinctrl-names = "default";
 	pinctrl-0 = <&nand_pins>;
diff --git a/arch/arm/boot/dts/da850.dtsi b/arch/arm/boot/dts/da850.dtsi
index f79e1b9..322a31a 100644
--- a/arch/arm/boot/dts/da850.dtsi
+++ b/arch/arm/boot/dts/da850.dtsi
@@ -372,6 +372,21 @@
 					>;
 			status = "disabled";
 		};
+		usb_phy: usb-phy {
+			compatible = "ti,da830-usb-phy";
+			#phy-cells = <1>;
+			status = "disabled";
+		};
+		usb0: usb at 200000 {
+			compatible = "ti,da830-musb";
+			reg = <0x200000 0x10000>;
+			interrupts = <58>;
+			interrupt-names = "mc";
+			dr_mode = "otg";
+			phys = <&usb_phy 0>;
+			phy-names = "usb-phy";
+			status = "disabled";
+		};
 		gpio: gpio at 226000 {
 			compatible = "ti,dm6441-gpio";
 			gpio-controller;
-- 
2.7.3

^ permalink raw reply related

* [PATCH v2 3/4] usb: musb: da8xx: Add DT support for the DA8xx driver
From: Alexandre Bailon @ 2016-10-26 15:03 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477494237-22831-1-git-send-email-abailon@baylibre.com>

From: Petr Kulhavy <petr@barix.com>

This adds DT support for TI DA8xx/OMAP-L1x/AM17xx/AM18xx MUSB driver

Signed-off-by: Petr Kulhavy <petr@barix.com>
Signed-off-by: Alexandre Bailon <abailon@baylibre.com>
---
 drivers/usb/musb/da8xx.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 47 insertions(+)

diff --git a/drivers/usb/musb/da8xx.c b/drivers/usb/musb/da8xx.c
index 210b7e4..bfa571d 100644
--- a/drivers/usb/musb/da8xx.c
+++ b/drivers/usb/musb/da8xx.c
@@ -6,6 +6,9 @@
  * Based on the DaVinci "glue layer" code.
  * Copyright (C) 2005-2006 by Texas Instruments
  *
+ * DT support
+ * Copyright (c) 2016 Petr Kulhavy <petr@barix.com>
+ *
  * This file is part of the Inventra Controller Driver for Linux.
  *
  * The Inventra Controller Driver for Linux is free software; you
@@ -433,6 +436,21 @@ static int da8xx_musb_exit(struct musb *musb)
 	return 0;
 }
 
+static inline u8 get_vbus_power(struct device *dev)
+{
+	struct regulator *vbus_supply;
+	int current_uA;
+
+	vbus_supply = regulator_get_optional(dev, "vbus");
+	if (IS_ERR(vbus_supply))
+		return 255;
+	current_uA = regulator_get_current_limit(vbus_supply);
+	regulator_put(vbus_supply);
+	if (current_uA <= 0 || current_uA > 510000)
+		return 255;
+	return current_uA / 1000 / 2;
+}
+
 static const struct musb_platform_ops da8xx_ops = {
 	.quirks		= MUSB_DMA_CPPI | MUSB_INDEXED_EP,
 	.init		= da8xx_musb_init,
@@ -458,6 +476,12 @@ static const struct platform_device_info da8xx_dev_info = {
 	.dma_mask	= DMA_BIT_MASK(32),
 };
 
+static const struct musb_hdrc_config da8xx_config = {
+	.ram_bits = 10,
+	.num_eps = 5,
+	.multipoint = 1,
+};
+
 static int da8xx_probe(struct platform_device *pdev)
 {
 	struct resource musb_resources[2];
@@ -465,7 +489,9 @@ static int da8xx_probe(struct platform_device *pdev)
 	struct da8xx_glue		*glue;
 	struct platform_device_info	pinfo;
 	struct clk			*clk;
+	struct device_node		*np = pdev->dev.of_node;
 	int				ret;
+	struct resource *res;
 
 	glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL);
 	if (!glue)
@@ -486,6 +512,18 @@ static int da8xx_probe(struct platform_device *pdev)
 	glue->dev			= &pdev->dev;
 	glue->clk			= clk;
 
+	if (IS_ENABLED(CONFIG_OF) && np) {
+		pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+		if (!pdata) {
+			/* FIXME */
+			return -ENOMEM;
+		}
+
+		pdata->config	= &da8xx_config;
+		pdata->mode	= musb_get_mode(&pdev->dev);
+		pdata->power	= get_vbus_power(&pdev->dev);
+	}
+
 	pdata->platform_ops		= &da8xx_ops;
 
 	glue->usb_phy = usb_phy_generic_register();
@@ -536,11 +574,20 @@ static int da8xx_remove(struct platform_device *pdev)
 	return 0;
 }
 
+static const struct of_device_id da8xx_id_table[] = {
+	{
+		.compatible = "ti,da830-musb",
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(of, da8xx_id_table);
+
 static struct platform_driver da8xx_driver = {
 	.probe		= da8xx_probe,
 	.remove		= da8xx_remove,
 	.driver		= {
 		.name	= "musb-da8xx",
+		.of_match_table = of_match_ptr(da8xx_id_table),
 	},
 };
 
-- 
2.7.3

^ permalink raw reply related

* [PATCH v2 2/4] usb: musb: core: added helper function for parsing DT
From: Alexandre Bailon @ 2016-10-26 15:03 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477494237-22831-1-git-send-email-abailon@baylibre.com>

From: Petr Kulhavy <petr@barix.com>

This adds the function musb_get_mode() to get the DT property "dr_mode"

Signed-off-by: Petr Kulhavy <petr@barix.com>
Acked-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: Alexandre Bailon <abailon@baylibre.com>
---
 drivers/usb/musb/musb_core.c | 19 +++++++++++++++++++
 drivers/usb/musb/musb_core.h |  5 +++++
 2 files changed, 24 insertions(+)

diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index 27dadc0..bba07e7 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -100,6 +100,7 @@
 #include <linux/io.h>
 #include <linux/dma-mapping.h>
 #include <linux/usb.h>
+#include <linux/usb/of.h>
 
 #include "musb_core.h"
 #include "musb_trace.h"
@@ -130,6 +131,24 @@ static inline struct musb *dev_to_musb(struct device *dev)
 	return dev_get_drvdata(dev);
 }
 
+enum musb_mode musb_get_mode(struct device *dev)
+{
+	enum usb_dr_mode mode;
+
+	mode = usb_get_dr_mode(dev);
+	switch (mode) {
+	case USB_DR_MODE_HOST:
+		return MUSB_HOST;
+	case USB_DR_MODE_PERIPHERAL:
+		return MUSB_PERIPHERAL;
+	case USB_DR_MODE_OTG:
+	case USB_DR_MODE_UNKNOWN:
+	default:
+		return MUSB_OTG;
+	}
+}
+EXPORT_SYMBOL_GPL(musb_get_mode);
+
 /*-------------------------------------------------------------------------*/
 
 #ifndef CONFIG_BLACKFIN
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h
index 2cb88a49..a406468 100644
--- a/drivers/usb/musb/musb_core.h
+++ b/drivers/usb/musb/musb_core.h
@@ -617,4 +617,9 @@ static inline void musb_platform_post_root_reset_end(struct musb *musb)
 		musb->ops->post_root_reset_end(musb);
 }
 
+/* gets the "dr_mode" property from DT and converts it into musb_mode
+ * if the property is not found or not recognized returns MUSB_OTG
+ */
+extern enum musb_mode musb_get_mode(struct device *dev);
+
 #endif	/* __MUSB_CORE_H__ */
-- 
2.7.3

^ permalink raw reply related

* [PATCH v2 1/4] dt/bindings: Add binding for the DA8xx MUSB driver
From: Alexandre Bailon @ 2016-10-26 15:03 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477494237-22831-1-git-send-email-abailon@baylibre.com>

From: Petr Kulhavy <petr@barix.com>

DT binding for the TI DA8xx/OMAP-L1x/AM17xx/AM18xx MUSB driver.

Signed-off-by: Petr Kulhavy <petr@barix.com>
Signed-off-by: Alexandre Bailon <abailon@baylibre.com>
---
 .../devicetree/bindings/usb/da8xx-usb.txt          | 43 ++++++++++++++++++++++
 1 file changed, 43 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/usb/da8xx-usb.txt

diff --git a/Documentation/devicetree/bindings/usb/da8xx-usb.txt b/Documentation/devicetree/bindings/usb/da8xx-usb.txt
new file mode 100644
index 0000000..5663d79
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/da8xx-usb.txt
@@ -0,0 +1,43 @@
+TI DA8xx MUSB
+~~~~~~~~~~~~~
+For DA8xx/OMAP-L1x/AM17xx/AM18xx platforms.
+
+Required properties:
+~~~~~~~~~~~~~~~~~~~~
+ - compatible : Should be set to "ti,da830-musb".
+
+ - reg: Offset and length of the USB controller register set.
+
+ - interrupts: The USB interrupt number.
+
+ - interrupt-names: Should be set to "mc".
+
+ - dr_mode: The USB operation mode. Should be one of "host", "peripheral" or "otg".
+
+ - phys: Phandle for the PHY device
+
+ - phy-names: Should be "usb-phy"
+
+Optional properties:
+~~~~~~~~~~~~~~~~~~~~
+ - vbus-supply: Phandle to a regulator providing the USB bus power.
+
+Example:
+	usb_phy: usb-phy {
+		compatible = "ti,da830-usb-phy";
+		#phy-cells = <0>;
+		status = "okay";
+	};
+	usb20: usb at 1e00000 {
+		compatible = "ti,da830-musb";
+		reg =   <0x00200000 0x10000>;
+		interrupts = <58>;
+		interrupt-names = "mc";
+
+		dr_mode = "host";
+		vbus-supply = <&usb_vbus>;
+		phys = <&usb_phy 0>;
+		phy-names = "usb-phy";
+
+		status = "okay";
+	};
-- 
2.7.3

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox