Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 4/5] tty: serial: 8250 core: add runtime pm
From: Felipe Balbi @ 2014-07-17 16:18 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <53C7F4A3.5080508@linutronix.de>

Hi,

On Thu, Jul 17, 2014 at 06:06:59PM +0200, Sebastian Andrzej Siewior wrote:
> On 07/17/2014 06:02 PM, Felipe Balbi wrote:
> >> diff --git a/drivers/tty/serial/8250/8250_core.c
> >> b/drivers/tty/serial/8250/8250_core.c index 2e4a93b..480a1c0
> >> 100644 --- a/drivers/tty/serial/8250/8250_core.c +++
> >> b/drivers/tty/serial/8250/8250_core.c @@ -1283,6 +1283,9 @@
> >> static inline void __stop_tx(struct uart_8250_port *p) if (p->ier
> >> & UART_IER_THRI) { p->ier &= ~UART_IER_THRI; serial_out(p,
> >> UART_IER, p->ier); + +		pm_runtime_mark_last_busy(p->port.dev); +
> >> pm_runtime_put_autosuspend(p->port.dev); } }
> >> 
> >> @@ -1310,12 +1313,12 @@ static void serial8250_start_tx(struct
> >> uart_port *port) struct uart_8250_port *up = container_of(port,
> >> struct uart_8250_port, port);
> >> 
> >> -	pm_runtime_get_sync(port->dev); if (up->dma &&
> >> !serial8250_tx_dma(up)) { goto out; } else if (!(up->ier &
> >> UART_IER_THRI)) { up->ier |= UART_IER_THRI; +
> >> pm_runtime_get_sync(port->dev); serial_port_out(port, UART_IER,
> >> up->ier);
> >> 
> >> if (up->bugs & UART_BUG_TXEN) { unsigned char lsr;
> > 
> > this looks better. So we get on start_tx() and put on stop_tx().
> > 
> >> @@ -1500,9 +1503,10 @@ void serial8250_tx_chars(struct
> >> uart_8250_port *up) uart_write_wakeup(port);
> >> 
> >> DEBUG_INTR("THRE..."); - +#if 0 if (uart_circ_empty(xmit)) 
> >> __stop_tx(up); +#endif } EXPORT_SYMBOL_GPL(serial8250_tx_chars);
> > 
> > is it so that start_tx() gets called one and stop_tx() might be
> > called N times ? That looks unbalanced to me. If the calls are
> > balanced, then you shouldn't need to care because pm_runtime will
> > handle reference counting for you, right?
> 
> No, this is okay. If you look, it checks for "up->ier &
> UART_IER_THRI". On the second invocation it will see that this bit is
> already set and therefore won't call get_sync() for the second time.
> That bit is removed in the _stop_tx() path.

oh, right. But that's actually unnecessary. Calling pm_runtime_get()
multiple times will just increment the usage counter multiple times,
which means you can call __stop_tx() multiple times too and everything
gets balanced, right ?

> >> and now I need to come up with something that is not if (port !=
> >> omap) for that #if 0 block. The code disables the TX FIFO empty
> >> interrupt once the transfer is complete. I want to call
> >> __stop_tx() once the tx fifo is empty. Felipe, Would a check for
> >> dev->power.use_autosuspend be the right thing to do?
> > 
> > probably not, as that's internal to the pm_runtime code. But I
> > wonder if start/stop tx calls are balanced, if they are then we're
> > good. Unless I'm missing something else.
> 
> Do you have other ideas? It doesn't look like this is exported at all.
> If we call _stop_tx() right away, then we have 64 bytes in the TX fifo
> in the worst case. They should be gone "soon" but the HW-flow control
> may delay it (in theory for a long time)).

this can be problematic, specially for OMAP which can go into OFF while
idle. Whatever is in the FIFO would get lost. It seems like omap-serial
solved this within transmit_chars().

See how transmit_chars() is called from within IRQ handler with clocks
enabled then it conditionally calls serial_omap_stop_tx() which will
pm_runtime_get_sync() -> do_the_harlem_shake() ->
pm_runtime_put_autosuspend(). That leaves one unbalanced
pm_runtime_get() which is balanced when we're exitting the IRQ handler.

This seems work fine and dandy without DMA, but for DMA work, I think we
need to make sure this IP stays powered until we get DMA completion
callback. But that's future, I guess.

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140717/ca4927f5/attachment-0001.sig>

^ permalink raw reply

* [PATCH 0/3] ARM: mvebu: disable I/O coherency on !SMP
From: Santosh Shilimkar @ 2014-07-17 16:18 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140717161010.GY21766@n2100.arm.linux.org.uk>

On Thursday 17 July 2014 12:10 PM, Russell King - ARM Linux wrote:
> On Thu, Jul 17, 2014 at 12:04:26PM -0400, Santosh Shilimkar wrote:
>> Thanks for spotting it RMK. Will have a loot at it.
> 
> I already have this for it - which includes a lot more comments on the
> code (some in anticipation of the reply from the architecture people.)
> The first hunk alone should fix the spotted problem.
> 
Cool. The alignment fix was easy but I was more worried about the
other part. Thanks for the those additional comments. 

> diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
> index ab14b79b03f0..917aabd6b2dc 100644
> --- a/arch/arm/mm/mmu.c
> +++ b/arch/arm/mm/mmu.c
> @@ -1406,8 +1406,8 @@ void __init early_paging_init(const struct machine_desc *mdesc,
>  		return;
>  
>  	/* remap kernel code and data */
> -	map_start = init_mm.start_code;
> -	map_end   = init_mm.brk;
> +	map_start = init_mm.start_code & PMD_MASK;
> +	map_end   = ALIGN(init_mm.brk, PMD_SIZE);
>  
>  	/* get a handle on things... */
>  	pgd0 = pgd_offset_k(0);
> @@ -1434,23 +1434,60 @@ void __init early_paging_init(const struct machine_desc *mdesc,
>  	dsb(ishst);
>  	isb();
>  
> -	/* remap level 1 table */
> +	/*
> +	 * WARNING: This code is not architecturally compliant: we modify
> +	 * the mappings in-place, indeed while they are in use by this
> +	 * very same code.
> +	 *
> +	 * Even modifying the mappings in a separate page table does
> +	 * not resolve this.
> +	 *
> +	 * The architecture strongly recommends that when a mapping is
> +	 * changed, that it is changed by first going via an invalid
> +	 * mapping and back to the new mapping.  This is to ensure
> +	 * that no TLB conflicts (caused by the TLB having more than
> +	 * one TLB entry match a translation) can occur.
> +	 */
> +
> +	/*
> +	 * Remap level 1 table.  This changes the physical addresses
> +	 * used to refer to the level 2 page tables to the high
> +	 * physical address alias, leaving everything else the same.
> +	 */
>  	for (i = 0; i < PTRS_PER_PGD; pud0++, i++) {
>  		set_pud(pud0,
>  			__pud(__pa(pmd0) | PMD_TYPE_TABLE | L_PGD_SWAPPER));
>  		pmd0 += PTRS_PER_PMD;
>  	}
>  
> -	/* remap pmds for kernel mapping */
> -	phys = __pa(map_start) & PMD_MASK;
> +	/*
> +	 * Remap the level 2 table, pointing the mappings at the high
> +	 * physical address alias of these pages.
> +	 */
> +	phys = __pa(map_start);
>  	do {
>  		*pmdk++ = __pmd(phys | pmdprot);
>  		phys += PMD_SIZE;
>  	} while (phys < map_end);
>  
> +	/*
> +	 * Ensure that the above updates are flushed out of the cache.
> +	 * This is not strictly correct; on a system where the caches
> +	 * are coherent with each other, but the MMU page table walks
> +	 * may not be coherent, flush_cache_all() may be a no-op, and
> +	 * this will fail.
> +	 */
>  	flush_cache_all();
> +
> +	/*
> +	 * Re-write the TTBR values to point them at the high physical
> +	 * alias of the page tables.  We expect __va() will work on
> +	 * cpu_get_pgd(), which returns the value of TTBR0.
> +	 */
>  	cpu_switch_mm(pgd0, &init_mm);
>  	cpu_set_ttbr(1, __pa(pgd0) + TTBR1_OFFSET);
> +
> +	/* Finally flush any stale TLB values. */
>  	local_flush_bp_all();
>  	local_flush_tlb_all();
>  }
> 
> 

^ permalink raw reply

* [RESEND PATCH v7 3/4] arm: dirty log write protect management support
From: Mario Smarduch @ 2014-07-17 16:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140703150401.GE20104@cbox>

Hi Christoffer,
   Just back from holiday - a short plan to resume work.

- move VM tlb flush and kvm log functions to generic, per Paolo's
comments use Kconfig approach
- update other architectures make sure they compile
- Keep it ARMv7 for now

Get maintainers to test the branch.

In parallel add dirty log support to ARMv8, to test I would
add a QEMU monitor function to validate general operation.

Your thoughts?

Thanks,
  Mario

On 07/03/2014 08:04 AM, Christoffer Dall wrote:
> On Tue, Jun 17, 2014 at 06:41:52PM -0700, Mario Smarduch wrote:
>> On 06/11/2014 12:03 AM, Christoffer Dall wrote:
>>
>>>>
>>>> There is also the issue of kvm_flush_remote_tlbs(), that's also weak,
>>>> the generic one is using IPIs. Since it's only used in mmu.c maybe make 
>>>> this one static.
>>>>
>>> So I don't see a lot of use of weak symbols in kvm_main.c (actually on
>>> kvmarm/next I don't see any), but we do want to share code when more
>>> than one architecture implements something in the exact same way, like
>>> it seems x86 and ARM is doing here for this particular function.
>>>
>>> I think the KVM scheme is usually to check for some define, like:
>>>
>>> #ifdef KVM_ARCH_HAVE_GET_DIRTY_LOG
>>> 	ret = kvm_arch_get_dirty_log(...);
>>> #else
>>> 	ret = kvm_get_dirty_log(...);
>>> #endif
>>>
>>> but Paolo may have a more informed oppinion of how to deal with these.
>>>
>>> Thanks,
>>> -Christoffer
>>>
>>
>>  
>> One approach I'm trying looking at the code in kvm_main().
>> This approach applies more to selecting features as opposed to
>> selecting generic vs architecture specific functions.
>>
>> 1.-------------------------------------------------
>>  - add to 'virt/kvm/Kconfig'
>> config HAVE_KVM_ARCH_TLB_FLUSH_ALL
>>        bool
>>
>> config HAVE_KVM_ARCH_DIRTY_LOG
>>        bool
>> 2.--------------------------------------------------
>> For ARM and later ARM64 add to 'arch/arm[64]/kvm/Kconfig'
>> config KVM
>>         bool "Kernel-based Virtual Machine (KVM) support"
>> ...
>> select HAVE_KVM_ARCH_TLB_FLUSH_ALL
>> ..
>>
>> Not for HAVE_KVM_ARCH_DIRTY_LOG given it's shared with x86,
>> but would need to do it for every other architecture that
>> does not share it (except initially for arm64 since it
>> will use the variant that returns -EINVAL until feature
>> is supported)
>>
>> 3------------------------------------------------------
>> In kvm_main.c would have something like
>>
>> void kvm_flush_remote_tlbs(struct kvm *kvm)
>> {
>> #ifdef CONFIG_HAVE_KVM_ARCH_TLB_FLUSH_ALL
>>         kvm_arch_flush_remote_tlbs(kvm);
>> #else
>>         long dirty_count = kvm->tlbs_dirty;
>>
>>         smp_mb();
>>         if (make_all_cpus_request(kvm, KVM_REQ_TLB_FLUSH))
>>                 ++kvm->stat.remote_tlb_flush;
>>         cmpxchg(&kvm->tlbs_dirty, dirty_count, 0);
>> #endif
>> }
>>
>> Then add void kvm_flush_remote_tlbs(struct kvm *kvm) definition
>> to arm kvm_host.h. Define the function in this case mmu.c
>>
>> For the dirty log function
>> int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
>>                                                 struct kvm_dirty_log *log)
>> {
>> #ifdef CONFIG_HAVE_KVM_ARCH_DIRTY_LOG
>>         kvm_arch_vm_ioctl_get_dirty_log(kvm, log);
>> #else
>>         int r;
>>         struct kvm_memory_slot *memslot;
>>         unsigned long n, i;
>>         unsigned long *dirty_bitmap;
>>         unsigned long *dirty_bitmap_buffer;
>>         bool is_dirty = false;
>> 	...
>>
>> But then you have to go into every architecture and define the
>> kvm_arch_vm_...() variant.
>>
>> Is this the right way to go? Or is there a simpler way?
>>
> Hmmm, I'm really not an expert in the 'established procedures' for what
> to put in config files etc., but here's my basic take:
> 
> a) you wouldn't put a config option in Kconfig unless it's comething
> that's actually configurable or some generic feature/subsystem that
> should only be enabled if hardware has certain capabilities or other
> config options enabled.
> 
> b) this seems entirely an implementation issue and not depending on
> anything users should select.
> 
> c) therefore, I think it's either a question of always having an
> arch-specific implementation that you probe for its return value or you
> have some sort of define in the header files for the
> arch/X/include/asm/kvm_host.h to control what you need.
> 
> -Christoffer
> 

^ permalink raw reply

* [PATCH v2 4/4] mfd: pm8921: rename pm8921-core driver
From: Stanimir Varbanov @ 2014-07-17 16:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1405613855-27572-1-git-send-email-svarbanov@mm-sol.com>

The pm8921-core driver presently supports pm8921 and pm8058
Qualcomm PMICs.  To avoid confusion with new generation PMICs
(like pm8941) rename the pm8921-core driver to more
appropriate name pm8xxx-ssbi, which reflects better that
those chips use SSBI interface.

Signed-off-by: Stanimir Varbanov <svarbanov@mm-sol.com>
---
 drivers/mfd/Kconfig                          |   14 +++++-----
 drivers/mfd/Makefile                         |    2 +-
 drivers/mfd/{pm8921-core.c => pm8xxx-ssbi.c} |   38 +++++++++++++-------------
 3 files changed, 27 insertions(+), 27 deletions(-)
 rename drivers/mfd/{pm8921-core.c => pm8xxx-ssbi.c} (92%)

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 122e2d9..884bc32 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -507,8 +507,8 @@ config UCB1400_CORE
 config MFD_PM8XXX
 	tristate
 
-config MFD_PM8921_CORE
-	tristate "Qualcomm PM8921 PMIC chip"
+config MFD_PM8XXX_SSBI
+	tristate "Qualcomm PM8XXX SSBI PMICs"
 	depends on (ARM || HEXAGON)
 	select IRQ_DOMAIN
 	select MFD_CORE
@@ -516,13 +516,13 @@ config MFD_PM8921_CORE
 	select REGMAP
 	help
 	  If you say yes to this option, support will be included for the
-	  built-in PM8921 PMIC chip.
+	  built-in PM8921 and PM8058 PMIC chips.
 
-	  This is required if your board has a PM8921 and uses its features,
-	  such as: MPPs, GPIOs, regulators, interrupts, and PWM.
+	  This is required if your board has a PM8921 or PM8058 and uses
+	  its features, such as: MPPs, GPIOs, regulators, interrupts, and PWM.
 
-	  Say M here if you want to include support for PM8921 chip as a module.
-	  This will build a module called "pm8921-core".
+	  Say M here if you want to include support for PM8921 or PM8058 chip
+	  as a module. This will build a module called "pm8xxx-ssbi".
 
 config MFD_PM8XXX_SPMI
 	tristate "Qualcomm PM8XXX SPMI PMICs"
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 93d82cc..d332085 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -152,7 +152,7 @@ obj-$(CONFIG_MFD_SI476X_CORE)	+= si476x-core.o
 
 obj-$(CONFIG_MFD_CS5535)	+= cs5535-mfd.o
 obj-$(CONFIG_MFD_OMAP_USB_HOST)	+= omap-usb-host.o omap-usb-tll.o
-obj-$(CONFIG_MFD_PM8921_CORE) 	+= pm8921-core.o ssbi.o
+obj-$(CONFIG_MFD_PM8XXX_SSBI) 	+= pm8xxx-ssbi.o ssbi.o
 obj-$(CONFIG_MFD_PM8XXX_SPMI)	+= pm8xxx-spmi.o
 obj-$(CONFIG_TPS65911_COMPARATOR)	+= tps65911-comparator.o
 obj-$(CONFIG_MFD_TPS65090)	+= tps65090.o
diff --git a/drivers/mfd/pm8921-core.c b/drivers/mfd/pm8xxx-ssbi.c
similarity index 92%
rename from drivers/mfd/pm8921-core.c
rename to drivers/mfd/pm8xxx-ssbi.c
index 9595138..102d7fb 100644
--- a/drivers/mfd/pm8921-core.c
+++ b/drivers/mfd/pm8xxx-ssbi.c
@@ -277,14 +277,14 @@ static const struct regmap_config ssbi_regmap_config = {
 	.reg_write = ssbi_reg_write
 };
 
-static const struct of_device_id pm8921_id_table[] = {
+static const struct of_device_id pm8xxx_id_table[] = {
 	{ .compatible = "qcom,pm8058", },
 	{ .compatible = "qcom,pm8921", },
 	{ }
 };
-MODULE_DEVICE_TABLE(of, pm8921_id_table);
+MODULE_DEVICE_TABLE(of, pm8xxx_id_table);
 
-static int pm8921_probe(struct platform_device *pdev)
+static int pm8xxx_probe(struct platform_device *pdev)
 {
 	struct regmap *regmap;
 	int irq, rc;
@@ -354,18 +354,18 @@ static int pm8921_probe(struct platform_device *pdev)
 	return rc;
 }
 
-static int pm8921_remove_child(struct device *dev, void *unused)
+static int pm8xxx_remove_child(struct device *dev, void *unused)
 {
 	platform_device_unregister(to_platform_device(dev));
 	return 0;
 }
 
-static int pm8921_remove(struct platform_device *pdev)
+static int pm8xxx_remove(struct platform_device *pdev)
 {
 	int irq = platform_get_irq(pdev, 0);
 	struct pm_irq_chip *chip = platform_get_drvdata(pdev);
 
-	device_for_each_child(&pdev->dev, NULL, pm8921_remove_child);
+	device_for_each_child(&pdev->dev, NULL, pm8xxx_remove_child);
 	irq_set_chained_handler(irq, NULL);
 	irq_set_handler_data(irq, NULL);
 	irq_domain_remove(chip->irqdomain);
@@ -373,29 +373,29 @@ static int pm8921_remove(struct platform_device *pdev)
 	return 0;
 }
 
-static struct platform_driver pm8921_driver = {
-	.probe		= pm8921_probe,
-	.remove		= pm8921_remove,
+static struct platform_driver pm8xxx_driver = {
+	.probe		= pm8xxx_probe,
+	.remove		= pm8xxx_remove,
 	.driver		= {
-		.name	= "pm8921-core",
+		.name	= "pm8xxx-ssbi",
 		.owner	= THIS_MODULE,
-		.of_match_table = pm8921_id_table,
+		.of_match_table = pm8xxx_id_table,
 	},
 };
 
-static int __init pm8921_init(void)
+static int __init pm8xxx_init(void)
 {
-	return platform_driver_register(&pm8921_driver);
+	return platform_driver_register(&pm8xxx_driver);
 }
-subsys_initcall(pm8921_init);
+subsys_initcall(pm8xxx_init);
 
-static void __exit pm8921_exit(void)
+static void __exit pm8xxx_exit(void)
 {
-	platform_driver_unregister(&pm8921_driver);
+	platform_driver_unregister(&pm8xxx_driver);
 }
-module_exit(pm8921_exit);
+module_exit(pm8xxx_exit);
 
 MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("PMIC 8921 core driver");
+MODULE_DESCRIPTION("PMIC PM8XXX SSBI driver");
 MODULE_VERSION("1.0");
-MODULE_ALIAS("platform:pm8921-core");
+MODULE_ALIAS("platform:pm8xxx-ssbi");
-- 
1.7.0.4

^ permalink raw reply related

* [PATCH v2 3/4] ARM: DT: qcom: add pm8941 and pm8841 device nodes
From: Stanimir Varbanov @ 2014-07-17 16:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1405613855-27572-1-git-send-email-svarbanov@mm-sol.com>

The pm8941 and pm8841 spmi devicetree nodes are childrens of
spmi pmic arbiter. The msm8974 SoC uses two PMIC chips
pm8941 and pm8841. Every PMIC chip has two spmi bus slave id's.

Signed-off-by: Stanimir Varbanov <svarbanov@mm-sol.com>
---
 arch/arm/boot/dts/qcom-msm8974.dtsi |   37 +++++++++++++++++++++++++++++++++++
 1 files changed, 37 insertions(+), 0 deletions(-)

diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom-msm8974.dtsi
index 69dca2a..cb05603 100644
--- a/arch/arm/boot/dts/qcom-msm8974.dtsi
+++ b/arch/arm/boot/dts/qcom-msm8974.dtsi
@@ -3,6 +3,7 @@
 #include "skeleton.dtsi"
 
 #include <dt-bindings/clock/qcom,gcc-msm8974.h>
+#include <dt-bindings/spmi/spmi.h>
 
 / {
 	model = "Qualcomm MSM8974";
@@ -236,5 +237,41 @@
 			#interrupt-cells = <2>;
 			interrupts = <0 208 0>;
 		};
+
+		spmi at fc4cf000 {
+			compatible = "qcom,spmi-pmic-arb";
+			reg-names = "core", "intr", "cnfg";
+			reg = <0xfc4cf000 0x1000>,
+			      <0xfc4cb000 0x1000>,
+			      <0xfc4ca000 0x1000>;
+			interrupt-names = "periph_irq";
+			interrupts = <0 190 0>;
+			qcom,ee = <0>;
+			qcom,channel = <0>;
+			#address-cells = <2>;
+			#size-cells = <0>;
+			interrupt-controller;
+			#interrupt-cells = <4>;
+
+			usid0: pm8941 at 0 {
+				compatible = "qcom,pm8941";
+				reg = <0x0 SPMI_USID>;
+			};
+
+			usid1: pm8941 at 1 {
+				compatible = "qcom,pm8941";
+				reg = <0x1 SPMI_USID>;
+			};
+
+			usid4: pm8841 at 4 {
+				compatible = "qcom,pm8841";
+				reg = <0x4 SPMI_USID>;
+			};
+
+			usid5: pm8841 at 5 {
+				compatible = "qcom,pm8841";
+				reg = <0x5 SPMI_USID>;
+			};
+		};
 	};
 };
-- 
1.7.0.4

^ permalink raw reply related

* [PATCH v2 2/4] mfd: pm8xxx-spmi: document DT bindings for Qualcomm SPMI PMICs
From: Stanimir Varbanov @ 2014-07-17 16:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1405613855-27572-1-git-send-email-svarbanov@mm-sol.com>

Document DT bindings used to describe the Qualcomm SPMI PMICs.
Currently the SPMI PMICs supported are pm8941, pm8841 and pma8084.

Signed-off-by: Stanimir Varbanov <svarbanov@mm-sol.com>
---
 .../devicetree/bindings/mfd/qcom,pm8xxx-spmi.txt   |   49 ++++++++++++++++++++
 1 files changed, 49 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/mfd/qcom,pm8xxx-spmi.txt

diff --git a/Documentation/devicetree/bindings/mfd/qcom,pm8xxx-spmi.txt b/Documentation/devicetree/bindings/mfd/qcom,pm8xxx-spmi.txt
new file mode 100644
index 0000000..2b7f5b6
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/qcom,pm8xxx-spmi.txt
@@ -0,0 +1,49 @@
+          Qualcomm PM8XXX SPMI PMICs multi-function device bindings
+
+The Qualcomm PM8XXX series presently includes PM8941, PM8841 and PMA8084
+PMICs.  These PMICs use a QPNP scheme through SPMI interface.
+QPNP is effectively a partitioning scheme for dividing the SPMI extended
+register space up into logical pieces, and set of fixed register
+locations/definitions within these regions, with some of these regions
+specifically used for interrupt handling.
+
+The QPNP PMICs are used with the Qualcomm Snapdragon series SoCs, and are
+interfaced to the chip via the SPMI (System Power Management Interface) bus.
+Support for multiple independent functions are implemented by splitting the
+16-bit SPMI slave address space into 256 smaller fixed-size regions, 256 bytes
+each. A function can consume one or more of these fixed-size register regions.
+
+Required properties:
+- compatible:      Should contain one of:
+                     "qcom,pm8941"
+                     "qcom,pm8841"
+                     "qcom,pma8084"
+- reg:             Specifies the SPMI USID slave address for this device.
+                   For more information see:
+                   Documentation/devicetree/bindings/spmi/spmi.txt
+
+Required properties for peripheral child nodes:
+- compatible:      Should contain "qcom,pm8xxx-xxx", where "xxx" is
+                   peripheral name. The "pm8xxx" can be any of supported PMICs,
+                   see example below.
+
+Optional properties for peripheral child nodes:
+- interrupts:      Interrupts are specified as a 4-tuple. For more information
+                   see:
+                   Documentation/devicetree/bindings/spmi/qcom,spmi-pmic-arb.txt
+- interrupt-names: Corresponding interrupt name to the interrupts property
+
+Each child node represents a function of the PMIC.
+
+Example:
+
+	pm8941 at 0 {
+		compatible = "qcom,pm8941";
+		reg = <0x0 SPMI_USID>;
+
+		rtc {
+			compatible = "qcom,pm8941-rtc";
+			interrupts = <0x0 0x61 0x1 IRQ_TYPE_EDGE_RISING>;
+			interrupt-names = "alarm";
+		};
+	};
-- 
1.7.0.4

^ permalink raw reply related

* [PATCH v2 1/4] mfd: pm8xxx-spmi: add support for Qualcomm SPMI PMICs
From: Stanimir Varbanov @ 2014-07-17 16:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1405613855-27572-1-git-send-email-svarbanov@mm-sol.com>

From: Josh Cartwright <joshc@codeaurora.org>

The Qualcomm SPMI PMIC chips are components used with the
Snapdragon 800 series SoC family.  This driver exists
largely as a glue mfd component, it exists to be an owner
of an SPMI regmap for children devices described in
device tree.

Signed-off-by: Stanimir Varbanov <svarbanov@mm-sol.com>
---
 drivers/mfd/Kconfig       |   16 +++++++++++
 drivers/mfd/Makefile      |    1 +
 drivers/mfd/pm8xxx-spmi.c |   63 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 80 insertions(+), 0 deletions(-)
 create mode 100644 drivers/mfd/pm8xxx-spmi.c

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 6cc4b6a..122e2d9 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -524,6 +524,22 @@ config MFD_PM8921_CORE
 	  Say M here if you want to include support for PM8921 chip as a module.
 	  This will build a module called "pm8921-core".
 
+config MFD_PM8XXX_SPMI
+	tristate "Qualcomm PM8XXX SPMI PMICs"
+	depends on ARCH_QCOM || COMPILE_TEST
+	depends on OF
+	depends on SPMI
+	select MFD_PM8XXX
+	select REGMAP_SPMI
+	help
+	  This enables support for the Qualcomm PM8XXX SPMI PMICs.
+	  These PMICs are currently used with the Snapdragon 800 series of
+	  SoCs.  Note, that this will only be useful paired with descriptions
+	  of the independent functions as children nodes in the device tree.
+
+	  Say M here if you want to include support for the PM8XXX SPMI PMIC
+	  series as a module.  The module will be called "pm8xxx-spmi".
+
 config MFD_RDC321X
 	tristate "RDC R-321x southbridge"
 	select MFD_CORE
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 8afedba..93d82cc 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -153,6 +153,7 @@ obj-$(CONFIG_MFD_SI476X_CORE)	+= si476x-core.o
 obj-$(CONFIG_MFD_CS5535)	+= cs5535-mfd.o
 obj-$(CONFIG_MFD_OMAP_USB_HOST)	+= omap-usb-host.o omap-usb-tll.o
 obj-$(CONFIG_MFD_PM8921_CORE) 	+= pm8921-core.o ssbi.o
+obj-$(CONFIG_MFD_PM8XXX_SPMI)	+= pm8xxx-spmi.o
 obj-$(CONFIG_TPS65911_COMPARATOR)	+= tps65911-comparator.o
 obj-$(CONFIG_MFD_TPS65090)	+= tps65090.o
 obj-$(CONFIG_MFD_AAT2870_CORE)	+= aat2870-core.o
diff --git a/drivers/mfd/pm8xxx-spmi.c b/drivers/mfd/pm8xxx-spmi.c
new file mode 100644
index 0000000..882da5e
--- /dev/null
+++ b/drivers/mfd/pm8xxx-spmi.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only 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.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/spmi.h>
+#include <linux/regmap.h>
+#include <linux/of_platform.h>
+
+static const struct regmap_config pm8xxx_regmap_config = {
+	.reg_bits	= 16,
+	.val_bits	= 8,
+	.max_register	= 0xffff,
+};
+
+static int pm8xxx_probe(struct spmi_device *sdev)
+{
+	struct device_node *root = sdev->dev.of_node;
+	struct regmap *regmap;
+
+	regmap = devm_regmap_init_spmi_ext(sdev, &pm8xxx_regmap_config);
+	if (IS_ERR(regmap))
+		return PTR_ERR(regmap);
+
+	return of_platform_populate(root, NULL, NULL, &sdev->dev);
+}
+
+static void pm8xxx_remove(struct spmi_device *sdev)
+{
+	of_platform_depopulate(&sdev->dev);
+}
+
+static const struct of_device_id pm8xxx_id_table[] = {
+	{ .compatible = "qcom,pm8941" },
+	{ .compatible = "qcom,pm8841" },
+	{ .compatible = "qcom,pma8084" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, pm8xxx_id_table);
+
+static struct spmi_driver pm8xxx_driver = {
+	.probe = pm8xxx_probe,
+	.remove = pm8xxx_remove,
+	.driver = {
+		.name = "pm8xxx-spmi",
+		.of_match_table = pm8xxx_id_table,
+	},
+};
+module_spmi_driver(pm8xxx_driver);
+
+MODULE_DESCRIPTION("PM8XXX SPMI PMIC driver");
+MODULE_ALIAS("platform:" KBUILD_MODNAME);
+MODULE_AUTHOR("The Linux Foundation");
+MODULE_LICENSE("GPL v2");
-- 
1.7.0.4

^ permalink raw reply related

* [PATCH v2 0/4] Support for Qualcomm QPNP PMIC's
From: Stanimir Varbanov @ 2014-07-17 16:17 UTC (permalink / raw)
  To: linux-arm-kernel

Hello everyone,

Here is the continuation of patch sets sent recently about Qualcomm
QPNP SPMI PMICs.

The previous version of the patch set can be found at [1].

Changes since v1:
 - removed completely custom *of* parser
 - renamed the mfd driver from qpnp-spmi to pm8xxx-spmi
 - now MFD_PM8XXX_SPMI Kconfig option depends on SPMI

Removing of the custom *of* parser leads to that that the *reg* devicetree
property cannot exist and therefore cannot be parsed to get PMIC peripheral
resources. I took this step aside because no one from mfd drivers does this
parsing. This will lead to inconvenience in the peripheral drivers to define
internally the SPMI base addresses depending on the compatible property
i.e. PMIC version. 

Comments are welcome!

regards,
Stan

[1] https://lkml.org/lkml/2014/7/8/428

Josh Cartwright (1):
  mfd: pm8xxx-spmi: add support for Qualcomm SPMI PMICs

Stanimir Varbanov (3):
  mfd: pm8xxx-spmi: document DT bindings for Qualcomm SPMI PMICs
  ARM: DT: qcom: add pm8941 and pm8841 device nodes
  mfd: pm8921: rename pm8921-core driver

 .../devicetree/bindings/mfd/qcom,pm8xxx-spmi.txt   |   49 +++++++++++++++
 arch/arm/boot/dts/qcom-msm8974.dtsi                |   37 ++++++++++++
 drivers/mfd/Kconfig                                |   30 +++++++--
 drivers/mfd/Makefile                               |    3 +-
 drivers/mfd/pm8xxx-spmi.c                          |   63 ++++++++++++++++++++
 drivers/mfd/{pm8921-core.c => pm8xxx-ssbi.c}       |   38 ++++++------
 6 files changed, 193 insertions(+), 27 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/mfd/qcom,pm8xxx-spmi.txt
 create mode 100644 drivers/mfd/pm8xxx-spmi.c
 rename drivers/mfd/{pm8921-core.c => pm8xxx-ssbi.c} (92%)

^ permalink raw reply

* [PATCH 0/3] ARM: mvebu: disable I/O coherency on !SMP
From: Russell King - ARM Linux @ 2014-07-17 16:10 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <53C7F40A.800@ti.com>

On Thu, Jul 17, 2014 at 12:04:26PM -0400, Santosh Shilimkar wrote:
> Thanks for spotting it RMK. Will have a loot at it.

I already have this for it - which includes a lot more comments on the
code (some in anticipation of the reply from the architecture people.)
The first hunk alone should fix the spotted problem.

diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index ab14b79b03f0..917aabd6b2dc 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -1406,8 +1406,8 @@ void __init early_paging_init(const struct machine_desc *mdesc,
 		return;
 
 	/* remap kernel code and data */
-	map_start = init_mm.start_code;
-	map_end   = init_mm.brk;
+	map_start = init_mm.start_code & PMD_MASK;
+	map_end   = ALIGN(init_mm.brk, PMD_SIZE);
 
 	/* get a handle on things... */
 	pgd0 = pgd_offset_k(0);
@@ -1434,23 +1434,60 @@ void __init early_paging_init(const struct machine_desc *mdesc,
 	dsb(ishst);
 	isb();
 
-	/* remap level 1 table */
+	/*
+	 * WARNING: This code is not architecturally compliant: we modify
+	 * the mappings in-place, indeed while they are in use by this
+	 * very same code.
+	 *
+	 * Even modifying the mappings in a separate page table does
+	 * not resolve this.
+	 *
+	 * The architecture strongly recommends that when a mapping is
+	 * changed, that it is changed by first going via an invalid
+	 * mapping and back to the new mapping.  This is to ensure
+	 * that no TLB conflicts (caused by the TLB having more than
+	 * one TLB entry match a translation) can occur.
+	 */
+
+	/*
+	 * Remap level 1 table.  This changes the physical addresses
+	 * used to refer to the level 2 page tables to the high
+	 * physical address alias, leaving everything else the same.
+	 */
 	for (i = 0; i < PTRS_PER_PGD; pud0++, i++) {
 		set_pud(pud0,
 			__pud(__pa(pmd0) | PMD_TYPE_TABLE | L_PGD_SWAPPER));
 		pmd0 += PTRS_PER_PMD;
 	}
 
-	/* remap pmds for kernel mapping */
-	phys = __pa(map_start) & PMD_MASK;
+	/*
+	 * Remap the level 2 table, pointing the mappings at the high
+	 * physical address alias of these pages.
+	 */
+	phys = __pa(map_start);
 	do {
 		*pmdk++ = __pmd(phys | pmdprot);
 		phys += PMD_SIZE;
 	} while (phys < map_end);
 
+	/*
+	 * Ensure that the above updates are flushed out of the cache.
+	 * This is not strictly correct; on a system where the caches
+	 * are coherent with each other, but the MMU page table walks
+	 * may not be coherent, flush_cache_all() may be a no-op, and
+	 * this will fail.
+	 */
 	flush_cache_all();
+
+	/*
+	 * Re-write the TTBR values to point them at the high physical
+	 * alias of the page tables.  We expect __va() will work on
+	 * cpu_get_pgd(), which returns the value of TTBR0.
+	 */
 	cpu_switch_mm(pgd0, &init_mm);
 	cpu_set_ttbr(1, __pa(pgd0) + TTBR1_OFFSET);
+
+	/* Finally flush any stale TLB values. */
 	local_flush_bp_all();
 	local_flush_tlb_all();
 }


-- 
FTTC broadband for 0.8mile line: currently@9.5Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply related

* [PATCH 02/14] clk: sunxi: factors: Implement clock min and max frequencies
From: Emilio López @ 2014-07-17 16:09 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1405588134-2396-3-git-send-email-maxime.ripard@free-electrons.com>

Hi Maxime,

El 17/07/14 06:08, Maxime Ripard escribi?:
> In the A13, the out of reset frequency for the PLL6 is too high to be actually
> working.
>
> Hence, we need to be able to lower down its frequency whenever we need to use
> the clock to some acceptable frequency.
>
> This patch adds two new properties in the clock-nodes, clk-min-frequency and
> clk-max-frequency, to specify acceptable boundaries for proper clock
> operations.

This paragraph looks out of place

>
> It also adds supports in the sunxi factor clocks driver to use these
> boundaries, enforce them at prepare time to make sure that the drivers will
> have a decent frequency, even though it never called set_rate, but also make
> sure we never cross these boundaries.
>
> Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
> ---
(...)
>
> @@ -123,6 +147,9 @@ static int clk_factors_set_rate(struct clk_hw *hw, unsigned long rate,
>
>   	factors->get_factors((u32 *)&rate, (u32)parent_rate, &n, &k, &m, &p);
>
> +	if ((rate > factors->max_rate) || (rate < factors->min_rate))
> +		return -EINVAL;

Printing an error message here may come in handy in the future, what do 
you think?

Thanks for working on this!

Emilio

^ permalink raw reply

* [PATCH 4/5] tty: serial: 8250 core: add runtime pm
From: Sebastian Andrzej Siewior @ 2014-07-17 16:06 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140717160206.GI10459@saruman.home>

On 07/17/2014 06:02 PM, Felipe Balbi wrote:
>> diff --git a/drivers/tty/serial/8250/8250_core.c
>> b/drivers/tty/serial/8250/8250_core.c index 2e4a93b..480a1c0
>> 100644 --- a/drivers/tty/serial/8250/8250_core.c +++
>> b/drivers/tty/serial/8250/8250_core.c @@ -1283,6 +1283,9 @@
>> static inline void __stop_tx(struct uart_8250_port *p) if (p->ier
>> & UART_IER_THRI) { p->ier &= ~UART_IER_THRI; serial_out(p,
>> UART_IER, p->ier); + +		pm_runtime_mark_last_busy(p->port.dev); +
>> pm_runtime_put_autosuspend(p->port.dev); } }
>> 
>> @@ -1310,12 +1313,12 @@ static void serial8250_start_tx(struct
>> uart_port *port) struct uart_8250_port *up = container_of(port,
>> struct uart_8250_port, port);
>> 
>> -	pm_runtime_get_sync(port->dev); if (up->dma &&
>> !serial8250_tx_dma(up)) { goto out; } else if (!(up->ier &
>> UART_IER_THRI)) { up->ier |= UART_IER_THRI; +
>> pm_runtime_get_sync(port->dev); serial_port_out(port, UART_IER,
>> up->ier);
>> 
>> if (up->bugs & UART_BUG_TXEN) { unsigned char lsr;
> 
> this looks better. So we get on start_tx() and put on stop_tx().
> 
>> @@ -1500,9 +1503,10 @@ void serial8250_tx_chars(struct
>> uart_8250_port *up) uart_write_wakeup(port);
>> 
>> DEBUG_INTR("THRE..."); - +#if 0 if (uart_circ_empty(xmit)) 
>> __stop_tx(up); +#endif } EXPORT_SYMBOL_GPL(serial8250_tx_chars);
> 
> is it so that start_tx() gets called one and stop_tx() might be
> called N times ? That looks unbalanced to me. If the calls are
> balanced, then you shouldn't need to care because pm_runtime will
> handle reference counting for you, right?

No, this is okay. If you look, it checks for "up->ier &
UART_IER_THRI". On the second invocation it will see that this bit is
already set and therefore won't call get_sync() for the second time.
That bit is removed in the _stop_tx() path.

>> and now I need to come up with something that is not if (port !=
>> omap) for that #if 0 block. The code disables the TX FIFO empty
>> interrupt once the transfer is complete. I want to call
>> __stop_tx() once the tx fifo is empty. Felipe, Would a check for
>> dev->power.use_autosuspend be the right thing to do?
> 
> probably not, as that's internal to the pm_runtime code. But I
> wonder if start/stop tx calls are balanced, if they are then we're
> good. Unless I'm missing something else.

Do you have other ideas? It doesn't look like this is exported at all.
If we call _stop_tx() right away, then we have 64 bytes in the TX fifo
in the worst case. They should be gone "soon" but the HW-flow control
may delay it (in theory for a long time)).

Sebastian

^ permalink raw reply

* [PATCH v4 1/3] soc: devicetree: bindings: Add Qualcomm RPM DT binding
From: pramod gurav @ 2014-07-17 16:04 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAJAp7OggtuxPSc0yXzMCs10aQ2R6E+m4Bu8sdLJopvrZ3+5Rmg@mail.gmail.com>

On Thu, Jul 17, 2014 at 3:50 AM, Bjorn Andersson <bjorn@kryo.se> wrote:
>> On Wed, Jul 16, 2014 at 4:30 AM, Bjorn Andersson
>> <bjorn.andersson@sonymobile.com> wrote:
> [...]
>>> +       rpm at 108000 {
>>> +               compatible = "qcom,rpm-msm8960";
>>> +               reg = <0x108000 0x1000>;
>>> +               qcom,ipc = <&apcs 0x8 2>;
>>
>> Tried adding this but there is no reference to 'apcs' registers itself
>> in any dts.
>>
>> Without these changes rpm breaks hence not able to test SATA which needs rpm.
>>
>
> Hi Pramod,
>
> Unfortunately the ipc bits resides in a block that needs to be
> accesses by various device drivers so I had to extract the access; so
> you now need to reference it via a syscon handle and offset instead -
> as described above.
>
> The apcs node I used for testing this with looks like this:
>
> apcs: syscon at 2011000 {
>     compatible = "syscon";
>     reg = <0x2011000 0x1000>;
> };
>
> Enable CONFIG_MFD_SYSCON and put the dt snippet somewhere under soc
> and you should be good.
>

Thanks Bjorn. Did this and seen things working (sata atleast).

> Regards,
> Bjorn



-- 
Thanks and Regards
Pramod

^ permalink raw reply

* [PATCH 0/3] ARM: mvebu: disable I/O coherency on !SMP
From: Santosh Shilimkar @ 2014-07-17 16:04 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <5105942.b7kcvNdlC8@wuerfel>

On Thursday 17 July 2014 11:53 AM, Arnd Bergmann wrote:
> On Thursday 17 July 2014 16:34:01 Russell King - ARM Linux wrote:
>> On Thu, Jul 17, 2014 at 04:40:21PM +0200, Arnd Bergmann wrote:
>>> On Thursday 17 July 2014 15:27:20 Will Deacon wrote:
>>>> Just an FYI, but I've had to check internally to clarify the behaviour
>>>> around TLB conflict aborts. We're changing live page tables here, but the
>>>> *only* thing to differ is the output address, which I would hope is ok but
>>>> need to check to be sure.
>>>
>>> The two cases are slightly different:
>>>
>>> - The existing keystone code changes the output address but not the flags
>>> - The hypothetical mvebu code needs to change the flags but not the address.
>>
>> Don't base too much confidence in the keystone code:
> 
> What I meant was that verifying the correctness of one of the two above
> with the architecture team doesn't mean that the other one is okay too.
> 
>>         map_start = init_mm.start_code;
>>         map_end   = init_mm.brk;
>>
>>         phys = __pa(map_start) & PMD_MASK;
>>         do {
>> ...
>>                 phys += PMD_SIZE;
>>         } while (phys < map_end);
>>
>> Consider what happens when map_end is not PMD aligned - it misses the
>> PMD covering the end of the kernel BSS, which will be quite a common
>> case.  Obviously something that needs fixing...
> 
> Ouch.
> 
Thanks for spotting it RMK. Will have a loot at it.

regards,
Santosh

^ permalink raw reply

* [PATCH 5/5] tty: serial: Add 8250-core based omap driver
From: Felipe Balbi @ 2014-07-17 16:04 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <53C7E7BE.7030403@linutronix.de>

On Thu, Jul 17, 2014 at 05:11:58PM +0200, Sebastian Andrzej Siewior wrote:
> On 07/17/2014 04:54 PM, Felipe Balbi wrote:
> > Hi,
> > 
> > On Wed, Jul 16, 2014 at 04:45:03PM +0200, Sebastian Andrzej Siewior wrote:
> >> +static int omap_8250_startup(struct uart_port *port)
> >> +{
> >> +	struct uart_8250_port *up =
> >> +		container_of(port, struct uart_8250_port, port);
> >> +	struct omap8250_priv *priv = port->private_data;
> >> +
> >> +	int ret;
> >> +
> >> +	if (priv->wakeirq) {
> >> +		ret = request_irq(priv->wakeirq, omap_wake_irq,
> >> +				port->irqflags, "wakeup irq", port);
> >> +		if (ret)
> >> +			return ret;
> >> +		disable_irq(priv->wakeirq);
> >> +	}
> >> +
> >> +	ret = serial8250_do_startup(port);
> >> +	if (ret)
> >> +		goto err;
> >> +
> >> +	pm_runtime_get_sync(port->dev);
> > 
> > should this pm_runtime_get_sync() be placed above
> > serial8250_do_startup() call ?
> 
> I don't think it matters since serial8250_do_startup() has its own
> pm_runtime_get_sync().

oh right, saw that now.

> ->startup(), ->shutdown() are called via omap callbacks so we could
> spare in the 8250-core if we do it in the omap code before invoking the
> function. The same goes for serial8250_set_termios() which is not used
> by omap but has those runtime-pm stuff, too.
> It would be wrong if someone would use the serial8250_do_startup()
> without his own runtime-pm get but it is omap only which does this
> things.
> So it is not used by anyone else (right now) and if you want to keep it
> to a minimum I could remove them from those places.

I don't think it matters as long as the calls are balanced.

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140717/fe4ab5fe/attachment.sig>

^ permalink raw reply

* [PATCH 4/5] tty: serial: 8250 core: add runtime pm
From: Felipe Balbi @ 2014-07-17 16:02 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140717154300.GA16623@linutronix.de>

Hi,

On Thu, Jul 17, 2014 at 05:43:00PM +0200, Sebastian Andrzej Siewior wrote:
> * Peter Hurley | 2014-07-17 11:31:59 [-0400]:
> 
> >On 07/16/2014 12:06 PM, Felipe Balbi wrote:
> >>On Wed, Jul 16, 2014 at 05:54:56PM +0200, Sebastian Andrzej Siewior wrote:
> >>>On 07/16/2014 05:16 PM, Felipe Balbi wrote:
> >
> >>>>I wonder if you should get_sync() on start_tx() and only
> >>>>put_autosuspend() at stop_tx(). I guess the outcome would be
> >>>>largely the same, no ?
> >>>
> >>>I just opened minicom on ttyS0 and gave a try. start_tx() was invoked
> >>>each time I pressed a key (sent a character). I haven't seen stop_tx()
> >>>even after after I closed minicom. I guess stop_tx() is invoked if you
> >>>switch half-duplex communication.
> >>
> >>that's bad, I expected stop to be called also after each character.
> >
> >The 8250 core auto-stops tx when the tx ring buffer is empty (except
> >in the case of dma, where stopping tx isn't necessary).
> 
> This is correct. So this is what I have now for the non-dma case:
> 
> diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c
> index 2e4a93b..480a1c0 100644
> --- a/drivers/tty/serial/8250/8250_core.c
> +++ b/drivers/tty/serial/8250/8250_core.c
> @@ -1283,6 +1283,9 @@ static inline void __stop_tx(struct uart_8250_port *p)
>  	if (p->ier & UART_IER_THRI) {
>  		p->ier &= ~UART_IER_THRI;
>  		serial_out(p, UART_IER, p->ier);
> +
> +		pm_runtime_mark_last_busy(p->port.dev);
> +		pm_runtime_put_autosuspend(p->port.dev);
>  	}
>  }
>  
> @@ -1310,12 +1313,12 @@ static void serial8250_start_tx(struct uart_port *port)
>  	struct uart_8250_port *up =
>  		container_of(port, struct uart_8250_port, port);
>  
> -	pm_runtime_get_sync(port->dev);
>  	if (up->dma && !serial8250_tx_dma(up)) {
>  		goto out;
>  	} else if (!(up->ier & UART_IER_THRI)) {
>  		up->ier |= UART_IER_THRI;
> +		pm_runtime_get_sync(port->dev);
>  		serial_port_out(port, UART_IER, up->ier);
>  
>  		if (up->bugs & UART_BUG_TXEN) {
>  			unsigned char lsr;

this looks better. So we get on start_tx() and put on stop_tx().

> @@ -1500,9 +1503,10 @@ void serial8250_tx_chars(struct uart_8250_port *up)
>  		uart_write_wakeup(port);
>  
>  	DEBUG_INTR("THRE...");
> -
> +#if 0
>  	if (uart_circ_empty(xmit))
>  		__stop_tx(up);
> +#endif
>  }
>  EXPORT_SYMBOL_GPL(serial8250_tx_chars);

is it so that start_tx() gets called one and stop_tx() might be called N
times ? That looks unbalanced to me. If the calls are balanced, then you
shouldn't need to care because pm_runtime will handle reference counting
for you, right?

> and now I need to come up with something that is not if (port != omap)
> for that #if 0 block. The code disables the TX FIFO empty interrupt once
> the transfer is complete. I want to call __stop_tx() once the tx fifo is
> empty.
> Felipe, Would a check for dev->power.use_autosuspend be the right thing
> to do?

probably not, as that's internal to the pm_runtime code. But I wonder if
start/stop tx calls are balanced, if they are then we're good. Unless
I'm missing something else.

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140717/f4f5d84b/attachment.sig>

^ permalink raw reply

* [RESEND PATCH v7 3/4] arm: dirty log write protect management support
From: Mario Smarduch @ 2014-07-17 16:00 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <53B6D66B.9070608@redhat.com>

On 07/04/2014 09:29 AM, Paolo Bonzini wrote:
> Il 03/07/2014 17:04, Christoffer Dall ha scritto:
>> Hmmm, I'm really not an expert in the 'established procedures' for what
>> to put in config files etc., but here's my basic take:
>>
>> a) you wouldn't put a config option in Kconfig unless it's comething
>> that's actually configurable or some generic feature/subsystem that
>> should only be enabled if hardware has certain capabilities or other
>> config options enabled.
>>
>> b) this seems entirely an implementation issue and not depending on
>> anything users should select.
> 
> Actually I think Mario's idea is just fine.  Non-user-accessible Kconfig
> symbols are used a lot to invoke an #ifdef elsewhere in the code;
> compare this with his proposal is a bit different but not too much.
> 
> Sometimes #defines are used, sometimes Kconfig symbols, but the idea is
> the same.
> 
> Paolo

Hi Paolo,
  thanks for your feedback. I forgot to add that I tried define 
ARCH_HAVE_... approach but checkpatch rejected it and insisted
on Kconfig.

Thanks,
- Mario

^ permalink raw reply

* [PATCH RFCv3 01/14] arm64: introduce aarch64_insn_gen_comp_branch_imm()
From: Alexei Starovoitov @ 2014-07-17 15:59 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140717091931.GC21153@arm.com>

On Thu, Jul 17, 2014 at 2:19 AM, Will Deacon <will.deacon@arm.com> wrote:
> On Wed, Jul 16, 2014 at 10:19:31PM +0100, Zi Shen Lim wrote:
>> >
>> > Is a BUG_ON justifiable here? Is there not a nicer way to fail?
>>
>> In general, it'd be nice if we returned something like -EINVAL and
>> have all callers handle failures. Today all code gen functions return
>> the u32 instruction and there's no error handling by callers.
>> I think following the precedence (aarch64_insn_gen_branch_imm())
>> of failing with BUG_ON is a reasonable tradeoff.
>
> Well, I don't necessarily agree with that BUG_ON, either :)
> I take it eBPF doesn't have a `trap' instruction or similar? Otherwise, we
> could generate that and avoid having to propagate errors directly to the
> caller.
>
>> In this case here, when we hit the default (failure) case, that means
>> there's a serious error of attempting to use an unsupported
>> variant. I think we're better off failing hard here than trying to
>> arbitrarily "fallback" on a default choice.
>
> It might be a serious error for BPF, but a BUG_ON brings down the entire
> machine, which I think is unfortunate.

There is some misunderstanding here. Here BUG_ON will trigger
only on actual bug in JIT implementation, it cannot be triggered by user.
eBPF program is verified before it reaches JIT, so all instructions are
valid and input to JIT is proper. Two instruction are not yet
implemented in this JIT and they trigger pr_.._once().
So I don't see any issue with this usage of BUG_ON
imo living with silent bugs in JIT is more dangerous.

For the same reason there is no 'trap' instruction in eBPF.
Static verifier checks that program is valid. If there was a 'trap'
insn the program would be rejected. Like programs with
'div by zero' are rejected. There is normal 'bpf_exit' insn to
return from the program.

^ permalink raw reply

* [PATCH] irqchip: gic: Fix core ID calculation when topology is read from DT
From: Tomasz Figa @ 2014-07-17 15:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140717155105.GT13108@titan.lakedaemon.net>

On 17.07.2014 17:51, Jason Cooper wrote:
> On Thu, Jul 17, 2014 at 05:40:50PM +0200, Tomasz Figa wrote:
>> Hi Jason,
>>
>> On 17.07.2014 17:32, Jason Cooper wrote:
>>> On Thu, Jul 17, 2014 at 05:23:44PM +0200, Tomasz Figa wrote:
>>>> Certain GIC implementation, namely those found on earlier, single
>>>> cluster, Exynos SoCs, have registers mapped without per-CPU banking,
>>>> which means that the driver needs to use different offset for each CPU.
>>>>
>>>> Currently the driver calculates the offset by multiplying value returned
>>>> by cpu_logical_map() by CPU offset parsed from DT. This is correct when
>>>> CPU topology is not specified in DT and aforementioned function returns
>>>> core ID alone. However when DT contains CPU topology, the function
>>>> changes to return cluster ID as well, which is non-zero on mentioned
>>>> SoCs and so breaks the calculation in GIC driver.
>>>>
>>>> This patch fixes this by masking out cluster ID in CPU offset
>>>> calculation so that only core ID is considered. Multi-cluster Exynos
>>>> SoCs already have banked GIC implementations, so this simple fix should
>>>> be enough.
>>>>
>>>> Reported-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
>>>> Reported-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
>>>> Signed-off-by: Tomasz Figa <t.figa@samsung.com>
>>>> ---
>>>>  drivers/irqchip/irq-gic.c | 5 ++++-
>>>>  1 file changed, 4 insertions(+), 1 deletion(-)
>>>
>>> iiuc, this was introduced by:
>>>
>>>   db0d4db22a78d ARM: gic: allow GIC to support non-banked setups
>>>
>>> and so should be for v3.3 and up, correct?
>>
>> Could be, although there was and still is no topology data specified in
>> DT for affected Exynos SoCs. The need for it showed up just recently, so
>> I'm not sure this is a regression to fix in older kernels.
> 
> In my "the kernel and the dtb aren't tied together" quest, these are the
> kinds of things I like to see fixed in stable kernels.
> 
> If a user needs to update a dtb, say to fix a bug, it's reasonable to
> use the newest one for a given board.  After all, any new nodes won't
> change anything, since the driver in the kernel won't match the node.
> 
> However, in this case, without this fix, a user upgrading to the newest
> dtb would get a broken system.  So, this fix should be backported to
> prevent the breakage.  Or, have I missed something in my analysis?

This is correct when looking only at this issue. However I suspect such
move would cause a breakage anyway, because DT stuff isn't that stable
on Exynos side. I don't mind if this patch hits stable, though.

Best regards,
Tomasz

^ permalink raw reply

* [PATCH v2 2/2] ARM: EXYNOS: Add support for firmware-assisted suspend/resume
From: Tomasz Figa @ 2014-07-17 15:56 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1405612571-32598-1-git-send-email-t.figa@samsung.com>

On a numer of Exynos-based boards Linux kernel is running in non-secure
mode under a secure firmware. This means that certain operations need to
be handled in special way, with firmware assistance. System-wide
suspend/resume is an example of such operations.

This patch adds support for firmware-assisted suspend/resume by
leveraging recently introduced suspend and resume firmware operations
and modifying existing suspend/resume paths to account for presence of
secure firmware.

Signed-off-by: Tomasz Figa <t.figa@samsung.com>
---
 arch/arm/mach-exynos/Makefile   |  1 +
 arch/arm/mach-exynos/common.h   |  4 ++++
 arch/arm/mach-exynos/firmware.c | 45 +++++++++++++++++++++++++++++++++++++++++
 arch/arm/mach-exynos/pm.c       | 16 ++++++++++-----
 arch/arm/mach-exynos/sleep.S    | 28 +++++++++++++++++++++++++
 arch/arm/mach-exynos/smc.h      |  4 ++++
 6 files changed, 93 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-exynos/Makefile b/arch/arm/mach-exynos/Makefile
index 788f26d..e7d1774 100644
--- a/arch/arm/mach-exynos/Makefile
+++ b/arch/arm/mach-exynos/Makefile
@@ -26,6 +26,7 @@ CFLAGS_hotplug.o		+= -march=armv7-a
 
 plus_sec := $(call as-instr,.arch_extension sec,+sec)
 AFLAGS_exynos-smc.o		:=-Wa,-march=armv7-a$(plus_sec)
+AFLAGS_sleep.o			:=-Wa,-march=armv7-a$(plus_sec)
 
 obj-$(CONFIG_EXYNOS5420_MCPM)	+= mcpm-exynos.o
 CFLAGS_mcpm-exynos.o		+= -march=armv7-a
diff --git a/arch/arm/mach-exynos/common.h b/arch/arm/mach-exynos/common.h
index f8daa9c..a3f3061 100644
--- a/arch/arm/mach-exynos/common.h
+++ b/arch/arm/mach-exynos/common.h
@@ -111,6 +111,9 @@ IS_SAMSUNG_CPU(exynos5800, EXYNOS5800_SOC_ID, EXYNOS5_SOC_MASK)
 #define soc_is_exynos5() (soc_is_exynos5250() || soc_is_exynos5410() || \
 			  soc_is_exynos5420() || soc_is_exynos5800())
 
+extern u32 cp15_save_diag;
+extern u32 cp15_save_power;
+
 extern void __iomem *sysram_ns_base_addr;
 extern void __iomem *sysram_base_addr;
 extern void __iomem *pmu_base_addr;
@@ -127,6 +130,7 @@ static inline void exynos_pm_init(void) {}
 #endif
 
 extern void exynos_cpu_resume(void);
+extern void exynos_cpu_resume_ns(void);
 
 extern struct smp_operations exynos_smp_ops;
 
diff --git a/arch/arm/mach-exynos/firmware.c b/arch/arm/mach-exynos/firmware.c
index e8797bb..f5e626d 100644
--- a/arch/arm/mach-exynos/firmware.c
+++ b/arch/arm/mach-exynos/firmware.c
@@ -14,13 +14,20 @@
 #include <linux/of.h>
 #include <linux/of_address.h>
 
+#include <asm/cacheflush.h>
+#include <asm/cputype.h>
 #include <asm/firmware.h>
+#include <asm/suspend.h>
 
 #include <mach/map.h>
 
 #include "common.h"
 #include "smc.h"
 
+#define EXYNOS_SLEEP_MAGIC	0x00000bad
+#define EXYNOS_BOOT_ADDR	0x8
+#define EXYNOS_BOOT_FLAG	0xc
+
 static int exynos_do_idle(void)
 {
 	exynos_smc(SMC_CMD_SLEEP, 0, 0, 0);
@@ -69,10 +76,48 @@ static int exynos_set_cpu_boot_addr(int cpu, unsigned long boot_addr)
 	return 0;
 }
 
+static int exynos_cpu_suspend(unsigned long arg)
+{
+	flush_cache_all();
+	outer_flush_all();
+
+	exynos_smc(SMC_CMD_SLEEP, 0, 0, 0);
+
+	pr_info("Failed to suspend the system\n");
+	writel(0, sysram_ns_base_addr + EXYNOS_BOOT_FLAG);
+	return 1;
+}
+
+static int exynos_suspend(void)
+{
+	if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9) {
+		/* Save Power control and Diagnostic registers */
+		asm ("mrc p15, 0, %0, c15, c0, 0\n"
+			"mrc p15, 0, %1, c15, c0, 1\n"
+			: "=r" (cp15_save_power), "=r" (cp15_save_diag)
+			: : "cc");
+	}
+
+	writel(EXYNOS_SLEEP_MAGIC, sysram_ns_base_addr + EXYNOS_BOOT_FLAG);
+	writel(virt_to_phys(exynos_cpu_resume_ns),
+		sysram_ns_base_addr + EXYNOS_BOOT_ADDR);
+
+	return cpu_suspend(0, exynos_cpu_suspend);
+}
+
+static int exynos_resume(void)
+{
+	writel(0, sysram_ns_base_addr + EXYNOS_BOOT_FLAG);
+
+	return 0;
+}
+
 static const struct firmware_ops exynos_firmware_ops = {
 	.do_idle		= exynos_do_idle,
 	.set_cpu_boot_addr	= exynos_set_cpu_boot_addr,
 	.cpu_boot		= exynos_cpu_boot,
+	.suspend		= exynos_suspend,
+	.resume			= exynos_resume,
 };
 
 void __init exynos_firmware_init(void)
diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c
index 63a1d6b..681e894 100644
--- a/arch/arm/mach-exynos/pm.c
+++ b/arch/arm/mach-exynos/pm.c
@@ -23,6 +23,7 @@
 #include <linux/clk.h>
 
 #include <asm/cacheflush.h>
+#include <asm/firmware.h>
 #include <asm/hardware/cache-l2x0.h>
 #include <asm/smp_scu.h>
 #include <asm/suspend.h>
@@ -354,12 +355,11 @@ static int exynos_pm_suspend(void)
 
 static void exynos_pm_resume(void)
 {
+	u32 cpuid = read_cpuid_part();
+
 	if (exynos_pm_central_resume())
 		goto early_wakeup;
 
-	if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9)
-		exynos_cpu_restore_register();
-
 	/* For release retention */
 
 	__raw_writel((1 << 28), S5P_PAD_RET_MAUDIO_OPTION);
@@ -376,9 +376,13 @@ static void exynos_pm_resume(void)
 
 	s3c_pm_do_restore_core(exynos_core_save, ARRAY_SIZE(exynos_core_save));
 
-	if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9)
+	if (cpuid == ARM_CPU_PART_CORTEX_A9)
 		scu_enable(S5P_VA_SCU);
 
+	if (call_firmware_op(resume) == -ENOSYS
+	    && cpuid == ARM_CPU_PART_CORTEX_A9)
+		exynos_cpu_restore_register();
+
 early_wakeup:
 
 	/* Clear SLEEP mode set in INFORM1 */
@@ -419,7 +423,9 @@ static int exynos_suspend_enter(suspend_state_t state)
 	flush_cache_all();
 	s3c_pm_check_store();
 
-	ret = cpu_suspend(0, exynos_cpu_suspend);
+	ret = call_firmware_op(suspend);
+	if (ret == -ENOSYS)
+		ret = cpu_suspend(0, exynos_cpu_suspend);
 	if (ret)
 		return ret;
 
diff --git a/arch/arm/mach-exynos/sleep.S b/arch/arm/mach-exynos/sleep.S
index 108a45f..e3c3730 100644
--- a/arch/arm/mach-exynos/sleep.S
+++ b/arch/arm/mach-exynos/sleep.S
@@ -16,6 +16,7 @@
  */
 
 #include <linux/linkage.h>
+#include "smc.h"
 
 #define CPU_MASK	0xff0ffff0
 #define CPU_CORTEX_A9	0x410fc090
@@ -55,3 +56,30 @@ ENTRY(exynos_cpu_resume)
 #endif
 	b	cpu_resume
 ENDPROC(exynos_cpu_resume)
+
+	.align
+
+ENTRY(exynos_cpu_resume_ns)
+	mrc	p15, 0, r0, c0, c0, 0
+	ldr	r1, =CPU_MASK
+	and	r0, r0, r1
+	ldr	r1, =CPU_CORTEX_A9
+	cmp	r0, r1
+	bne	skip_cp15
+
+	adr	r0, cp15_save_power
+	ldr	r1, [r0]
+	adr	r0, cp15_save_diag
+	ldr	r2, [r0]
+	mov	r0, #SMC_CMD_C15RESUME
+	dsb
+	smc	#0
+skip_cp15:
+	b	cpu_resume
+ENDPROC(exynos_cpu_resume_ns)
+	.globl cp15_save_diag
+cp15_save_diag:
+	.long	0	@ cp15 diagnostic
+	.globl cp15_save_power
+cp15_save_power:
+	.long	0	@ cp15 power control
diff --git a/arch/arm/mach-exynos/smc.h b/arch/arm/mach-exynos/smc.h
index 13a1dc8..f7b82f9 100644
--- a/arch/arm/mach-exynos/smc.h
+++ b/arch/arm/mach-exynos/smc.h
@@ -26,6 +26,10 @@
 #define SMC_CMD_L2X0INVALL	(-24)
 #define SMC_CMD_L2X0DEBUG	(-25)
 
+#ifndef __ASSEMBLY__
+
 extern void exynos_smc(u32 cmd, u32 arg1, u32 arg2, u32 arg3);
 
+#endif /* __ASSEMBLY__ */
+
 #endif
-- 
1.9.3

^ permalink raw reply related

* [PATCH v2 1/2] ARM: firmware: Introduce suspend and resume operations
From: Tomasz Figa @ 2014-07-17 15:56 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1405612571-32598-1-git-send-email-t.figa@samsung.com>

This patch extends the firmware_ops structure with two new callbacks:
.suspend() and .resume(). The former is intended to ask the firmware to
save all its volatile state and suspend the system, without returning
back to the kernel in between. The latter is to be called early by
very low level platform suspend code after waking up to restore low
level hardware state, which can't be restored in non-secure mode.

While at it, outdated version of the structure is removed from the
documentation and replaced with a reference to the header file.

Signed-off-by: Tomasz Figa <t.figa@samsung.com>
Acked-by: Alexandre Courbot <acourbot@nvidia.com>
---
 Documentation/arm/firmware.txt  | 28 +++++-----------------------
 arch/arm/include/asm/firmware.h |  8 ++++++++
 2 files changed, 13 insertions(+), 23 deletions(-)

diff --git a/Documentation/arm/firmware.txt b/Documentation/arm/firmware.txt
index c2e468f..da6713a 100644
--- a/Documentation/arm/firmware.txt
+++ b/Documentation/arm/firmware.txt
@@ -7,32 +7,14 @@ world, which changes the way some things have to be initialized. This makes
 a need to provide an interface for such platforms to specify available firmware
 operations and call them when needed.
 
-Firmware operations can be specified using struct firmware_ops
-
-	struct firmware_ops {
-		/*
-		* Enters CPU idle mode
-		*/
-		int (*do_idle)(void);
-		/*
-		* Sets boot address of specified physical CPU
-		*/
-		int (*set_cpu_boot_addr)(int cpu, unsigned long boot_addr);
-		/*
-		* Boots specified physical CPU
-		*/
-		int (*cpu_boot)(int cpu);
-		/*
-		* Initializes L2 cache
-		*/
-		int (*l2x0_init)(void);
-	};
-
-and then registered with register_firmware_ops function
+Firmware operations can be specified by filling in a struct firmware_ops
+with appropriate callbacks and then registering it with register_firmware_ops()
+function.
 
 	void register_firmware_ops(const struct firmware_ops *ops)
 
-the ops pointer must be non-NULL.
+The ops pointer must be non-NULL. More information about struct firmware_ops
+and its members can be found in arch/arm/include/asm/firmware.h header.
 
 There is a default, empty set of operations provided, so there is no need to
 set anything if platform does not require firmware operations.
diff --git a/arch/arm/include/asm/firmware.h b/arch/arm/include/asm/firmware.h
index 2c9f10d..5904f59 100644
--- a/arch/arm/include/asm/firmware.h
+++ b/arch/arm/include/asm/firmware.h
@@ -41,6 +41,14 @@ struct firmware_ops {
 	 * Initializes L2 cache
 	 */
 	int (*l2x0_init)(void);
+	/*
+	 * Enter system-wide suspend.
+	 */
+	int (*suspend)(void);
+	/*
+	 * Restore state of privileged hardware after system-wide suspend.
+	 */
+	int (*resume)(void);
 };
 
 /* Global pointer for current firmware_ops structure, can't be NULL. */
-- 
1.9.3

^ permalink raw reply related

* [PATCH v2 0/2] Firmware-assisted suspend/resume of Exynos SoCs
From: Tomasz Figa @ 2014-07-17 15:56 UTC (permalink / raw)
  To: linux-arm-kernel

On Exynos-based boards running secure firmware the sequence of low level
operations to enter and leave system-wide sleep mode is different than
on those without the firmware. Namely:
 - CP15 power control and diagnostic registers cannot be written directly,
 - the way of setting boot address and boot flag is different,
 - different resume handler needs to be used,
 - dedicated SMC call needs to be performed instead of letting the CPU enter
   WFI.

This series introduces .suspend() and .resume() firmware operations to
perform low level firmware-specific suspend and resume and then leverages
them to provide suspend-resume path meeting the above requirements.

The series is based on Kgene's for-next branch and tested on:
 - Exynos4412-based Trats2 board running in non-secure mode (under secure
   firmware) with few board-specific fixes that will be sent separately soon,
 - Exynos4210-based Trats board running in secure mode,
 - Exynos4412-based ODROID-U3 board running in non-secure mode with one minor
   board-specific fix which will be send shortly.

Depends on:
 - [PATCH v3] ARM: save/restore Cortex-A9 CP15 registers on suspend/resume
   (http://www.spinics.net/lists/arm-kernel/msg346212.html)
 - [PATCH v3] ARM: EXYNOS: Fix suspend/resume sequences
   (https://lkml.org/lkml/2014/7/15/319)
 - [PATCH] ARM: make it easier to check the CPU part number correctly
   (http://thread.gmane.org/gmane.linux.ports.arm.kernel/335126
    already in linux-next)

Changes since v1:
 - dropped outer_resume() - will be handled in assembly in further patches,
   as support for L2C in non-secure mode gets added,
 - moved CP15 resume to assembly as it needs to be done before MMU is enabled,
 - surrounded CP15 save with a check for cpuid part, because it is valid only
   on Cortex A9,
 - rebased on next-20140717 tag of linux-next tree.

Tomasz Figa (2):
  ARM: firmware: Introduce suspend and resume operations
  ARM: EXYNOS: Add support for firmware-assisted suspend/resume

 Documentation/arm/firmware.txt  | 28 +++++--------------------
 arch/arm/include/asm/firmware.h |  8 ++++++++
 arch/arm/mach-exynos/Makefile   |  1 +
 arch/arm/mach-exynos/common.h   |  4 ++++
 arch/arm/mach-exynos/firmware.c | 45 +++++++++++++++++++++++++++++++++++++++++
 arch/arm/mach-exynos/pm.c       | 16 ++++++++++-----
 arch/arm/mach-exynos/sleep.S    | 28 +++++++++++++++++++++++++
 arch/arm/mach-exynos/smc.h      |  4 ++++
 8 files changed, 106 insertions(+), 28 deletions(-)

-- 
1.9.3

^ permalink raw reply

* [PATCH 0/3] ARM: mvebu: disable I/O coherency on !SMP
From: Arnd Bergmann @ 2014-07-17 15:53 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140717153401.GX21766@n2100.arm.linux.org.uk>

On Thursday 17 July 2014 16:34:01 Russell King - ARM Linux wrote:
> On Thu, Jul 17, 2014 at 04:40:21PM +0200, Arnd Bergmann wrote:
> > On Thursday 17 July 2014 15:27:20 Will Deacon wrote:
> > > Just an FYI, but I've had to check internally to clarify the behaviour
> > > around TLB conflict aborts. We're changing live page tables here, but the
> > > *only* thing to differ is the output address, which I would hope is ok but
> > > need to check to be sure.
> > 
> > The two cases are slightly different:
> > 
> > - The existing keystone code changes the output address but not the flags
> > - The hypothetical mvebu code needs to change the flags but not the address.
> 
> Don't base too much confidence in the keystone code:

What I meant was that verifying the correctness of one of the two above
with the architecture team doesn't mean that the other one is okay too.

>         map_start = init_mm.start_code;
>         map_end   = init_mm.brk;
> 
>         phys = __pa(map_start) & PMD_MASK;
>         do {
> ...
>                 phys += PMD_SIZE;
>         } while (phys < map_end);
> 
> Consider what happens when map_end is not PMD aligned - it misses the
> PMD covering the end of the kernel BSS, which will be quite a common
> case.  Obviously something that needs fixing...

Ouch.

	Arnd

^ permalink raw reply

* [PATCH] irqchip: gic: Fix core ID calculation when topology is read from DT
From: Jason Cooper @ 2014-07-17 15:51 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <53C7EE82.6040803@samsung.com>

On Thu, Jul 17, 2014 at 05:40:50PM +0200, Tomasz Figa wrote:
> Hi Jason,
> 
> On 17.07.2014 17:32, Jason Cooper wrote:
> > On Thu, Jul 17, 2014 at 05:23:44PM +0200, Tomasz Figa wrote:
> >> Certain GIC implementation, namely those found on earlier, single
> >> cluster, Exynos SoCs, have registers mapped without per-CPU banking,
> >> which means that the driver needs to use different offset for each CPU.
> >>
> >> Currently the driver calculates the offset by multiplying value returned
> >> by cpu_logical_map() by CPU offset parsed from DT. This is correct when
> >> CPU topology is not specified in DT and aforementioned function returns
> >> core ID alone. However when DT contains CPU topology, the function
> >> changes to return cluster ID as well, which is non-zero on mentioned
> >> SoCs and so breaks the calculation in GIC driver.
> >>
> >> This patch fixes this by masking out cluster ID in CPU offset
> >> calculation so that only core ID is considered. Multi-cluster Exynos
> >> SoCs already have banked GIC implementations, so this simple fix should
> >> be enough.
> >>
> >> Reported-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> >> Reported-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
> >> Signed-off-by: Tomasz Figa <t.figa@samsung.com>
> >> ---
> >>  drivers/irqchip/irq-gic.c | 5 ++++-
> >>  1 file changed, 4 insertions(+), 1 deletion(-)
> > 
> > iiuc, this was introduced by:
> > 
> >   db0d4db22a78d ARM: gic: allow GIC to support non-banked setups
> > 
> > and so should be for v3.3 and up, correct?
> 
> Could be, although there was and still is no topology data specified in
> DT for affected Exynos SoCs. The need for it showed up just recently, so
> I'm not sure this is a regression to fix in older kernels.

In my "the kernel and the dtb aren't tied together" quest, these are the
kinds of things I like to see fixed in stable kernels.

If a user needs to update a dtb, say to fix a bug, it's reasonable to
use the newest one for a given board.  After all, any new nodes won't
change anything, since the driver in the kernel won't match the node.

However, in this case, without this fix, a user upgrading to the newest
dtb would get a broken system.  So, this fix should be backported to
prevent the breakage.  Or, have I missed something in my analysis?

thx,

Jason.

^ permalink raw reply

* [PATCH v11 11/11] seccomp: implement SECCOMP_FILTER_FLAG_TSYNC
From: Kees Cook @ 2014-07-17 15:45 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAHse=S_32tmusk4ceY4U6GbNpX4PkX12iPPDZFVZ7qgv-RAooA@mail.gmail.com>

On Thu, Jul 17, 2014 at 8:04 AM, David Drysdale <drysdale@google.com> wrote:
> On Wed, Jul 16, 2014 at 10:50 PM, Kees Cook <keescook@chromium.org> wrote:
>> diff --git a/kernel/seccomp.c b/kernel/seccomp.c
>> index 9065d2c79c56..2125b83ccfd4 100644
>> +/**
>> + * seccomp_can_sync_threads: checks if all threads can be synchronized
>> + *
>> + * Expects sighand and cred_guard_mutex locks to be held.
>> + *
>> + * Returns 0 on success, -ve on error, or the pid of a thread which was
>> + * either not in the correct seccomp mode or it did not have an ancestral
>> + * seccomp filter.
>> + */
>> +static inline pid_t seccomp_can_sync_threads(void)
>> +{
>> +       struct task_struct *thread, *caller;
>> +
>> +       BUG_ON(!mutex_is_locked(&current->signal->cred_guard_mutex));
>> +       BUG_ON(!spin_is_locked(&current->sighand->siglock));
>> +
>> +       if (current->seccomp.mode != SECCOMP_MODE_FILTER)
>> +               return -EACCES;
>
> Quick question -- is it possible to apply the first filter and also synchronize
> it across threads in the same operation?  If so, does this arm also need to
> cope with seccomp.mode being SECCOMP_MODE_DISABLED?
>
> [seccomp_set_mode_filter() looks to call this via seccomp_attach_filter()
> before it does seccomp_assign_mode()]

I don't entirely understand what you're asking. The threads gain the
filter and the mode before the current thread may gain the mode (if
it's the first time this has been called). Due to all the locks,
though, this isn't a problem. Is there a situation you see where there
might be a problem?

-Kees

-- 
Kees Cook
Chrome OS Security

^ permalink raw reply

* [PATCH 4/5] tty: serial: 8250 core: add runtime pm
From: Sebastian Andrzej Siewior @ 2014-07-17 15:43 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <53C7EC6F.6060902@hurleysoftware.com>

* Peter Hurley | 2014-07-17 11:31:59 [-0400]:

>On 07/16/2014 12:06 PM, Felipe Balbi wrote:
>>On Wed, Jul 16, 2014 at 05:54:56PM +0200, Sebastian Andrzej Siewior wrote:
>>>On 07/16/2014 05:16 PM, Felipe Balbi wrote:
>
>>>>I wonder if you should get_sync() on start_tx() and only
>>>>put_autosuspend() at stop_tx(). I guess the outcome would be
>>>>largely the same, no ?
>>>
>>>I just opened minicom on ttyS0 and gave a try. start_tx() was invoked
>>>each time I pressed a key (sent a character). I haven't seen stop_tx()
>>>even after after I closed minicom. I guess stop_tx() is invoked if you
>>>switch half-duplex communication.
>>
>>that's bad, I expected stop to be called also after each character.
>
>The 8250 core auto-stops tx when the tx ring buffer is empty (except
>in the case of dma, where stopping tx isn't necessary).

This is correct. So this is what I have now for the non-dma case:

diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c
index 2e4a93b..480a1c0 100644
--- a/drivers/tty/serial/8250/8250_core.c
+++ b/drivers/tty/serial/8250/8250_core.c
@@ -1283,6 +1283,9 @@ static inline void __stop_tx(struct uart_8250_port *p)
 	if (p->ier & UART_IER_THRI) {
 		p->ier &= ~UART_IER_THRI;
 		serial_out(p, UART_IER, p->ier);
+
+		pm_runtime_mark_last_busy(p->port.dev);
+		pm_runtime_put_autosuspend(p->port.dev);
 	}
 }
 
@@ -1310,12 +1313,12 @@ static void serial8250_start_tx(struct uart_port *port)
 	struct uart_8250_port *up =
 		container_of(port, struct uart_8250_port, port);
 
-	pm_runtime_get_sync(port->dev);
 	if (up->dma && !serial8250_tx_dma(up)) {
 		goto out;
 	} else if (!(up->ier & UART_IER_THRI)) {
 		up->ier |= UART_IER_THRI;
+		pm_runtime_get_sync(port->dev);
 		serial_port_out(port, UART_IER, up->ier);
 
 		if (up->bugs & UART_BUG_TXEN) {
 			unsigned char lsr;
@@ -1500,9 +1503,10 @@ void serial8250_tx_chars(struct uart_8250_port *up)
 		uart_write_wakeup(port);
 
 	DEBUG_INTR("THRE...");
-
+#if 0
 	if (uart_circ_empty(xmit))
 		__stop_tx(up);
+#endif
 }
 EXPORT_SYMBOL_GPL(serial8250_tx_chars);
 

and now I need to come up with something that is not if (port != omap)
for that #if 0 block. The code disables the TX FIFO empty interrupt once
the transfer is complete. I want to call __stop_tx() once the tx fifo is
empty.
Felipe, Would a check for dev->power.use_autosuspend be the right thing
to do?

>Regards,
>Peter Hurley

Sebastian

^ 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