Re: Enabling DBGEN signal in GP OMAP3

2015-02-23 Thread Matthijs van Duin
At least on the am335x, the trick actually works!  I have a working
demo which configures ICEPick registers and even performs transactions
on the debug interconnect.

I've been lazy and imported a bunch of files from my baremetal
projects so I could easily mess with the hardware, rudely bypassing
the kernel.  The whole implementation is hideous in all sorts of ways,
but it gets the job done: https://github.com/dutchanddutch/jbang

The key part, how to bitbang JTAG, is reasonably isolated from all
this in src/jbang.cc and glues onto the device-specific part via
hw-subarctic.h.  You could probably also turn jbang.cc into plain C
without too much effort and discard the rest... I accept that my code
style is probably a bit of an acquired taste ;-)

For the omap3, apart from the differences in padconf details, you'll
want to change icepick_init_regs[] to just { 0x23002100 } I think and
hopefully you can then write the DAPCTL regs using ap_write().

I hope this example is of any help.

Matthijs
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 0/2] ARM: omap2plus_defconfig: Fix SATA and NAND for v4.0-rc

2015-02-23 Thread Roger Quadros
Hi,

These changes fix SATA boot and NAND for OMAP based boards.

I must also point out that basic SATA operation is also
broken when TI_PIPE3 driver is built as a module.
I will be investigating that on lower priority.

--
cheers,
-roger

Roger Quadros (2):
  ARM: omap2plus_defconfig: Enable OMAP NAND BCH driver
  ARM: omap2plus_defconfig: Fix SATA boot

 arch/arm/configs/omap2plus_defconfig | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

-- 
2.1.0

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/2] ARM: omap2plus_defconfig: Enable OMAP NAND BCH driver

2015-02-23 Thread Roger Quadros
Without this NAND doesn't work on most EVMs.

Signed-off-by: Roger Quadros rog...@ti.com
---
 arch/arm/configs/omap2plus_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/configs/omap2plus_defconfig 
b/arch/arm/configs/omap2plus_defconfig
index b738652..b674245 100644
--- a/arch/arm/configs/omap2plus_defconfig
+++ b/arch/arm/configs/omap2plus_defconfig
@@ -114,6 +114,7 @@ CONFIG_MTD_PHYSMAP_OF=y
 CONFIG_MTD_NAND=y
 CONFIG_MTD_NAND_ECC_BCH=y
 CONFIG_MTD_NAND_OMAP2=y
+CONFIG_MTD_NAND_OMAP_BCH=y
 CONFIG_MTD_ONENAND=y
 CONFIG_MTD_ONENAND_VERIFY_WRITE=y
 CONFIG_MTD_ONENAND_OMAP2=y
-- 
2.1.0

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/2] ARM: omap2plus_defconfig: Fix SATA boot

2015-02-23 Thread Roger Quadros
SATA operation depends on PIPE3 PHY and if we want
to boot from SATA drives, we have to have the PIPE3 PHY
driver built-in.

Signed-off-by: Roger Quadros rog...@ti.com
---
 arch/arm/configs/omap2plus_defconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/configs/omap2plus_defconfig 
b/arch/arm/configs/omap2plus_defconfig
index b674245..088096f 100644
--- a/arch/arm/configs/omap2plus_defconfig
+++ b/arch/arm/configs/omap2plus_defconfig
@@ -375,7 +375,7 @@ CONFIG_PWM_TIEHRPWM=m
 CONFIG_PWM_TWL=m
 CONFIG_PWM_TWL_LED=m
 CONFIG_OMAP_USB2=m
-CONFIG_TI_PIPE3=m
+CONFIG_TI_PIPE3=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT3_FS=y
 # CONFIG_EXT3_FS_XATTR is not set
-- 
2.1.0

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v5 6/7] DT: omap4/5: add binding for the wake-up generator

2015-02-23 Thread Marc Zyngier
Signed-off-by: Marc Zyngier marc.zyng...@arm.com
---
 .../interrupt-controller/ti,omap4-wugen-mpu| 33 ++
 1 file changed, 33 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/interrupt-controller/ti,omap4-wugen-mpu

diff --git 
a/Documentation/devicetree/bindings/interrupt-controller/ti,omap4-wugen-mpu 
b/Documentation/devicetree/bindings/interrupt-controller/ti,omap4-wugen-mpu
new file mode 100644
index 000..43effa0
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/ti,omap4-wugen-mpu
@@ -0,0 +1,33 @@
+TI OMAP4 Wake-up Generator
+
+All TI OMAP4/5 (and their derivatives) an interrupt controller that
+routes interrupts to the GIC, and also serves as a wakeup source. It
+is also referred to as WUGEN-MPU, hence the name of the binding.
+
+Reguired properties:
+
+- compatible : should contain at least ti,omap4-wugen-mpu or
+  ti,omap5-wugen-mpu
+- reg : Specifies base physical address and size of the registers.
+- interrupt-controller : Identifies the node as an interrupt controller.
+- #interrupt-cells : Specifies the number of cells needed to encode an
+  interrupt source. The value must be 3.
+- interrupt-parent : a phandle to the GIC these interrupts are routed
+  to.
+
+Notes:
+
+- Because this HW ultimately routes interrupts to the GIC, the
+  interrupt specifier must be that of the GIC.
+- Only SPIs can use the WUGEN as an interrupt parent. SGIs and PPIs
+  are explicitly forbiden.
+
+Example:
+
+   wakeupgen: interrupt-controller@48281000 {
+   compatible = ti,omap5-wugen-mpu, ti,omap4-wugen-mpu;
+   interrupt-controller;
+   #interrupt-cells = 3;
+   reg = 0x48281000 0x1000;
+   interrupt-parent = gic;
+   };
-- 
2.1.4

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v5 3/7] DT: update ti,irq-crossbar binding

2015-02-23 Thread Marc Zyngier
Make it look like a real interrupt controller.

Signed-off-by: Marc Zyngier marc.zyng...@arm.com
---
 .../devicetree/bindings/arm/omap/crossbar.txt  | 18 +-
 1 file changed, 5 insertions(+), 13 deletions(-)

diff --git a/Documentation/devicetree/bindings/arm/omap/crossbar.txt 
b/Documentation/devicetree/bindings/arm/omap/crossbar.txt
index 4139db3..a9b28d7 100644
--- a/Documentation/devicetree/bindings/arm/omap/crossbar.txt
+++ b/Documentation/devicetree/bindings/arm/omap/crossbar.txt
@@ -9,7 +9,9 @@ inputs.
 Required properties:
 - compatible : Should be ti,irq-crossbar
 - reg: Base address and the size of the crossbar registers.
-- ti,max-irqs: Total number of irqs available at the interrupt controller.
+- interrupt-controller: indicates that this block is an interrupt controller.
+- interrupt-parent: the interrupt controller this block is connected to.
+- ti,max-irqs: Total number of irqs available at the parent interrupt 
controller.
 - ti,max-crossbar-sources: Maximum number of crossbar sources that can be 
routed.
 - ti,reg-size: Size of a individual register in bytes. Every individual
register is assumed to be of same size. Valid sizes are 1, 2, 4.
@@ -27,13 +29,13 @@ Optional properties:
   when the interrupt controller irq is unused (when not provided, default is 0)
 
 Examples:
-   crossbar_mpu: @4a02 {
+   crossbar_mpu: crossbar@4a002a48 {
compatible = ti,irq-crossbar;
reg = 0x4a002a48 0x130;
ti,max-irqs = 160;
ti,max-crossbar-sources = 400;
ti,reg-size = 2;
-   ti,irqs-reserved = 0 1 2 3 5 6 131 132 139 140;
+   ti,irqs-reserved = 0 1 2 3 5 6 131 132;
ti,irqs-skip = 10 133 139 140;
};
 
@@ -44,10 +46,6 @@ Documentation/devicetree/bindings/arm/gic.txt for further 
details.
 
 An interrupt consumer on an SoC using crossbar will use:
interrupts = GIC_SPI request_number interrupt_level
-When the request number is between 0 to that described by
-ti,max-crossbar-sources, it is assumed to be a crossbar mapping. If the
-request_number is greater than ti,max-crossbar-sources, then it is mapped as 
a
-quirky hardware mapping direct to GIC.
 
 Example:
device_x@0x4a023000 {
@@ -55,9 +53,3 @@ Example:
interrupts = GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH;
...
};
-
-   device_y@0x4a033000 {
-   /* Direct mapped GIC SPI 1 used */
-   interrupts = GIC_SPI DIRECT_IRQ(1) IRQ_TYPE_LEVEL_HIGH;
-   ...
-   };
-- 
2.1.4

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v5 7/7] ARM: omap: convert wakeupgen to stacked domains

2015-02-23 Thread Marc Zyngier
OMAP4/5 has been (ab)using the gic_arch_extn to provide
wakeup from suspend, and it makes a lot of sense to convert
this code to use stacked domains instead.

This patch does just this, updating the DT files to actually
reflect what the HW provides.

BIG FAT WARNING: because the DTs were so far lying by not
exposing the WUGEN HW block, kernels with this patch applied
won't have any suspend-resume facility when booted with old DTs,
and old kernels with updated DTs won't even boot.

On a platform with this patch applied, the system looks like
this:

root@bacon-fat:~# cat /proc/interrupts
CPU0   CPU1
 16:  0  0 WUGEN  37  gp_timer
 19: 233799 155916   GIC  27  arch_timer
 23:  0  0 WUGEN   9  l3-dbg-irq
 24:  1  0 WUGEN  10  l3-app-irq
 27:282  0 WUGEN  13  omap-dma-engine
 44:  0  0  4ae1.gpio  13  DMA
294:  0  0 WUGEN  20  gpmc
297:506  0 WUGEN  56  4807.i2c
298:  0  0 WUGEN  57  48072000.i2c
299:  0  0 WUGEN  61  4806.i2c
300:  0  0 WUGEN  62  4807a000.i2c
301:  8  0 WUGEN  60  4807c000.i2c
308:   2439  0 WUGEN  74  OMAP UART2
312:362  0 WUGEN  83  mmc2
313:502  0 WUGEN  86  mmc0
314: 13  0 WUGEN  94  mmc1
350:  0  0  PRCM  pinctrl, pinctrl
406:   35155709  0   GIC 109  ehci_hcd:usb1
407:  0  0 WUGEN   7  palmas
409:  0  0 WUGEN 119  twl6040
410:  0  0   twl6040   5  twl6040_irq_ready
411:  0  0   twl6040   0  twl6040_irq_th
IPI0:  0  1  CPU wakeup interrupts
IPI1:  0  0  Timer broadcast interrupts
IPI2:  95334 902334  Rescheduling interrupts
IPI3:  0  0  Function call interrupts
IPI4:479648  Single function call interrupts
IPI5:  0  0  CPU stop interrupts
IPI6:  0  0  IRQ work interrupts
IPI7:  0  0  completion interrupts
Err:  0

Signed-off-by: Marc Zyngier marc.zyng...@arm.com
---
 arch/arm/boot/dts/am4372.dtsi |  11 ++-
 arch/arm/boot/dts/am437x-gp-evm.dts   |   1 -
 arch/arm/boot/dts/am437x-sk-evm.dts   |   1 -
 arch/arm/boot/dts/am43x-epos-evm.dts  |   1 -
 arch/arm/boot/dts/dra7.dtsi   |  12 ++-
 arch/arm/boot/dts/dra72x.dtsi |   2 +-
 arch/arm/boot/dts/dra74x.dtsi |   2 +-
 arch/arm/boot/dts/omap4-duovero.dtsi  |   2 -
 arch/arm/boot/dts/omap4-panda-common.dtsi |   8 +-
 arch/arm/boot/dts/omap4-sdp.dts   |   8 +-
 arch/arm/boot/dts/omap4-var-som-om44.dtsi |   2 -
 arch/arm/boot/dts/omap4.dtsi  |  18 -
 arch/arm/boot/dts/omap5-cm-t54.dts|   1 -
 arch/arm/boot/dts/omap5-uevm.dts  |   2 -
 arch/arm/boot/dts/omap5.dtsi  |  26 ---
 arch/arm/mach-omap2/omap-wakeupgen.c  | 125 +++---
 arch/arm/mach-omap2/omap-wakeupgen.h  |   1 -
 arch/arm/mach-omap2/omap4-common.c|  17 ++--
 18 files changed, 162 insertions(+), 78 deletions(-)

diff --git a/arch/arm/boot/dts/am4372.dtsi b/arch/arm/boot/dts/am4372.dtsi
index 1943fc3..8a099bc 100644
--- a/arch/arm/boot/dts/am4372.dtsi
+++ b/arch/arm/boot/dts/am4372.dtsi
@@ -15,7 +15,7 @@
 
 / {
compatible = ti,am4372, ti,am43;
-   interrupt-parent = gic;
+   interrupt-parent = wakeupgen;
 
 
aliases {
@@ -48,6 +48,15 @@
#interrupt-cells = 3;
reg = 0x48241000 0x1000,
  0x48240100 0x0100;
+   interrupt-parent = gic;
+   };
+
+   wakeupgen: interrupt-controller@48281000 {
+   compatible = ti,omap4-wugen-mpu;
+   interrupt-controller;
+   #interrupt-cells = 3;
+   reg = 0x48281000 0x1000;
+   interrupt-parent = gic;
};
 
l2-cache-controller@48242000 {
diff --git a/arch/arm/boot/dts/am437x-gp-evm.dts 
b/arch/arm/boot/dts/am437x-gp-evm.dts
index f84d971..26956cb 100644
--- a/arch/arm/boot/dts/am437x-gp-evm.dts
+++ b/arch/arm/boot/dts/am437x-gp-evm.dts
@@ -352,7 +352,6 @@
reg = 0x24;
compatible = ti,tps65218;
interrupts = GIC_SPI 7 IRQ_TYPE_NONE; /* NMIn */
-   interrupt-parent = gic;
interrupt-controller;
#interrupt-cells = 2;
 
diff --git a/arch/arm/boot/dts/am437x-sk-evm.dts 
b/arch/arm/boot/dts/am437x-sk-evm.dts
index 832d243..8ae29c9 100644
--- a/arch/arm/boot/dts/am437x-sk-evm.dts
+++ b/arch/arm/boot/dts/am437x-sk-evm.dts
@@ -392,7 +392,6 @@
tps@24 {
compatible = ti,tps65218;
reg = 0x24;
-   interrupt-parent = gic;
interrupts = GIC_SPI 7 

[PATCH v5 0/7] irqchip: Move OMAP{4,5}/DRA7 to use stacked domains

2015-02-23 Thread Marc Zyngier
This series is extracted from [4], which is trying to remove all
traces of gic_arch_extn from the tree. As some maintainers are more
responsive than others (understatement of the year...), I've decided
to split it per sub-arch, and get it moving, at least partially.

This series addresses OMAP{4,5} by converting the WUGEN to stacked
domains. The DRA7 crossbar gets the same treatment.

It is worth realizing that:

- I haven't been able to test this as much as I would have wanted to
  (it's only been tested on omap4 and omap5).

- This actively *breaks* existing setups. Once you boot a new kernel
  with an old DT, suspend/resume *will* be broken. Old kernels on a
  new DT won't even boot! You've been warned. This really outline the
  necessity of actually describing the HW in device trees...

Based on 4.0-rc1.

* From v4: [4]
- Extracted from the full series
- Rebased on 4.0-rc1

* From v3 [3]:
- Rebased on top of the patch working around hardcoded IRQ on OMAP4/5 [4]
- Fixed more iMX6 DTs (Stephan)
- Fixed Exynos4/5 DTs

* From v2 [2]:
- Addressed numerous comments from Thierry
- Merged bug fixes from Nishanth
- Merged bug fix from Stefan

* From v1 [1]:
- Rebased on 3.19-rc3
- Fixed a number of additional platforms
- Added crossbar conversion to stacked domains
- Merged bug fixes from Nishanth

[4]: 
http://lists.infradead.org/pipermail/linux-arm-kernel/2015-January/317531.html
[3]: 
http://lists.infradead.org/pipermail/linux-arm-kernel/2015-January/315385.html
[2]: 
http://lists.infradead.org/pipermail/linux-arm-kernel/2015-January/314041.html
[1]: 
http://lists.infradead.org/pipermail/linux-arm-kernel/2014-November/307338.html

Marc Zyngier (7):
  genirq: Add irqchip_set_wake_parent
  irqchip: crossbar: convert dra7 crossbar to stacked domains
  DT: update ti,irq-crossbar binding
  irqchip: GIC: get rid of routable domain
  DT: arm,gic: kill arm,routable-irqs
  DT: omap4/5: add binding for the wake-up generator
  ARM: omap: convert wakeupgen to stacked domains

 Documentation/devicetree/bindings/arm/gic.txt  |   6 -
 .../devicetree/bindings/arm/omap/crossbar.txt  |  18 +-
 .../interrupt-controller/ti,omap4-wugen-mpu|  33 
 arch/arm/boot/dts/am4372.dtsi  |  11 +-
 arch/arm/boot/dts/am437x-gp-evm.dts|   1 -
 arch/arm/boot/dts/am437x-sk-evm.dts|   1 -
 arch/arm/boot/dts/am43x-epos-evm.dts   |   1 -
 arch/arm/boot/dts/am57xx-beagle-x15.dts|   3 +-
 arch/arm/boot/dts/dra7-evm.dts |   2 +-
 arch/arm/boot/dts/dra7.dtsi|  43 +++--
 arch/arm/boot/dts/dra72-evm.dts|   1 -
 arch/arm/boot/dts/dra72x.dtsi  |   3 +-
 arch/arm/boot/dts/dra74x.dtsi  |   5 +-
 arch/arm/boot/dts/omap4-duovero.dtsi   |   2 -
 arch/arm/boot/dts/omap4-panda-common.dtsi  |   8 +-
 arch/arm/boot/dts/omap4-sdp.dts|   8 +-
 arch/arm/boot/dts/omap4-var-som-om44.dtsi  |   2 -
 arch/arm/boot/dts/omap4.dtsi   |  18 +-
 arch/arm/boot/dts/omap5-cm-t54.dts |   1 -
 arch/arm/boot/dts/omap5-uevm.dts   |   2 -
 arch/arm/boot/dts/omap5.dtsi   |  26 ++-
 arch/arm/mach-omap2/omap-wakeupgen.c   | 125 ++---
 arch/arm/mach-omap2/omap-wakeupgen.h   |   1 -
 arch/arm/mach-omap2/omap4-common.c |  21 +--
 drivers/irqchip/irq-crossbar.c | 207 -
 drivers/irqchip/irq-gic.c  |  59 +-
 include/linux/irq.h|   1 +
 include/linux/irqchip/arm-gic.h|   6 -
 include/linux/irqchip/irq-crossbar.h   |  11 --
 kernel/irq/chip.c  |  16 ++
 30 files changed, 364 insertions(+), 278 deletions(-)
 create mode 100644 
Documentation/devicetree/bindings/interrupt-controller/ti,omap4-wugen-mpu
 delete mode 100644 include/linux/irqchip/irq-crossbar.h

-- 
2.1.4

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v5 2/7] irqchip: crossbar: convert dra7 crossbar to stacked domains

2015-02-23 Thread Marc Zyngier
Support for the TI crossbar used on the DRA7 family of chips
is implemented as an ugly hack on the side of the GIC.

Converting it to stacked domains makes it slightly more
palatable, as it results in a cleanup.

Unfortunately, as the DT bindings failed to acknowledge the
fact that this is actually yet another interrupt controller
(the third, actually), we have yet another breakage. Oh well.

Signed-off-by: Marc Zyngier marc.zyng...@arm.com
---
 arch/arm/boot/dts/am57xx-beagle-x15.dts |   3 +-
 arch/arm/boot/dts/dra7-evm.dts  |   2 +-
 arch/arm/boot/dts/dra7.dtsi |  35 +++---
 arch/arm/boot/dts/dra72-evm.dts |   1 -
 arch/arm/boot/dts/dra72x.dtsi   |   3 +-
 arch/arm/boot/dts/dra74x.dtsi   |   5 +-
 arch/arm/mach-omap2/omap4-common.c  |   4 -
 drivers/irqchip/irq-crossbar.c  | 207 ++--
 include/linux/irqchip/irq-crossbar.h|  11 --
 9 files changed, 146 insertions(+), 125 deletions(-)
 delete mode 100644 include/linux/irqchip/irq-crossbar.h

diff --git a/arch/arm/boot/dts/am57xx-beagle-x15.dts 
b/arch/arm/boot/dts/am57xx-beagle-x15.dts
index 03750af..170fbf9 100644
--- a/arch/arm/boot/dts/am57xx-beagle-x15.dts
+++ b/arch/arm/boot/dts/am57xx-beagle-x15.dts
@@ -454,7 +454,6 @@
mcp_rtc: rtc@6f {
compatible = microchip,mcp7941x;
reg = 0x6f;
-   interrupt-parent = gic;
interrupts = GIC_SPI 2 IRQ_TYPE_LEVEL_LOW;  /* IRQ_SYS_1N */
 
pinctrl-names = default;
@@ -477,7 +476,7 @@
 
 uart3 {
status = okay;
-   interrupts-extended = gic GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH,
+   interrupts-extended = crossbar_mpu GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH,
  dra7_pmx_core 0x248;
 
pinctrl-names = default;
diff --git a/arch/arm/boot/dts/dra7-evm.dts b/arch/arm/boot/dts/dra7-evm.dts
index 746cddb..789ee58 100644
--- a/arch/arm/boot/dts/dra7-evm.dts
+++ b/arch/arm/boot/dts/dra7-evm.dts
@@ -446,7 +446,7 @@
status = okay;
pinctrl-names = default;
pinctrl-0 = uart1_pins;
-   interrupts-extended = gic GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH,
+   interrupts-extended = crossbar_mpu GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH,
  dra7_pmx_core 0x3e0;
 };
 
diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi
index 5827fed..850f949 100644
--- a/arch/arm/boot/dts/dra7.dtsi
+++ b/arch/arm/boot/dts/dra7.dtsi
@@ -13,14 +13,13 @@
 #include skeleton.dtsi
 
 #define MAX_SOURCES 400
-#define DIRECT_IRQ(irq) (MAX_SOURCES + irq)
 
 / {
#address-cells = 1;
#size-cells = 1;
 
compatible = ti,dra7xx;
-   interrupt-parent = gic;
+   interrupt-parent = crossbar_mpu;
 
aliases {
i2c0 = i2c1;
@@ -50,18 +49,19 @@
 GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | 
IRQ_TYPE_LEVEL_LOW),
 GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | 
IRQ_TYPE_LEVEL_LOW),
 GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | 
IRQ_TYPE_LEVEL_LOW);
+   interrupt-parent = gic;
};
 
gic: interrupt-controller@48211000 {
compatible = arm,cortex-a15-gic;
interrupt-controller;
#interrupt-cells = 3;
-   arm,routable-irqs = 192;
reg = 0x48211000 0x1000,
  0x48212000 0x1000,
  0x48214000 0x2000,
  0x48216000 0x2000;
interrupts = GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(2) | 
IRQ_TYPE_LEVEL_HIGH);
+   interrupt-parent = gic;
};
 
/*
@@ -91,8 +91,8 @@
ti,hwmods = l3_main_1, l3_main_2;
reg = 0x4400 0x100,
  0x4500 0x1000;
-   interrupts = GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH,
-GIC_SPI DIRECT_IRQ(10) IRQ_TYPE_LEVEL_HIGH;
+   interrupts-extended = crossbar_mpu GIC_SPI 4 
IRQ_TYPE_LEVEL_HIGH,
+ gic GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH;
 
prm: prm@4ae06000 {
compatible = ti,dra7-prm;
@@ -344,7 +344,7 @@
uart1: serial@4806a000 {
compatible = ti,omap4-uart;
reg = 0x4806a000 0x100;
-   interrupts-extended = gic GIC_SPI 67 
IRQ_TYPE_LEVEL_HIGH;
+   interrupts-extended = crossbar_mpu GIC_SPI 67 
IRQ_TYPE_LEVEL_HIGH;
ti,hwmods = uart1;
clock-frequency = 4800;
status = disabled;
@@ -355,7 +355,7 @@
uart2: serial@4806c000 {
compatible = ti,omap4-uart;
reg = 0x4806c000 0x100;
-   interrupts-extended = gic GIC_SPI 68 
IRQ_TYPE_LEVEL_HIGH;
+   interrupts = GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH;

[PATCH v5 5/7] DT: arm,gic: kill arm,routable-irqs

2015-02-23 Thread Marc Zyngier
Nobody will regret it.

Signed-off-by: Marc Zyngier marc.zyng...@arm.com
---
 Documentation/devicetree/bindings/arm/gic.txt | 6 --
 1 file changed, 6 deletions(-)

diff --git a/Documentation/devicetree/bindings/arm/gic.txt 
b/Documentation/devicetree/bindings/arm/gic.txt
index c97484b..1e0d212 100644
--- a/Documentation/devicetree/bindings/arm/gic.txt
+++ b/Documentation/devicetree/bindings/arm/gic.txt
@@ -56,11 +56,6 @@ Optional
   regions, used when the GIC doesn't have banked registers. The offset is
   cpu-offset * cpu-nr.
 
-- arm,routable-irqs : Total number of gic irq inputs which are not directly
- connected from the peripherals, but are routed dynamically
- by a crossbar/multiplexer preceding the GIC. The GIC irq
- input line is assigned dynamically when the corresponding
- peripheral's crossbar line is mapped.
 Example:
 
intc: interrupt-controller@fff11000 {
@@ -68,7 +63,6 @@ Example:
#interrupt-cells = 3;
#address-cells = 1;
interrupt-controller;
-   arm,routable-irqs = 160;
reg = 0xfff11000 0x1000,
  0xfff10100 0x100;
};
-- 
2.1.4

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v5 4/7] irqchip: GIC: get rid of routable domain

2015-02-23 Thread Marc Zyngier
The only user of the so called routable domain functionality
now being fixed, let's clean up the GIC.

Signed-off-by: Marc Zyngier marc.zyng...@arm.com
---
 drivers/irqchip/irq-gic.c   | 59 -
 include/linux/irqchip/arm-gic.h |  6 -
 2 files changed, 5 insertions(+), 60 deletions(-)

diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index 4634cf7..e3ca6da 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -798,15 +798,12 @@ static int gic_irq_domain_map(struct irq_domain *d, 
unsigned int irq,
irq_domain_set_info(d, irq, hw, gic_chip, d-host_data,
handle_fasteoi_irq, NULL, NULL);
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
-
-   gic_routable_irq_domain_ops-map(d, irq, hw);
}
return 0;
 }
 
 static void gic_irq_domain_unmap(struct irq_domain *d, unsigned int irq)
 {
-   gic_routable_irq_domain_ops-unmap(d, irq);
 }
 
 static int gic_irq_domain_xlate(struct irq_domain *d,
@@ -825,16 +822,8 @@ static int gic_irq_domain_xlate(struct irq_domain *d,
*out_hwirq = intspec[1] + 16;
 
/* For SPIs, we need to add 16 more to get the GIC irq ID number */
-   if (!intspec[0]) {
-   ret = gic_routable_irq_domain_ops-xlate(d, controller,
-intspec,
-intsize,
-out_hwirq,
-out_type);
-
-   if (IS_ERR_VALUE(ret))
-   return ret;
-   }
+   if (!intspec[0])
+   *out_hwirq += 16;
 
*out_type = intspec[2]  IRQ_TYPE_SENSE_MASK;
 
@@ -891,37 +880,6 @@ static const struct irq_domain_ops gic_irq_domain_ops = {
.xlate = gic_irq_domain_xlate,
 };
 
-/* Default functions for routable irq domain */
-static int gic_routable_irq_domain_map(struct irq_domain *d, unsigned int irq,
- irq_hw_number_t hw)
-{
-   return 0;
-}
-
-static void gic_routable_irq_domain_unmap(struct irq_domain *d,
- unsigned int irq)
-{
-}
-
-static int gic_routable_irq_domain_xlate(struct irq_domain *d,
-   struct device_node *controller,
-   const u32 *intspec, unsigned int intsize,
-   unsigned long *out_hwirq,
-   unsigned int *out_type)
-{
-   *out_hwirq += 16;
-   return 0;
-}
-
-static const struct irq_domain_ops gic_default_routable_irq_domain_ops = {
-   .map = gic_routable_irq_domain_map,
-   .unmap = gic_routable_irq_domain_unmap,
-   .xlate = gic_routable_irq_domain_xlate,
-};
-
-const struct irq_domain_ops *gic_routable_irq_domain_ops =
-   gic_default_routable_irq_domain_ops;
-
 void __init gic_init_bases(unsigned int gic_nr, int irq_start,
   void __iomem *dist_base, void __iomem *cpu_base,
   u32 percpu_offset, struct device_node *node)
@@ -929,7 +887,6 @@ void __init gic_init_bases(unsigned int gic_nr, int 
irq_start,
irq_hw_number_t hwirq_base;
struct gic_chip_data *gic;
int gic_irqs, irq_base, i;
-   int nr_routable_irqs;
 
BUG_ON(gic_nr = MAX_GIC_NR);
 
@@ -985,15 +942,9 @@ void __init gic_init_bases(unsigned int gic_nr, int 
irq_start,
gic-gic_irqs = gic_irqs;
 
if (node) { /* DT case */
-   const struct irq_domain_ops *ops = 
gic_irq_domain_hierarchy_ops;
-
-   if (!of_property_read_u32(node, arm,routable-irqs,
- nr_routable_irqs)) {
-   ops = gic_irq_domain_ops;
-   gic_irqs = nr_routable_irqs;
-   }
-
-   gic-domain = irq_domain_add_linear(node, gic_irqs, ops, gic);
+   gic-domain = irq_domain_add_linear(node, gic_irqs,
+   
gic_irq_domain_hierarchy_ops,
+   gic);
} else {/* Non-DT case */
/*
 * For primary GICs, skip over SGIs.
diff --git a/include/linux/irqchip/arm-gic.h b/include/linux/irqchip/arm-gic.h
index 71d706d..3978c5b 100644
--- a/include/linux/irqchip/arm-gic.h
+++ b/include/linux/irqchip/arm-gic.h
@@ -115,11 +115,5 @@ int gic_get_cpu_id(unsigned int cpu);
 void gic_migrate_target(unsigned int new_cpu_id);
 unsigned long gic_get_sgir_physaddr(void);
 
-extern const struct irq_domain_ops *gic_routable_irq_domain_ops;
-static inline void __init register_routable_domain_ops
-   (const struct irq_domain_ops *ops)
-{
-   gic_routable_irq_domain_ops = ops;
-}
 

[PATCH v5 1/7] genirq: Add irqchip_set_wake_parent

2015-02-23 Thread Marc Zyngier
This proves to be useful with stacked domains, when the current
domain doesn't implement wake-up, but expect the parent to do so.

Signed-off-by: Marc Zyngier marc.zyng...@arm.com
---
 include/linux/irq.h |  1 +
 kernel/irq/chip.c   | 16 
 2 files changed, 17 insertions(+)

diff --git a/include/linux/irq.h b/include/linux/irq.h
index d09ec7a..3057c48 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -460,6 +460,7 @@ extern void irq_chip_eoi_parent(struct irq_data *data);
 extern int irq_chip_set_affinity_parent(struct irq_data *data,
const struct cpumask *dest,
bool force);
+extern int irq_chip_set_wake_parent(struct irq_data *data, unsigned int on);
 #endif
 
 /* Handling of unhandled and spurious interrupts: */
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 6f1c7a5..eb9a4ea 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -948,6 +948,22 @@ int irq_chip_retrigger_hierarchy(struct irq_data *data)
 
return -ENOSYS;
 }
+
+/**
+ * irq_chip_set_wake_parent - Set/reset wake-up on the parent interrupt
+ * @data:  Pointer to interrupt specific data
+ * @on:Whether to set or reset the wake-up capability of this 
irq
+ *
+ * Conditional, as the underlying parent chip might not implement it.
+ */
+int irq_chip_set_wake_parent(struct irq_data *data, unsigned int on)
+{
+   data = data-parent_data;
+   if (data-chip-irq_set_wake)
+   return data-chip-irq_set_wake(data, on);
+
+   return -ENOSYS;
+}
 #endif
 
 /**
-- 
2.1.4

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/4] ARM OMAP2+ GPMC: always program GPMCFCLKDIVIDER

2015-02-23 Thread Robert Abel
On Tue, Feb 17, 2015 at 3:25 PM, Roger Quadros rog...@ti.com wrote:
 one more thing to note is that just specifying sync-clk-ps in DT is not 
 enough for
 asynchronous devices.

 The driver doesn't set gpmc_t-sync_clk if gpmc,sync-read or 
 gpmc,sync-write
 was not set in the DT, which would be the case for asynchronous devices.

You're mistaken. It's always parsed, no matter what. See [1]. But I
did implement your suggestion of computing the divider in the mean
time. I'm going to send the patches rebased to 3.19 tomorrow, after I
tested them.

 What is your proposal to make things better? And what is your use case that 
 doesn't
 work with existing setup?

Well, the current setup was obviously inspired by an asynchronous-only
use-case, where all the timings are in seconds and get converted
on-the-fly. Of course, currently, there is no support to re-compute
them once the gpmc_fclk changes frequency, but I guess that's what the
TODO about the clock framework is about?

Anyway, my synchronous use-case is inherently... synchronous.
Synchronous protocols shouldn't be specified in ns at all. They should
directly be specified in clock ticks. This is also advantageous, as
changes in gpmc_fclk don't need to propagate to the registers.

My main grief with the current setup is its dependency on the
*unknown* gpmc_fclk period at startup when the DT is processed and
GPMC code is called. For instance, my private DT currently operates on
the assumption of 166 Mhz L3 clk (and therefore gpmc_fclk), so all my
timings are in multiples of 6 ns. Should now a colleague of mine think
it would be a splendid idea to change this frequency by means of
bootloader options [to save power, to process data even faster, etc],
everything would break, because the L3 might have to be clocked at 100
MHz (due to divider limits along the clock tree for example) thus
making my gpmc_fclk period 10ns. Now all my synchronous timings are
wrong, because all DT values round to different clock ticks.

One solution would obviously be very verbose: Split synchronous and
asynchronous timings completely. Have a time-ns and a time-tck (where
time is waitmonitoring, or readaccess etc) setting for different use
cases. This would work for truly asynchronous (read _and_ write
asynchronous) as well as truly synchronous (read _and_ write
synchronous) setups.

This 'simple' model breaks for parts where one form of access is
synchronous while the other is asynchronous, e.g. Spansion WS/NS/VS
parts, see [2] pg. 10. There's no easy solution for mixed timings,
because some timing parameters are shared between synchronous and
asynchronous accesses (WAITMONITORINGTIME, CSONTIME, ADVONTIME,
WRDATAONADMUXBUS etc.). One obvious solution is to try to slow the
synchronous side down until asynchronous timings can be met, but that
would make for very slow accesses in most cases.

For instance, I originally started out thinking the GPMC would run at
100 MHz externally -- because it's the max frequency rating -- only to
be surprised when the clock looked weird on the GPMC_CLK pin, because
it was at 166 MHz. I'm not sure how to completely remedy this, but
specifying timings in ns in DT and then depending on the correct board
frequency is kind of shady... :(

Regards,

Robert

[1]: http://lxr.free-electrons.com/source/drivers/memory/omap-gpmc.c#L1509
[2]: http://processors.wiki.ti.com/images/5/56/SpansionNOR-AM35x.pdf ;
(WS/NS/VS can be used for synchronous burst read / asynchronous
single write)
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v5 0/7] irqchip: Move OMAP{4,5}/DRA7 to use stacked domains

2015-02-23 Thread Nishanth Menon
On 02/23/2015 02:32 PM, Nishanth Menon wrote:
 On 17:44-20150223, Marc Zyngier wrote:
 This series is extracted from [4], which is trying to remove all
 traces of gic_arch_extn from the tree. As some maintainers are more
 responsive than others (understatement of the year...), I've decided
 to split it per sub-arch, and get it moving, at least partially.

 This series addresses OMAP{4,5} by converting the WUGEN to stacked
 domains. The DRA7 crossbar gets the same treatment.

 It is worth realizing that:

 - I haven't been able to test this as much as I would have wanted to
   (it's only been tested on omap4 and omap5).

 - This actively *breaks* existing setups. Once you boot a new kernel
   with an old DT, suspend/resume *will* be broken. Old kernels on a
   new DT won't even boot! You've been warned. This really outline the
   necessity of actually describing the HW in device trees...

 Based on 4.0-rc1.

 * From v4: [4]
 - Extracted from the full series
 - Rebased on 4.0-rc1

 * From v3 [3]:
 - Rebased on top of the patch working around hardcoded IRQ on OMAP4/5 [4]
 - Fixed more iMX6 DTs (Stephan)
 - Fixed Exynos4/5 DTs

 * From v2 [2]:
 - Addressed numerous comments from Thierry
 - Merged bug fixes from Nishanth
 - Merged bug fix from Stefan

 * From v1 [1]:
 - Rebased on 3.19-rc3
 - Fixed a number of additional platforms
 - Added crossbar conversion to stacked domains
 - Merged bug fixes from Nishanth

 [4]: 
 http://lists.infradead.org/pipermail/linux-arm-kernel/2015-January/317531.html
 [3]: 
 http://lists.infradead.org/pipermail/linux-arm-kernel/2015-January/315385.html
 [2]: 
 http://lists.infradead.org/pipermail/linux-arm-kernel/2015-January/314041.html
 [1]: 
 http://lists.infradead.org/pipermail/linux-arm-kernel/2014-November/307338.html

 Marc Zyngier (7):
   genirq: Add irqchip_set_wake_parent
   irqchip: crossbar: convert dra7 crossbar to stacked domains
   DT: update ti,irq-crossbar binding
   irqchip: GIC: get rid of routable domain
   DT: arm,gic: kill arm,routable-irqs
   DT: omap4/5: add binding for the wake-up generator
   ARM: omap: convert wakeupgen to stacked domains

  Documentation/devicetree/bindings/arm/gic.txt  |   6 -
  .../devicetree/bindings/arm/omap/crossbar.txt  |  18 +-
  .../interrupt-controller/ti,omap4-wugen-mpu|  33 
  arch/arm/boot/dts/am4372.dtsi  |  11 +-
  arch/arm/boot/dts/am437x-gp-evm.dts|   1 -
  arch/arm/boot/dts/am437x-sk-evm.dts|   1 -
  arch/arm/boot/dts/am43x-epos-evm.dts   |   1 -
  arch/arm/boot/dts/am57xx-beagle-x15.dts|   3 +-
  arch/arm/boot/dts/dra7-evm.dts |   2 +-
  arch/arm/boot/dts/dra7.dtsi|  43 +++--
  arch/arm/boot/dts/dra72-evm.dts|   1 -
  arch/arm/boot/dts/dra72x.dtsi  |   3 +-
  arch/arm/boot/dts/dra74x.dtsi  |   5 +-
  arch/arm/boot/dts/omap4-duovero.dtsi   |   2 -
  arch/arm/boot/dts/omap4-panda-common.dtsi  |   8 +-
  arch/arm/boot/dts/omap4-sdp.dts|   8 +-
  arch/arm/boot/dts/omap4-var-som-om44.dtsi  |   2 -
  arch/arm/boot/dts/omap4.dtsi   |  18 +-
  arch/arm/boot/dts/omap5-cm-t54.dts |   1 -
  arch/arm/boot/dts/omap5-uevm.dts   |   2 -
  arch/arm/boot/dts/omap5.dtsi   |  26 ++-
  arch/arm/mach-omap2/omap-wakeupgen.c   | 125 ++---
  arch/arm/mach-omap2/omap-wakeupgen.h   |   1 -
  arch/arm/mach-omap2/omap4-common.c |  21 +--
  drivers/irqchip/irq-crossbar.c | 207 
 -
  drivers/irqchip/irq-gic.c  |  59 +-
  include/linux/irq.h|   1 +
  include/linux/irqchip/arm-gic.h|   6 -
  include/linux/irqchip/irq-crossbar.h   |  11 --
  kernel/irq/chip.c  |  16 ++
  30 files changed, 364 insertions(+), 278 deletions(-)
  create mode 100644 
 Documentation/devicetree/bindings/interrupt-controller/ti,omap4-wugen-mpu
  delete mode 100644 include/linux/irqchip/irq-crossbar.h
 
 marc-test-irq (Applied the series to v4.0-rc1) - boot logs:
  1: am335x-evm: BOOT: PASS: 
 http://paste.ubuntu.org.cn/2469913
  2:  am335x-sk: BOOT: PASS: 
 http://paste.ubuntu.org.cn/2469914
  3: am3517-evm: BOOT: PASS: 
 http://paste.ubuntu.org.cn/2469915
  4:  am37x-evm: BOOT: PASS: 
 http://paste.ubuntu.org.cn/2469916
  5:  am437x-sk: BOOT: PASS: 
 http://paste.ubuntu.org.cn/2469917
  6:am43xx-epos: BOOT: PASS: 
 http://paste.ubuntu.org.cn/2469918
  7:   am43xx-gpevm: BOOT: PASS: 
 http://paste.ubuntu.org.cn/2469919
  8: BeagleBoard-XM: BOOT: PASS: 
 http://paste.ubuntu.org.cn/2469920
  9

Re: [PATCH v5 0/7] irqchip: Move OMAP{4,5}/DRA7 to use stacked domains

2015-02-23 Thread Nishanth Menon
On 17:44-20150223, Marc Zyngier wrote:
 This series is extracted from [4], which is trying to remove all
 traces of gic_arch_extn from the tree. As some maintainers are more
 responsive than others (understatement of the year...), I've decided
 to split it per sub-arch, and get it moving, at least partially.
 
 This series addresses OMAP{4,5} by converting the WUGEN to stacked
 domains. The DRA7 crossbar gets the same treatment.
 
 It is worth realizing that:
 
 - I haven't been able to test this as much as I would have wanted to
   (it's only been tested on omap4 and omap5).
 
 - This actively *breaks* existing setups. Once you boot a new kernel
   with an old DT, suspend/resume *will* be broken. Old kernels on a
   new DT won't even boot! You've been warned. This really outline the
   necessity of actually describing the HW in device trees...
 
 Based on 4.0-rc1.
 
 * From v4: [4]
 - Extracted from the full series
 - Rebased on 4.0-rc1
 
 * From v3 [3]:
 - Rebased on top of the patch working around hardcoded IRQ on OMAP4/5 [4]
 - Fixed more iMX6 DTs (Stephan)
 - Fixed Exynos4/5 DTs
 
 * From v2 [2]:
 - Addressed numerous comments from Thierry
 - Merged bug fixes from Nishanth
 - Merged bug fix from Stefan
 
 * From v1 [1]:
 - Rebased on 3.19-rc3
 - Fixed a number of additional platforms
 - Added crossbar conversion to stacked domains
 - Merged bug fixes from Nishanth
 
 [4]: 
 http://lists.infradead.org/pipermail/linux-arm-kernel/2015-January/317531.html
 [3]: 
 http://lists.infradead.org/pipermail/linux-arm-kernel/2015-January/315385.html
 [2]: 
 http://lists.infradead.org/pipermail/linux-arm-kernel/2015-January/314041.html
 [1]: 
 http://lists.infradead.org/pipermail/linux-arm-kernel/2014-November/307338.html
 
 Marc Zyngier (7):
   genirq: Add irqchip_set_wake_parent
   irqchip: crossbar: convert dra7 crossbar to stacked domains
   DT: update ti,irq-crossbar binding
   irqchip: GIC: get rid of routable domain
   DT: arm,gic: kill arm,routable-irqs
   DT: omap4/5: add binding for the wake-up generator
   ARM: omap: convert wakeupgen to stacked domains
 
  Documentation/devicetree/bindings/arm/gic.txt  |   6 -
  .../devicetree/bindings/arm/omap/crossbar.txt  |  18 +-
  .../interrupt-controller/ti,omap4-wugen-mpu|  33 
  arch/arm/boot/dts/am4372.dtsi  |  11 +-
  arch/arm/boot/dts/am437x-gp-evm.dts|   1 -
  arch/arm/boot/dts/am437x-sk-evm.dts|   1 -
  arch/arm/boot/dts/am43x-epos-evm.dts   |   1 -
  arch/arm/boot/dts/am57xx-beagle-x15.dts|   3 +-
  arch/arm/boot/dts/dra7-evm.dts |   2 +-
  arch/arm/boot/dts/dra7.dtsi|  43 +++--
  arch/arm/boot/dts/dra72-evm.dts|   1 -
  arch/arm/boot/dts/dra72x.dtsi  |   3 +-
  arch/arm/boot/dts/dra74x.dtsi  |   5 +-
  arch/arm/boot/dts/omap4-duovero.dtsi   |   2 -
  arch/arm/boot/dts/omap4-panda-common.dtsi  |   8 +-
  arch/arm/boot/dts/omap4-sdp.dts|   8 +-
  arch/arm/boot/dts/omap4-var-som-om44.dtsi  |   2 -
  arch/arm/boot/dts/omap4.dtsi   |  18 +-
  arch/arm/boot/dts/omap5-cm-t54.dts |   1 -
  arch/arm/boot/dts/omap5-uevm.dts   |   2 -
  arch/arm/boot/dts/omap5.dtsi   |  26 ++-
  arch/arm/mach-omap2/omap-wakeupgen.c   | 125 ++---
  arch/arm/mach-omap2/omap-wakeupgen.h   |   1 -
  arch/arm/mach-omap2/omap4-common.c |  21 +--
  drivers/irqchip/irq-crossbar.c | 207 
 -
  drivers/irqchip/irq-gic.c  |  59 +-
  include/linux/irq.h|   1 +
  include/linux/irqchip/arm-gic.h|   6 -
  include/linux/irqchip/irq-crossbar.h   |  11 --
  kernel/irq/chip.c  |  16 ++
  30 files changed, 364 insertions(+), 278 deletions(-)
  create mode 100644 
 Documentation/devicetree/bindings/interrupt-controller/ti,omap4-wugen-mpu
  delete mode 100644 include/linux/irqchip/irq-crossbar.h

marc-test-irq (Applied the series to v4.0-rc1) - boot logs:
 1: am335x-evm: BOOT: PASS: 
http://paste.ubuntu.org.cn/2469913
 2:  am335x-sk: BOOT: PASS: 
http://paste.ubuntu.org.cn/2469914
 3: am3517-evm: BOOT: PASS: 
http://paste.ubuntu.org.cn/2469915
 4:  am37x-evm: BOOT: PASS: 
http://paste.ubuntu.org.cn/2469916
 5:  am437x-sk: BOOT: PASS: 
http://paste.ubuntu.org.cn/2469917
 6:am43xx-epos: BOOT: PASS: 
http://paste.ubuntu.org.cn/2469918
 7:   am43xx-gpevm: BOOT: PASS: 
http://paste.ubuntu.org.cn/2469919
 8: BeagleBoard-XM: BOOT: PASS: 
http://paste.ubuntu.org.cn/2469920
 9:beagleboard-vanilla: BOOT: PASS: 
http

Re: [PATCH 2/4] ARM OMAP2+ GPMC: always program GPMCFCLKDIVIDER

2015-02-23 Thread Tony Lindgren
* Robert Abel ra...@cit-ec.uni-bielefeld.de [150223 13:42]:
 On Tue, Feb 17, 2015 at 3:25 PM, Roger Quadros rog...@ti.com wrote:
  one more thing to note is that just specifying sync-clk-ps in DT is not 
  enough for
  asynchronous devices.
 
  The driver doesn't set gpmc_t-sync_clk if gpmc,sync-read or 
  gpmc,sync-write
  was not set in the DT, which would be the case for asynchronous devices.
 
 You're mistaken. It's always parsed, no matter what. See [1]. But I
 did implement your suggestion of computing the divider in the mean
 time. I'm going to send the patches rebased to 3.19 tomorrow, after I
 tested them.
 
  What is your proposal to make things better? And what is your use case that 
  doesn't
  work with existing setup?
 
 Well, the current setup was obviously inspired by an asynchronous-only
 use-case, where all the timings are in seconds and get converted
 on-the-fly. Of course, currently, there is no support to re-compute
 them once the gpmc_fclk changes frequency, but I guess that's what the
 TODO about the clock framework is about?
 
 Anyway, my synchronous use-case is inherently... synchronous.
 Synchronous protocols shouldn't be specified in ns at all. They should
 directly be specified in clock ticks. This is also advantageous, as
 changes in gpmc_fclk don't need to propagate to the registers.
 
 My main grief with the current setup is its dependency on the
 *unknown* gpmc_fclk period at startup when the DT is processed and
 GPMC code is called. For instance, my private DT currently operates on
 the assumption of 166 Mhz L3 clk (and therefore gpmc_fclk), so all my
 timings are in multiples of 6 ns. Should now a colleague of mine think
 it would be a splendid idea to change this frequency by means of
 bootloader options [to save power, to process data even faster, etc],
 everything would break, because the L3 might have to be clocked at 100
 MHz (due to divider limits along the clock tree for example) thus
 making my gpmc_fclk period 10ns. Now all my synchronous timings are
 wrong, because all DT values round to different clock ticks.
 
 One solution would obviously be very verbose: Split synchronous and
 asynchronous timings completely. Have a time-ns and a time-tck (where
 time is waitmonitoring, or readaccess etc) setting for different use
 cases. This would work for truly asynchronous (read _and_ write
 asynchronous) as well as truly synchronous (read _and_ write
 synchronous) setups.
 
 This 'simple' model breaks for parts where one form of access is
 synchronous while the other is asynchronous, e.g. Spansion WS/NS/VS
 parts, see [2] pg. 10. There's no easy solution for mixed timings,
 because some timing parameters are shared between synchronous and
 asynchronous accesses (WAITMONITORINGTIME, CSONTIME, ADVONTIME,
 WRDATAONADMUXBUS etc.). One obvious solution is to try to slow the
 synchronous side down until asynchronous timings can be met, but that
 would make for very slow accesses in most cases.
 
 For instance, I originally started out thinking the GPMC would run at
 100 MHz externally -- because it's the max frequency rating -- only to
 be surprised when the clock looked weird on the GPMC_CLK pin, because
 it was at 166 MHz. I'm not sure how to completely remedy this, but
 specifying timings in ns in DT and then depending on the correct board
 frequency is kind of shady... :(

There have been few gpmc devices that were configured to work with
changing L3 frequencies. For the related retime function, maybe take
a look at the code removed for tusb_set_sync_mode() in commit
47acde167260. Just specifying the ticks is not enough there either..

Sorry I don't have a solution to how the timings should be specified,
but both timings and ticks are needed it seems.

Regards,

Tony
 
 [1]: http://lxr.free-electrons.com/source/drivers/memory/omap-gpmc.c#L1509
 [2]: http://processors.wiki.ti.com/images/5/56/SpansionNOR-AM35x.pdf ;
 (WS/NS/VS can be used for synchronous burst read / asynchronous
 single write)
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v5 0/7] irqchip: Move OMAP{4,5}/DRA7 to use stacked domains

2015-02-23 Thread Tony Lindgren
* Marc Zyngier marc.zyng...@arm.com [150223 09:48]:
 This series is extracted from [4], which is trying to remove all
 traces of gic_arch_extn from the tree. As some maintainers are more
 responsive than others (understatement of the year...), I've decided
 to split it per sub-arch, and get it moving, at least partially.
 
 This series addresses OMAP{4,5} by converting the WUGEN to stacked
 domains. The DRA7 crossbar gets the same treatment.
 
 It is worth realizing that:
 
 - I haven't been able to test this as much as I would have wanted to
   (it's only been tested on omap4 and omap5).
 
 - This actively *breaks* existing setups. Once you boot a new kernel
   with an old DT, suspend/resume *will* be broken. Old kernels on a
   new DT won't even boot! You've been warned. This really outline the
   necessity of actually describing the HW in device trees...

Could we parse still the old binding and produce warning for the
case when a new kernel is booted with the old DT? That would make
it easier for people to debug what's going on.

Regards,

Tony
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: advanced LED controllers

2015-02-23 Thread Felipe Balbi
On Mon, Feb 23, 2015 at 11:34:57PM +0100, Pavel Machek wrote:
 On Thu 2015-02-19 15:14:24, Felipe Balbi wrote:
  Hi,
  
  Do we have support for LED controllers which can handle patterns of
  different kinds ? I mean, currently, if we have an LED controller such
  as TPIC2810 [1] which can control 8 different leds and each LED
  corresponds to one bit on register 0x44, we could control leds by just
  playing a wave file on the controller and create easy patterns with
  that.
  
  AFAICT, in linux today we would have to register each of the 8 LEDs as a
  different LED and have driver magic to write the proper bits on register
  0x44, that seems a bit overkill, specially when we want to make
  patterns: instead of writing 0xff we would have to write 0x80, 0x40,
  0x20, 0x10, 0x08, 0x04, 0x02, 0x01 separately and have the driver cache
  the previous results so we don't end up switching off other LEDs.
  
  IOW, what could be handled with a single write, currently needs 8.
  
  I wonder if there's any work happening to support these slightly more
  inteligent LED engines.
  
  regards
  
  [1] http://www.ti.com/product/tpic2810
  
  ps: tpic2810 is probably the simplest example, lp551, lp5523 and others
  have even more advanced pattern engines which can even handle RGB leds.
 
 Well... some more advanced pattern engines can actually run code, up
 to and including prime number computation. So yes, this is complex,
 and how to handle it nicely is a question...
 
 I have notcc to compile for that.

right, the point is that this is a solution which only works with lp5523
and IMO linux led subsystem should do a little more for such devices.

-- 
balbi


signature.asc
Description: Digital signature


Re: advanced LED controllers

2015-02-23 Thread Pavel Machek
On Thu 2015-02-19 15:14:24, Felipe Balbi wrote:
 Hi,
 
 Do we have support for LED controllers which can handle patterns of
 different kinds ? I mean, currently, if we have an LED controller such
 as TPIC2810 [1] which can control 8 different leds and each LED
 corresponds to one bit on register 0x44, we could control leds by just
 playing a wave file on the controller and create easy patterns with
 that.
 
 AFAICT, in linux today we would have to register each of the 8 LEDs as a
 different LED and have driver magic to write the proper bits on register
 0x44, that seems a bit overkill, specially when we want to make
 patterns: instead of writing 0xff we would have to write 0x80, 0x40,
 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 separately and have the driver cache
 the previous results so we don't end up switching off other LEDs.
 
 IOW, what could be handled with a single write, currently needs 8.
 
 I wonder if there's any work happening to support these slightly more
 inteligent LED engines.
 
 regards
 
 [1] http://www.ti.com/product/tpic2810
 
 ps: tpic2810 is probably the simplest example, lp551, lp5523 and others
 have even more advanced pattern engines which can even handle RGB leds.

Well... some more advanced pattern engines can actually run code, up
to and including prime number computation. So yes, this is complex,
and how to handle it nicely is a question...

I have notcc to compile for that.

#!/usr/bin/python3
#
# NOTification Compiler
#
# for LP5523 chip.
#
# Copyright 2014 Pavel Machek pa...@ucw.cz, GPLv3
#
# http://wiki.maemo.org/LED_patterns#Lysti_Format_Engine_Patterns_and_Commands
# 
http://www.ti.com/general/docs/lit/getliterature.tsp?genericPartNumber=lp5523fileType=pdf
#
# Seems to have A,B local variables, C global variable,
#
# 2.6.28-omap1 seems to cut execution after 16 steps.

import sys



Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) 
http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: New l3-noc error with CPUFREQ_DT built-in with v4.0-rc1

2015-02-23 Thread Tony Lindgren
* Felipe Balbi ba...@ti.com [150223 18:28]:
 Hi,
 
 On Mon, Feb 23, 2015 at 05:59:04PM -0800, Tony Lindgren wrote:
  * Tony Lindgren t...@atomide.com [150223 16:09]:
   Hi Nishanth,
   
   Olof told me about a new L3 error happening on omap5-uevm with
   v4.0-rc1:
   
   WARNING: CPU: 0 PID: 0 at drivers/bus/omap_l3_noc.c:147 
   l3_interrupt_handler+0x214/0x340()
   400.ocp:L3 Custom Error: MASTER MPU TARGET L4PER2 (Idle): Data Access 
   in Supervisor mode during Functional access
   ...
   
   I tried bisecting this with no luck, but narrowed it down to
   having CONFIG_CPUFREQ_DT=y causing it, while =m wont' trigger
   it. This got changed by commit 40d1746d2eee (ARM:
   omap2plus_defconfig: use CONFIG_CPUFREQ_DT).
   
   Any ideas?
  
  Hmm so setting CONFIG_CPUFREQ_DT=m in arch/arm/configs/omap2plus_defconfig
  produces the same output with make omap2plus_defconfig as with =y.. So
  CPUFREQ_DT can't be the real cause of the problem.
  
  It's now looking like the l3-noc warning does not get triggered on
  every boot.
  
  It also seems the zImage triggering the error does not trigger the
  error on every boot. To trigger the error, it seems the device needs to
  be powered down for at least 10 or so seconds between the boots.
  So far no luck reproducing the error on v3.19.
  
  The easy way to reproduce is to power down omap5 for at least 10 seconds,
  make omap2lus_defconfig on v4.0-rc1 and boot it.
  
  And so far it looks like next-20150204 works and next-20150209
  failed at once so far. But of course I would not trust anything
  at this point :)
 
 got a log of the failure ? Is it pointing to a device or one of the L4s?

Well mostly the MASTER MPU TARGET L4PER2, the following stack dump is
really the stack dump of the l3_interrupt_handler.
 
 Might be worth to boot with just the bare minimum (UART  timers) and
 disable everything else. You might need to build busybox and append that
 to the kernel so you don't need to rely on MMC/USB/etc for rootfs.
 
 After that, you could start enabling modules one by one (as modules, not
 built-in) and loading them one by one to see which one causes the
 failure. Big PITA, I know, but I can't think of any other way to go
 about this.

It seems the best way to deal with this is to make the l3_handle_target
actually show the address where the error happened to limit it down
to a single device..

Regards,

Tony
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: New l3-noc error with CPUFREQ_DT built-in with v4.0-rc1

2015-02-23 Thread Tony Lindgren
* Tony Lindgren t...@atomide.com [150223 18:43]:
 * Felipe Balbi ba...@ti.com [150223 18:28]:
  Hi,
  
  On Mon, Feb 23, 2015 at 05:59:04PM -0800, Tony Lindgren wrote:
   * Tony Lindgren t...@atomide.com [150223 16:09]:
Hi Nishanth,

Olof told me about a new L3 error happening on omap5-uevm with
v4.0-rc1:

WARNING: CPU: 0 PID: 0 at drivers/bus/omap_l3_noc.c:147 
l3_interrupt_handler+0x214/0x340()
400.ocp:L3 Custom Error: MASTER MPU TARGET L4PER2 (Idle): Data 
Access in Supervisor mode during Functional access
...

I tried bisecting this with no luck, but narrowed it down to
having CONFIG_CPUFREQ_DT=y causing it, while =m wont' trigger
it. This got changed by commit 40d1746d2eee (ARM:
omap2plus_defconfig: use CONFIG_CPUFREQ_DT).

Any ideas?
   
   Hmm so setting CONFIG_CPUFREQ_DT=m in arch/arm/configs/omap2plus_defconfig
   produces the same output with make omap2plus_defconfig as with =y.. So
   CPUFREQ_DT can't be the real cause of the problem.
   
   It's now looking like the l3-noc warning does not get triggered on
   every boot.
   
   It also seems the zImage triggering the error does not trigger the
   error on every boot. To trigger the error, it seems the device needs to
   be powered down for at least 10 or so seconds between the boots.
   So far no luck reproducing the error on v3.19.
   
   The easy way to reproduce is to power down omap5 for at least 10 seconds,
   make omap2lus_defconfig on v4.0-rc1 and boot it.
   
   And so far it looks like next-20150204 works and next-20150209
   failed at once so far. But of course I would not trust anything
   at this point :)
  
  got a log of the failure ? Is it pointing to a device or one of the L4s?
 
 Well mostly the MASTER MPU TARGET L4PER2, the following stack dump is
 really the stack dump of the l3_interrupt_handler.
  
  Might be worth to boot with just the bare minimum (UART  timers) and
  disable everything else. You might need to build busybox and append that
  to the kernel so you don't need to rely on MMC/USB/etc for rootfs.
  
  After that, you could start enabling modules one by one (as modules, not
  built-in) and loading them one by one to see which one causes the
  failure. Big PITA, I know, but I can't think of any other way to go
  about this.
 
 It seems the best way to deal with this is to make the l3_handle_target
 actually show the address where the error happened to limit it down
 to a single device..

Looks like the address is 0 for Custom Error. Anyways, reverting
a fix for similar issue found on omap3 so far seems to help, that's
3d009c8c61f9 (gpio: omap: Fix bad device access with setup_irq()).

That got merged very late for v3.19, so it certainly explains why
it was not noticed until now.

Regards,

Tony
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: New l3-noc error with CPUFREQ_DT built-in with v4.0-rc1

2015-02-23 Thread Tony Lindgren
* Felipe Balbi ba...@ti.com [150223 19:19]:
 On Mon, Feb 23, 2015 at 07:01:42PM -0800, Tony Lindgren wrote:
  * Tony Lindgren t...@atomide.com [150223 18:43]:
  
  Looks like the address is 0 for Custom Error. Anyways, reverting
 
 yeah, that's because the error comes from l4per2, not l3 :-)

Right so it seems :)
 
  a fix for similar issue found on omap3 so far seems to help, that's
  3d009c8c61f9 (gpio: omap: Fix bad device access with setup_irq()).
 
 if we revert that, we regress omap3, right ?

Yes we saw that getting triggered on omap3/4 before 3d009c8c61f9.

Now looking at the stack trace again, it actually has something:

...
[c05999a4] (__irq_svc) from [c0599164] 
(_raw_spin_unlock_irqrestore+0x34/0x44)
[c0599164] (_raw_spin_unlock_irqrestore) from [c0027120] 
(omap_hwmod_idle+0x34/0x44)
[c0027120] (omap_hwmod_idle) from [c00283f8] (omap_device_idle+0x38/0x78)
[c00283f8] (omap_device_idle) from [c0028454] 
(_od_runtime_suspend+0x1c/0x24)
[c0028454] (_od_runtime_suspend) from [c03b5214] (__rpm_callback+0x2c/0x60)
[c03b5214] (__rpm_callback) from [c03b5268] (rpm_callback+0x20/0x80)
[c03b5268] (rpm_callback) from [c03b56b8] (rpm_suspend+0xe8/0x55c)
[c03b56b8] (rpm_suspend) from [c03b6bdc] (pm_runtime_work+0x74/0xa8)
[c03b6bdc] (pm_runtime_work) from [c0054608] (process_one_work+0x1b0/0x4a0)
...

If it's the gpio-omap, there's probably some confusion still in
the driver regarding the GPIO bank idle status. Anyways, will look
more into it tomorrow.

Regards,

Tony
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v5 0/7] irqchip: Move OMAP{4,5}/DRA7 to use stacked domains

2015-02-23 Thread Tony Lindgren
* Tony Lindgren t...@atomide.com [150223 15:10]:
 * Marc Zyngier marc.zyng...@arm.com [150223 09:48]:
  This series is extracted from [4], which is trying to remove all
  traces of gic_arch_extn from the tree. As some maintainers are more
  responsive than others (understatement of the year...), I've decided
  to split it per sub-arch, and get it moving, at least partially.
  
  This series addresses OMAP{4,5} by converting the WUGEN to stacked
  domains. The DRA7 crossbar gets the same treatment.
  
  It is worth realizing that:
  
  - I haven't been able to test this as much as I would have wanted to
(it's only been tested on omap4 and omap5).
  
  - This actively *breaks* existing setups. Once you boot a new kernel
with an old DT, suspend/resume *will* be broken. Old kernels on a
new DT won't even boot! You've been warned. This really outline the
necessity of actually describing the HW in device trees...
 
 Could we parse still the old binding and produce warning for the
 case when a new kernel is booted with the old DT? That would make
 it easier for people to debug what's going on.

Other than that, this series seems to behave for me. Please feel
free to add Acked-by: Tony Lindgren t...@atomide.com. It Looks
like this series should be applied into an immutable branch
against v4.0-rc1 that I can pull in as needed to avoid merge
conflicts with the dts files.

Regards,

Tony
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/4] mmc: core: fold mmc_set_bus_width calls into sdio_enable_4bit_bus.

2015-02-23 Thread NeilBrown
Every call to sdio_enable_4bit_bus is followed (on success) but a call
to mmc_set_bus_width().

To simplify the code, include those calls directly in
sdio_enable_4bit_bus().

Signed-off-by: NeilBrown n...@brown.name
---
 drivers/mmc/core/sdio.c |   32 
 1 file changed, 12 insertions(+), 20 deletions(-)

diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
index ce6cc47206b0..5bc6c7dbbd60 100644
--- a/drivers/mmc/core/sdio.c
+++ b/drivers/mmc/core/sdio.c
@@ -293,19 +293,22 @@ static int sdio_enable_4bit_bus(struct mmc_card *card)
int err;
 
if (card-type == MMC_TYPE_SDIO)
-   return sdio_enable_wide(card);
-
-   if ((card-host-caps  MMC_CAP_4_BIT_DATA) 
-   (card-scr.bus_widths  SD_SCR_BUS_WIDTH_4)) {
+   err = sdio_enable_wide(card);
+   else if ((card-host-caps  MMC_CAP_4_BIT_DATA) 
+(card-scr.bus_widths  SD_SCR_BUS_WIDTH_4)) {
err = mmc_app_set_bus_width(card, MMC_BUS_WIDTH_4);
if (err)
return err;
+   err = sdio_enable_wide(card);
+   if (err = 0)
+   mmc_app_set_bus_width(card, MMC_BUS_WIDTH_1);
} else
return 0;
 
-   err = sdio_enable_wide(card);
-   if (err = 0)
-   mmc_app_set_bus_width(card, MMC_BUS_WIDTH_1);
+   if (err  0) {
+   mmc_set_bus_width(card-host, MMC_BUS_WIDTH_4);
+   err = 0;
+   }
 
return err;
 }
@@ -547,13 +550,8 @@ static int mmc_sdio_init_uhs_card(struct mmc_card *card)
/*
 * Switch to wider bus (if supported).
 */
-   if (card-host-caps  MMC_CAP_4_BIT_DATA) {
+   if (card-host-caps  MMC_CAP_4_BIT_DATA)
err = sdio_enable_4bit_bus(card);
-   if (err  0) {
-   mmc_set_bus_width(card-host, MMC_BUS_WIDTH_4);
-   err = 0;
-   }
-   }
 
/* Set the driver strength for the card */
sdio_select_driver_type(card);
@@ -803,9 +801,7 @@ try_again:
 * Switch to wider bus (if supported).
 */
err = sdio_enable_4bit_bus(card);
-   if (err  0)
-   mmc_set_bus_width(card-host, MMC_BUS_WIDTH_4);
-   else if (err)
+   if (err)
goto remove;
}
 finish:
@@ -983,10 +979,6 @@ static int mmc_sdio_resume(struct mmc_host *host)
} else if (mmc_card_keep_power(host)  mmc_card_wake_sdio_irq(host)) {
/* We may have switched to 1-bit mode during suspend */
err = sdio_enable_4bit_bus(host-card);
-   if (err  0) {
-   mmc_set_bus_width(host, MMC_BUS_WIDTH_4);
-   err = 0;
-   }
}
 
if (!err  host-sdio_irqs) {


--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 4/4] mmc: omap_hsmmc: switch to 1-bit before stopping clocks.

2015-02-23 Thread NeilBrown
Make use of the new mmc_sdio_want_no_clocks() call to avoid stopping
clocks while SD Card interrupts are enabled and we aren't in
1-bit mode.

Also stop clocks immediately in omap_hsmmc_disable_fclk() if
1-bit mode has been entered for this purpose.

With this, I can use my libertas wifi with a 4-bit bus, with
interrupts and runtime power-management enabled, and get around
14Mb/sec throughput (which is the best I've seen).

Signed-off-by: NeilBrown n...@brown.name
---
 drivers/mmc/host/omap_hsmmc.c |   13 ++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index f84cfb01716d..14fce3b92633 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -1791,9 +1791,12 @@ static int omap_hsmmc_disable_fclk(struct mmc_host *mmc)
 {
struct omap_hsmmc_host *host = mmc_priv(mmc);
 
-   pm_runtime_mark_last_busy(host-dev);
-   pm_runtime_put_autosuspend(host-dev);
-
+   if (atomic_read(mmc-sdio_narrowed) == 2)
+   pm_runtime_put_sync(host-dev);
+   else {
+   pm_runtime_mark_last_busy(host-dev);
+   pm_runtime_put_autosuspend(host-dev);
+   }
return 0;
 }
 
@@ -2311,6 +2314,10 @@ static int omap_hsmmc_runtime_suspend(struct device *dev)
spin_lock_irqsave(host-irq_lock, flags);
if ((host-mmc-caps  MMC_CAP_SDIO_IRQ) 
(host-flags  HSMMC_SDIO_IRQ_ENABLED)) {
+   if (mmc_sdio_want_no_clocks(host-mmc) == 0) {
+   ret = -EBUSY;
+   goto abort;
+   }
/* disable sdio irq handling to prevent race */
OMAP_HSMMC_WRITE(host-base, ISE, 0);
OMAP_HSMMC_WRITE(host-base, IE, 0);


--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/4] mmc: core: allow non-blocking form of mmc_claim_host

2015-02-23 Thread NeilBrown
Change the handling for the 'abort' flag so that if
it is set, but we can claim the host, then do the claim,
rather than aborting.

When the abort is async this just means that a race between aborting
an allowing a claim is resolved slightly differently.  Any
code must already be able to handle 'abort' being set just as the host
is claimed.

This allows extra functionality.  If __mmc_claim_host() is called
with an 'abort' pointer which is initialized to '1', it will effect a
non-blocking 'claim'.

Signed-off-by: NeilBrown n...@brown.name
---
 drivers/mmc/core/core.c |3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 23f10f72e5f3..541c8903dc6b 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -912,10 +912,11 @@ int __mmc_claim_host(struct mmc_host *host, atomic_t 
*abort)
spin_lock_irqsave(host-lock, flags);
}
set_current_state(TASK_RUNNING);
-   if (!stop) {
+   if (!host-claimed || host-claimer == current) {
host-claimed = 1;
host-claimer = current;
host-claim_cnt += 1;
+   stop = 0;
} else
wake_up(host-wq);
spin_unlock_irqrestore(host-lock, flags);


--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 0/4] Switch to 1-bit mode SDIO before disabling clocks.

2015-02-23 Thread NeilBrown
This is a reworking of this code that I promised at the end of
January.

SDIO interrupt in 4-bit mode require the clock to be running.  So we
need to switch to 1-bit mode before turning off the clock.

This series provides infrastructure in mmc-core, and adds the
functionality to omap_hsmmc.

Thanks,
NeilBrown


---

NeilBrown (4):
  mmc: core: fold mmc_set_bus_width calls into sdio_enable_4bit_bus.
  mmc: core: allow non-blocking form of mmc_claim_host
  mmc: sdio: support switching to 1-bit before turning off clocks
  mmc: omap_hsmmc: switch to 1-bit before stopping clocks.


 drivers/mmc/core/core.c   |   21 +---
 drivers/mmc/core/sdio.c   |   74 +
 drivers/mmc/host/omap_hsmmc.c |   13 ++-
 include/linux/mmc/core.h  |2 +
 include/linux/mmc/host.h  |2 +
 5 files changed, 83 insertions(+), 29 deletions(-)

--
Signature

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 3/4] mmc: sdio: support switching to 1-bit before turning off clocks

2015-02-23 Thread NeilBrown
According to section 7.1.2 of

http://www.sandisk.com/media/File/OEM/Manuals/SD_SDIO_specsv1.pdf

In the case where the interrupt mechanism is used to wake the host while
the card is in a low power state (i.e. no clocks), Both the card and the
host shall be placed into the 1-bit SD mode prior to stopping the clock.

This is particularly important for the Marvell libertas wifi chip
in the GTA04.  While in 4-bit mode it will only signal an interrupt
when the clock is running (which is why setting CLKEXTFREE is
important).
In 1-bit mode, the interrupt is asynchronous (explained in OMAP3
TRM description of the CIRQ flag to MMCHS_STAT:

  In 1-bit mode, interrupt source is asynchronous (can be a source of
  asynchronous wakeup).
  In 4-bit mode, interrupt source is sampled during the interrupt
  cycle.

)

It is awkward to simply set 1-bit mode in -runtime_suspend
as that will call mmc_set_ios which calls ops-set_ios(),
which will likely call pm_runtime_get_sync(), on the device that
is currently suspending.  This deadlocks.

So:
 - create a work_struct to schedule setting of 1-bit mode
 - introduce an 'sdio_narrowed' state flag which transitions:
 0 (normal) - 1 (convert to 1-bit pending) -
 2 (have switch to 1-bit mode) - 0 (normal)
 - create a function mmc_sdio_want_no_clocks() which can be called
   when the driver wants to turn off clocks (presumably after an
   idle timeout).  This either succeeds (in 1-bit mode) or fails
   and schedules the work to switch to 1-bit mode.
 - when the host is claimed, if sdio_narrowed is 2, restore the
   4-bit bus
 - When the host is released, if sdio_narrowed is 1, then some
   caller other  than our worker claimed the host first, so
   clear sdio_narrowed.

This all allows a graceful and race-free switch to 1-bit mode
before switching off the clocks, if SDIO interrupts are enabled.

A host should call mmc_sdio_want_no_clocks() when about to turn off
clocks if sdio interrupts are enabled, and the -disable() function
should not use a timeout (pm_runtime_put_autosuspend) if
-sdio_narrowed is 2.

Signed-off-by: NeilBrown n...@brown.name
---
 drivers/mmc/core/core.c  |   18 ++
 drivers/mmc/core/sdio.c  |   42 +-
 include/linux/mmc/core.h |2 ++
 include/linux/mmc/host.h |2 ++
 4 files changed, 59 insertions(+), 5 deletions(-)

diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 541c8903dc6b..0258fdf1a03d 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -921,8 +921,14 @@ int __mmc_claim_host(struct mmc_host *host, atomic_t 
*abort)
wake_up(host-wq);
spin_unlock_irqrestore(host-lock, flags);
remove_wait_queue(host-wq, wait);
-   if (host-ops-enable  !stop  host-claim_cnt == 1)
-   host-ops-enable(host);
+   if (!stop  host-claim_cnt == 1) {
+   if (host-ops-enable)
+   host-ops-enable(host);
+   if (atomic_read(host-sdio_narrowed) == 2) {
+   sdio_enable_4bit_bus(host-card);
+   atomic_set(host-sdio_narrowed, 0);
+   }
+   }
return stop;
 }
 
@@ -941,8 +947,12 @@ void mmc_release_host(struct mmc_host *host)
 
WARN_ON(!host-claimed);
 
-   if (host-ops-disable  host-claim_cnt == 1)
-   host-ops-disable(host);
+   if (host-claim_cnt == 1) {
+   if (atomic_read(host-sdio_narrowed) == 1)
+   atomic_set(host-sdio_narrowed, 0);
+   if (host-ops-disable)
+   host-ops-disable(host);
+   }
 
spin_lock_irqsave(host-lock, flags);
if (--host-claim_cnt) {
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
index 5bc6c7dbbd60..9761e4d5f49b 100644
--- a/drivers/mmc/core/sdio.c
+++ b/drivers/mmc/core/sdio.c
@@ -288,7 +288,7 @@ static int sdio_disable_wide(struct mmc_card *card)
 }
 
 
-static int sdio_enable_4bit_bus(struct mmc_card *card)
+int sdio_enable_4bit_bus(struct mmc_card *card)
 {
int err;
 
@@ -313,6 +313,45 @@ static int sdio_enable_4bit_bus(struct mmc_card *card)
return err;
 }
 
+static void mmc_sdio_width_work(struct work_struct *work)
+{
+   struct mmc_host *host = container_of(work, struct mmc_host,
+sdio_width_work);
+   atomic_t noblock;
+
+   atomic_set(noblock, 1);
+   if (__mmc_claim_host(host, noblock))
+   return;
+   if (atomic_read(host-sdio_narrowed) != 1) {
+   /* Nothing to do */
+   mmc_release_host(host);
+   return;
+   }
+   if (sdio_disable_wide(host-card) == 0)
+   atomic_set(host-sdio_narrowed, 2);
+   else
+   atomic_set(host-sdio_narrowed, 0);
+   mmc_release_host(host);
+}
+
+int mmc_sdio_want_no_clocks(struct mmc_host *host)
+{
+   if (!(host-caps  MMC_CAP_SDIO_IRQ) ||
+   

New l3-noc error with CPUFREQ_DT built-in with v4.0-rc1

2015-02-23 Thread Tony Lindgren
Hi Nishanth,

Olof told me about a new L3 error happening on omap5-uevm with
v4.0-rc1:

WARNING: CPU: 0 PID: 0 at drivers/bus/omap_l3_noc.c:147 
l3_interrupt_handler+0x214/0x340()
400.ocp:L3 Custom Error: MASTER MPU TARGET L4PER2 (Idle): Data Access in 
Supervisor mode during Functional access
...

I tried bisecting this with no luck, but narrowed it down to
having CONFIG_CPUFREQ_DT=y causing it, while =m wont' trigger
it. This got changed by commit 40d1746d2eee (ARM:
omap2plus_defconfig: use CONFIG_CPUFREQ_DT).

Any ideas?

Regards,

Tony
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: New l3-noc error with CPUFREQ_DT built-in with v4.0-rc1

2015-02-23 Thread Tony Lindgren
* Tony Lindgren t...@atomide.com [150223 16:09]:
 Hi Nishanth,
 
 Olof told me about a new L3 error happening on omap5-uevm with
 v4.0-rc1:
 
 WARNING: CPU: 0 PID: 0 at drivers/bus/omap_l3_noc.c:147 
 l3_interrupt_handler+0x214/0x340()
 400.ocp:L3 Custom Error: MASTER MPU TARGET L4PER2 (Idle): Data Access in 
 Supervisor mode during Functional access
 ...
 
 I tried bisecting this with no luck, but narrowed it down to
 having CONFIG_CPUFREQ_DT=y causing it, while =m wont' trigger
 it. This got changed by commit 40d1746d2eee (ARM:
 omap2plus_defconfig: use CONFIG_CPUFREQ_DT).
 
 Any ideas?

Hmm so setting CONFIG_CPUFREQ_DT=m in arch/arm/configs/omap2plus_defconfig
produces the same output with make omap2plus_defconfig as with =y.. So
CPUFREQ_DT can't be the real cause of the problem.

It's now looking like the l3-noc warning does not get triggered on
every boot.

It also seems the zImage triggering the error does not trigger the
error on every boot. To trigger the error, it seems the device needs to
be powered down for at least 10 or so seconds between the boots.
So far no luck reproducing the error on v3.19.

The easy way to reproduce is to power down omap5 for at least 10 seconds,
make omap2lus_defconfig on v4.0-rc1 and boot it.

And so far it looks like next-20150204 works and next-20150209
failed at once so far. But of course I would not trust anything
at this point :)

Regards,

Tony 
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: New l3-noc error with CPUFREQ_DT built-in with v4.0-rc1

2015-02-23 Thread Felipe Balbi
Hi,

On Mon, Feb 23, 2015 at 07:01:42PM -0800, Tony Lindgren wrote:
 * Tony Lindgren t...@atomide.com [150223 18:43]:
  * Felipe Balbi ba...@ti.com [150223 18:28]:
   Hi,
   
   On Mon, Feb 23, 2015 at 05:59:04PM -0800, Tony Lindgren wrote:
* Tony Lindgren t...@atomide.com [150223 16:09]:
 Hi Nishanth,
 
 Olof told me about a new L3 error happening on omap5-uevm with
 v4.0-rc1:
 
 WARNING: CPU: 0 PID: 0 at drivers/bus/omap_l3_noc.c:147 
 l3_interrupt_handler+0x214/0x340()
 400.ocp:L3 Custom Error: MASTER MPU TARGET L4PER2 (Idle): Data 
 Access in Supervisor mode during Functional access
 ...
 
 I tried bisecting this with no luck, but narrowed it down to
 having CONFIG_CPUFREQ_DT=y causing it, while =m wont' trigger
 it. This got changed by commit 40d1746d2eee (ARM:
 omap2plus_defconfig: use CONFIG_CPUFREQ_DT).
 
 Any ideas?

Hmm so setting CONFIG_CPUFREQ_DT=m in 
arch/arm/configs/omap2plus_defconfig
produces the same output with make omap2plus_defconfig as with =y.. So
CPUFREQ_DT can't be the real cause of the problem.

It's now looking like the l3-noc warning does not get triggered on
every boot.

It also seems the zImage triggering the error does not trigger the
error on every boot. To trigger the error, it seems the device needs to
be powered down for at least 10 or so seconds between the boots.
So far no luck reproducing the error on v3.19.

The easy way to reproduce is to power down omap5 for at least 10 
seconds,
make omap2lus_defconfig on v4.0-rc1 and boot it.

And so far it looks like next-20150204 works and next-20150209
failed at once so far. But of course I would not trust anything
at this point :)
   
   got a log of the failure ? Is it pointing to a device or one of the L4s?
  
  Well mostly the MASTER MPU TARGET L4PER2, the following stack dump is
  really the stack dump of the l3_interrupt_handler.
   
   Might be worth to boot with just the bare minimum (UART  timers) and
   disable everything else. You might need to build busybox and append that
   to the kernel so you don't need to rely on MMC/USB/etc for rootfs.
   
   After that, you could start enabling modules one by one (as modules, not
   built-in) and loading them one by one to see which one causes the
   failure. Big PITA, I know, but I can't think of any other way to go
   about this.
  
  It seems the best way to deal with this is to make the l3_handle_target
  actually show the address where the error happened to limit it down
  to a single device..
 
 Looks like the address is 0 for Custom Error. Anyways, reverting

yeah, that's because the error comes from l4per2, not l3 :-)

 a fix for similar issue found on omap3 so far seems to help, that's
 3d009c8c61f9 (gpio: omap: Fix bad device access with setup_irq()).

if we revert that, we regress omap3, right ?

-- 
balbi


signature.asc
Description: Digital signature


Re: New l3-noc error with CPUFREQ_DT built-in with v4.0-rc1

2015-02-23 Thread Felipe Balbi
On Mon, Feb 23, 2015 at 06:35:06PM -0800, Tony Lindgren wrote:
 * Felipe Balbi ba...@ti.com [150223 18:28]:
  Hi,
  
  On Mon, Feb 23, 2015 at 05:59:04PM -0800, Tony Lindgren wrote:
   * Tony Lindgren t...@atomide.com [150223 16:09]:
Hi Nishanth,

Olof told me about a new L3 error happening on omap5-uevm with
v4.0-rc1:

WARNING: CPU: 0 PID: 0 at drivers/bus/omap_l3_noc.c:147 
l3_interrupt_handler+0x214/0x340()
400.ocp:L3 Custom Error: MASTER MPU TARGET L4PER2 (Idle): Data 
Access in Supervisor mode during Functional access
...

I tried bisecting this with no luck, but narrowed it down to
having CONFIG_CPUFREQ_DT=y causing it, while =m wont' trigger
it. This got changed by commit 40d1746d2eee (ARM:
omap2plus_defconfig: use CONFIG_CPUFREQ_DT).

Any ideas?
   
   Hmm so setting CONFIG_CPUFREQ_DT=m in arch/arm/configs/omap2plus_defconfig
   produces the same output with make omap2plus_defconfig as with =y.. So
   CPUFREQ_DT can't be the real cause of the problem.
   
   It's now looking like the l3-noc warning does not get triggered on
   every boot.
   
   It also seems the zImage triggering the error does not trigger the
   error on every boot. To trigger the error, it seems the device needs to
   be powered down for at least 10 or so seconds between the boots.
   So far no luck reproducing the error on v3.19.
   
   The easy way to reproduce is to power down omap5 for at least 10 seconds,
   make omap2lus_defconfig on v4.0-rc1 and boot it.
   
   And so far it looks like next-20150204 works and next-20150209
   failed at once so far. But of course I would not trust anything
   at this point :)
  
  got a log of the failure ? Is it pointing to a device or one of the L4s?
 
 Well mostly the MASTER MPU TARGET L4PER2, the following stack dump is
 really the stack dump of the l3_interrupt_handler.
  
  Might be worth to boot with just the bare minimum (UART  timers) and
  disable everything else. You might need to build busybox and append that
  to the kernel so you don't need to rely on MMC/USB/etc for rootfs.
  
  After that, you could start enabling modules one by one (as modules, not
  built-in) and loading them one by one to see which one causes the
  failure. Big PITA, I know, but I can't think of any other way to go
  about this.
 
 It seems the best way to deal with this is to make the l3_handle_target
 actually show the address where the error happened to limit it down
 to a single device..

you can't really do that from within l3. It doesn't have enough
information to figure that out. Since it pointed you to l4per2, then you
need to decode l4per2's debug registers. That has never been
implemented, though. What happened here is that l4per2 detected the
bogus access from one of the devices attached to it and passed the error
up to l3. Since we only have l3 decoding, that's what you see and it
ends up being really cryptic.

If you decode l4per2's registers, I'm sure it'll point you to a real
device. I guess just to prove the concept, you just hack it inside l3
irq handler, though ideally we would have a real drivers/bus/omap-l4.c,
or something like that.

-- 
balbi


signature.asc
Description: Digital signature


[PATCH 2/4] usb: phy: twl4030: allow charger to see usb current draw limits.

2015-02-23 Thread NeilBrown
The charger needs to know when a USB gadget has been enumerated
and what the agreed maximum current was so that it can adjust
charging accordingly.

So define a set_power() function to record the permitted
draw, and pass a pointer to that when sending USB_EVENT_ENUMERATED
notification.

Signed-off-by: NeilBrown ne...@suse.de
---
 drivers/phy/phy-twl4030-usb.c |   27 +--
 1 file changed, 21 insertions(+), 6 deletions(-)

diff --git a/drivers/phy/phy-twl4030-usb.c b/drivers/phy/phy-twl4030-usb.c
index 97c59074233f..023fe150c7a1 100644
--- a/drivers/phy/phy-twl4030-usb.c
+++ b/drivers/phy/phy-twl4030-usb.c
@@ -163,6 +163,11 @@ struct twl4030_usb {
enum omap_musb_vbus_id_status linkstat;
boolvbus_supplied;
 
+   /* Permitted vbus draw - only meaningful after
+* USB_EVENT_ENUMERATED
+*/
+   unsignedvbus_draw;
+
struct delayed_work id_workaround_work;
 };
 
@@ -547,12 +552,7 @@ static irqreturn_t twl4030_usb_irq(int irq, void *_twl)
mutex_unlock(twl-lock);
 
if (status_changed) {
-   /* FIXME add a set_power() method so that B-devices can
-* configure the charger appropriately.  It's not always
-* correct to consume VBUS power, and how much current to
-* consume is a function of the USB configuration chosen
-* by the host.
-*
+   /*
 * REVISIT usb_gadget_vbus_connect(...) as needed, ditto
 * its disconnect() sibling, when changing to/from the
 * USB_LINK_VBUS state.  musb_hdrc won't care until it
@@ -625,6 +625,20 @@ static int twl4030_set_host(struct usb_otg *otg, struct 
usb_bus *host)
return 0;
 }
 
+static int twl4030_set_power(struct usb_phy *phy, unsigned mA)
+{
+   struct twl4030_usb *twl = phy_to_twl(phy);
+
+   if (twl-vbus_draw != mA) {
+   phy-last_event = USB_EVENT_ENUMERATED;
+   twl-vbus_draw = mA;
+   atomic_notifier_call_chain(phy-notifier,
+  USB_EVENT_ENUMERATED,
+  twl-vbus_draw);
+   }
+   return 0;
+}
+
 static const struct phy_ops ops = {
.init   = twl4030_phy_init,
.power_on   = twl4030_phy_power_on,
@@ -675,6 +689,7 @@ static int twl4030_usb_probe(struct platform_device *pdev)
twl-phy.label  = twl4030;
twl-phy.otg= otg;
twl-phy.type   = USB_PHY_TYPE_USB2;
+   twl-phy.set_power  = twl4030_set_power;
 
otg-usb_phy= twl-phy;
otg-set_host   = twl4030_set_host;


--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/4] usb: phy: twl4030: make runtime pm more reliable.

2015-02-23 Thread NeilBrown
A construct like:

if (pm_runtime_suspended(twl-dev))
   pm_runtime_get_sync(twl-dev);

is against the spirit of the runtime_pm interface as it
makes the internal refcounting useless.

In this case it is also racy, particularly as 'put_autosuspend'
is use to drop a reference.
When that happens a timer is started and the device is
runtime-suspended after the timeout.
If the above code runs in this window, the device will not be
found to be suspended so no pm_runtime reference is taken.
When the timer expires the device will be suspended, which is
against the intention of the code.

So be more direct is taking and dropping references.
If twl-linkstat is VBUS_VALID or ID_GROUND, then hold a
pm_runtime reference, otherwise don't.

Signed-off-by: NeilBrown ne...@suse.de
---
 drivers/phy/phy-twl4030-usb.c |   20 +---
 1 file changed, 13 insertions(+), 7 deletions(-)

diff --git a/drivers/phy/phy-twl4030-usb.c b/drivers/phy/phy-twl4030-usb.c
index 8e87f54671f3..97c59074233f 100644
--- a/drivers/phy/phy-twl4030-usb.c
+++ b/drivers/phy/phy-twl4030-usb.c
@@ -536,8 +536,13 @@ static irqreturn_t twl4030_usb_irq(int irq, void *_twl)
 
mutex_lock(twl-lock);
if (status = 0  status != twl-linkstat) {
+   status_changed =
+   (twl-linkstat == OMAP_MUSB_VBUS_VALID ||
+twl-linkstat == OMAP_MUSB_ID_GROUND)
+   !=
+   (status == OMAP_MUSB_VBUS_VALID ||
+status == OMAP_MUSB_ID_GROUND);
twl-linkstat = status;
-   status_changed = true;
}
mutex_unlock(twl-lock);
 
@@ -555,13 +560,10 @@ static irqreturn_t twl4030_usb_irq(int irq, void *_twl)
 */
if ((status == OMAP_MUSB_VBUS_VALID) ||
(status == OMAP_MUSB_ID_GROUND)) {
-   if (pm_runtime_suspended(twl-dev))
-   pm_runtime_get_sync(twl-dev);
+   pm_runtime_get_sync(twl-dev);
} else {
-   if (pm_runtime_active(twl-dev)) {
-   pm_runtime_mark_last_busy(twl-dev);
-   pm_runtime_put_autosuspend(twl-dev);
-   }
+   pm_runtime_mark_last_busy(twl-dev);
+   pm_runtime_put_autosuspend(twl-dev);
}
omap_musb_mailbox(status);
}
@@ -768,6 +770,10 @@ static int twl4030_usb_remove(struct platform_device *pdev)
 
/* disable complete OTG block */
twl4030_usb_clear_bits(twl, POWER_CTRL, POWER_CTRL_OTG_ENAB);
+
+   if (twl-linkstat == OMAP_MUSB_VBUS_VALID ||
+   twl-linkstat == OMAP_MUSB_ID_GROUND)
+   pm_runtime_put_noidle(twl-dev);
pm_runtime_mark_last_busy(twl-dev);
pm_runtime_put(twl-dev);
 


--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 3/4] usb: phy: twl4030: add support for reading restore on ID pin.

2015-02-23 Thread NeilBrown
The twl4030 phy can measure, with low precision, the
resistance-to-ground of the ID pin.

Add a function to read the value, and export the result
via sysfs.

If the read fails, which it does sometimes, try again in 50msec.

Signed-off-by: NeilBrown ne...@suse.de
---
 drivers/phy/phy-twl4030-usb.c |   63 +
 1 file changed, 63 insertions(+)

diff --git a/drivers/phy/phy-twl4030-usb.c b/drivers/phy/phy-twl4030-usb.c
index 023fe150c7a1..759950898df9 100644
--- a/drivers/phy/phy-twl4030-usb.c
+++ b/drivers/phy/phy-twl4030-usb.c
@@ -374,6 +374,56 @@ static void twl4030_i2c_access(struct twl4030_usb *twl, 
int on)
}
 }
 
+enum twl4030_id_status {
+   TWL4030_GROUND,
+   TWL4030_102K,
+   TWL4030_200K,
+   TWL4030_440K,
+   TWL4030_FLOATING,
+   TWL4030_ID_UNKNOWN,
+};
+static char *twl4030_id_names[] = {
+   ground,
+   102k,
+   200k,
+   440k,
+   floating,
+   unknown
+};
+
+enum twl4030_id_status twl4030_get_id(struct twl4030_usb *twl)
+{
+   int ret;
+
+   pm_runtime_get_sync(twl-dev);
+   if (twl-usb_mode == T2_USB_MODE_ULPI)
+   twl4030_i2c_access(twl, 1);
+   ret = twl4030_usb_read(twl, ULPI_OTG_CTRL);
+   if (ret  0 || !(ret  ULPI_OTG_ID_PULLUP)) {
+   /* Need pull-up to read ID */
+   twl4030_usb_set_bits(twl, ULPI_OTG_CTRL,
+ULPI_OTG_ID_PULLUP);
+   mdelay(50);
+   }
+   ret = twl4030_usb_read(twl, ID_STATUS);
+   if (ret  0 || (ret  0x1f) == 0) {
+   mdelay(50);
+   ret = twl4030_usb_read(twl, ID_STATUS);
+   }
+
+   if (twl-usb_mode == T2_USB_MODE_ULPI)
+   twl4030_i2c_access(twl, 0);
+   pm_runtime_put_autosuspend(twl-dev);
+
+   if (ret  0)
+   return TWL4030_ID_UNKNOWN;
+   ret = ffs(ret) - 1;
+   if (ret  TWL4030_GROUND || ret  TWL4030_FLOATING)
+   return TWL4030_ID_UNKNOWN;
+
+   return ret;
+}
+
 static void __twl4030_phy_power(struct twl4030_usb *twl, int on)
 {
u8 pwr = twl4030_usb_read(twl, PHY_PWR_CTRL);
@@ -531,6 +581,16 @@ static ssize_t twl4030_usb_vbus_show(struct device *dev,
 }
 static DEVICE_ATTR(vbus, 0444, twl4030_usb_vbus_show, NULL);
 
+static ssize_t twl4030_usb_id_show(struct device *dev,
+  struct device_attribute *attr,
+  char *buf)
+{
+   struct twl4030_usb *twl = dev_get_drvdata(dev);
+   return scnprintf(buf, PAGE_SIZE, %s\n,
+twl4030_id_names[twl4030_get_id(twl)]);
+}
+static DEVICE_ATTR(id, 0444, twl4030_usb_id_show, NULL);
+
 static irqreturn_t twl4030_usb_irq(int irq, void *_twl)
 {
struct twl4030_usb *twl = _twl;
@@ -723,6 +783,8 @@ static int twl4030_usb_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, twl);
if (device_create_file(pdev-dev, dev_attr_vbus))
dev_warn(pdev-dev, could not create sysfs file\n);
+   if (device_create_file(pdev-dev, dev_attr_id))
+   dev_warn(pdev-dev, could not create sysfs file\n);
 
ATOMIC_INIT_NOTIFIER_HEAD(twl-phy.notifier);
 
@@ -768,6 +830,7 @@ static int twl4030_usb_remove(struct platform_device *pdev)
pm_runtime_get_sync(twl-dev);
cancel_delayed_work(twl-id_workaround_work);
device_remove_file(twl-dev, dev_attr_vbus);
+   device_remove_file(twl-dev, dev_attr_id);
 
/* set transceiver mode to power on defaults */
twl4030_usb_set_mode(twl, -1);


--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 4/4] usb: phy: twl4030: test ID resistance to see if charger is present.

2015-02-23 Thread NeilBrown
If an 'A' plug is inserted, ID should be pulled to ground.
If a 'B' plug, then ID should be floating.

If an Accessory Charger Adapter is inserted, then ID will
be neither grounded nor floating.  In this case tell the
USB subsystem that it is an A plug, and the battery
charging subsystem that it is a charger.

Fortunately, this will treat the Openmoko charger (and
other similar chargers) as a charger.

Signed-off-by: NeilBrown ne...@suse.de
---
 drivers/phy/phy-twl4030-usb.c |   28 
 1 file changed, 28 insertions(+)

diff --git a/drivers/phy/phy-twl4030-usb.c b/drivers/phy/phy-twl4030-usb.c
index 759950898df9..8a43080cdbd7 100644
--- a/drivers/phy/phy-twl4030-usb.c
+++ b/drivers/phy/phy-twl4030-usb.c
@@ -596,9 +596,31 @@ static irqreturn_t twl4030_usb_irq(int irq, void *_twl)
struct twl4030_usb *twl = _twl;
enum omap_musb_vbus_id_status status;
bool status_changed = false;
+   bool found_charger = false;
 
status = twl4030_usb_linkstat(twl);
 
+   if (status == OMAP_MUSB_ID_GROUND ||
+   status == OMAP_MUSB_VBUS_VALID) {
+   /* We should check the resistance on the ID pin.
+* If not a Ground or Floating, then this is
+* likely a charger
+*/
+   enum twl4030_id_status sts = twl4030_get_id(twl);
+   if (sts  TWL4030_GROUND 
+   sts  TWL4030_FLOATING) {
+   /*
+* This might be a charger, or an
+* Accessory Charger Adapter.
+* In either case we can charge, and it
+* makes sense to tell the USB system
+* that we might be acting as a HOST.
+*/
+   status = OMAP_MUSB_ID_GROUND;
+   found_charger = true;
+   }
+   }
+
mutex_lock(twl-lock);
if (status = 0  status != twl-linkstat) {
status_changed =
@@ -627,6 +649,12 @@ static irqreturn_t twl4030_usb_irq(int irq, void *_twl)
}
omap_musb_mailbox(status);
}
+   if (found_charger  twl-phy.last_event != USB_EVENT_CHARGER) {
+   twl-phy.last_event = USB_EVENT_CHARGER;
+   atomic_notifier_call_chain(twl-phy.notifier,
+  USB_EVENT_CHARGER,
+  NULL);
+   }
 
/* don't schedule during sleep - irq works right then */
if (status == OMAP_MUSB_ID_GROUND  pm_runtime_active(twl-dev)) {


--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 0/4] Enhancements to twl4030 phy to support better charging.

2015-02-23 Thread NeilBrown
Hi,
 the following 4 patches make some improvements to the twl4030
 phy.  Together with some other patches I have for twl4030_charger,
 they allow for better automatic control of charging.

 In particular, the status of the ID pin is assessed and the
 result in communicated to the charger drivers.
 There is also support for conveying the max current negotiated by a
 host to the charger.

Comments most welcome.

thanks,
NeilBrown


---

NeilBrown (4):
  usb: phy: twl4030: make runtime pm more reliable.
  usb: phy: twl4030: allow charger to see usb current draw limits.
  usb: phy: twl4030: add support for reading restore on ID pin.
  usb: phy: twl4030: test ID resistance to see if charger is present.


 drivers/phy/phy-twl4030-usb.c |  138 +
 1 file changed, 125 insertions(+), 13 deletions(-)

--
Signature

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 08/15] twl4030_charger: distinguish between USB current and 'AC' current

2015-02-23 Thread NeilBrown
The twl4030 charger has two current sources, 'USB' and 'AC' (which is
really DC of course...).

If 'AC' is providing current, we should set the current limit
differently to when it isn't (and so USB is used).
So split 'cur' into 'usb_cur' and 'ac_cur' and use accordingly.

Now we must review the current setting on any interrupt or USB
event which might indicate that the charger-source has changed.

Signed-off-by: NeilBrown ne...@suse.de
---
 drivers/power/twl4030_charger.c |   30 +-
 1 file changed, 25 insertions(+), 5 deletions(-)

diff --git a/drivers/power/twl4030_charger.c b/drivers/power/twl4030_charger.c
index 7c35cd9ba171..bfc9b808301e 100644
--- a/drivers/power/twl4030_charger.c
+++ b/drivers/power/twl4030_charger.c
@@ -22,6 +22,7 @@
 #include linux/power_supply.h
 #include linux/notifier.h
 #include linux/usb/otg.h
+#include linux/i2c/twl4030-madc.h
 
 #define TWL4030_BCIMSTATEC 0x02
 #define TWL4030_BCIICHG0x08
@@ -103,7 +104,9 @@ struct twl4030_bci {
/* ichg values in uA. If any are 'large', we set CGAIN to
 * '1' which doubles the range for half the precision.
 */
-   int ichg_eoc, ichg_lo, ichg_hi, cur;
+   int ichg_eoc, ichg_lo, ichg_hi;
+   int usb_cur, ac_cur;
+   boolac_is_active;
 
unsigned long   event;
 };
@@ -224,11 +227,23 @@ static int ua2regval(int ua, bool cgain)
 static int twl4030_charger_update_current(struct twl4030_bci *bci)
 {
int status;
+   int cur;
unsigned reg, cur_reg;
u8 bcictl1, oldreg, fullreg;
int cgain = 0;
u8 boot_bci;
 
+   /* If VAC exceeds 4.5V (MADC 11) and ac is enabled, set current
+* for 'ac'
+*/
+   if (twl4030_get_madc_conversion(11)  4500) {
+   cur = bci-ac_cur;
+   bci-ac_is_active = 1;
+   } else {
+   cur = bci-usb_cur;
+   bci-ac_is_active = 0;
+   }
+
/* First, check thresholds and see if cgain is needed */
if (bci-ichg_eoc = 20)
cgain = 1;
@@ -236,7 +251,7 @@ static int twl4030_charger_update_current(struct 
twl4030_bci *bci)
cgain = 1;
if (bci-ichg_hi = 82)
cgain = 1;
-   if (bci-cur  852000)
+   if (cur  852000)
cgain = 1;
 
status = twl4030_bci_read(TWL4030_BCICTL1, bcictl1);
@@ -311,7 +326,7 @@ static int twl4030_charger_update_current(struct 
twl4030_bci *bci)
 
/* And finally, set the current.  This is stored in
 * two registers. */
-   reg = ua2regval(bci-cur, cgain);
+   reg = ua2regval(cur, cgain);
/* we have only 10 bit */
if (reg  0x3ff)
reg = 0x3ff;
@@ -364,6 +379,8 @@ static int twl4030_charger_enable_usb(struct twl4030_bci 
*bci, bool enable)
 
if (enable  !IS_ERR_OR_NULL(bci-transceiver)) {
 
+   twl4030_charger_update_current(bci);
+
/* Need to keep phy powered */
if (!bci-usb_enabled) {
pm_runtime_get_sync(bci-transceiver-dev);
@@ -456,6 +473,7 @@ static irqreturn_t twl4030_charger_interrupt(int irq, void 
*arg)
struct twl4030_bci *bci = arg;
 
dev_dbg(bci-dev, CHG_PRES irq\n);
+   twl4030_charger_update_current(bci);
power_supply_changed(bci-ac);
power_supply_changed(bci-usb);
 
@@ -488,6 +506,7 @@ static irqreturn_t twl4030_bci_interrupt(int irq, void *arg)
power_supply_changed(bci-ac);
power_supply_changed(bci-usb);
}
+   twl4030_charger_update_current(bci);
 
/* various monitoring events, for now we just log them here */
if (irqs1  (TWL4030_TBATOR2 | TWL4030_TBATOR1))
@@ -701,10 +720,11 @@ static int __init twl4030_bci_probe(struct 
platform_device *pdev)
bci-ichg_eoc = 80100; /* Stop charging when current drops to here */
bci-ichg_lo = 241000; /* low threshold */
bci-ichg_hi = 50; /* High threshold */
+   bci-ac_cur = 50; /* 500mA */
if (allow_usb)
-   bci-cur = 50;  /* 500mA */
+   bci-usb_cur = 50;  /* 500mA */
else
-   bci-cur = 10;  /* 100mA */
+   bci-usb_cur = 10;  /* 100mA */
 
bci-dev = pdev-dev;
bci-irq_chg = platform_get_irq(pdev, 0);


--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 07/15] twl4030_charger: allow fine control of charger current.

2015-02-23 Thread NeilBrown
The twl4030 allows control of the incoming current.
Part of this control is a 'CGAIN' setting which doubles
the range for half the precision.  This control affects
several different current setting, so all need to be updated
at once when CGAIN is changed.

With this patch, all of these current setting are managed
by the driver, but most are left at their default settings.

The current drawn is set to 500mA if the allow_usb module parameter is
set, and to 100mA otherwise.
More fine control will appear in later patches.

Signed-off-by: NeilBrown ne...@suse.de
---
 drivers/power/twl4030_charger.c |  161 +--
 1 file changed, 153 insertions(+), 8 deletions(-)

diff --git a/drivers/power/twl4030_charger.c b/drivers/power/twl4030_charger.c
index 0b6fb06a0c01..7c35cd9ba171 100644
--- a/drivers/power/twl4030_charger.c
+++ b/drivers/power/twl4030_charger.c
@@ -31,6 +31,11 @@
 #define TWL4030_BCIMFSTS4  0x10
 #define TWL4030_BCICTL10x23
 #define TWL4030_BB_CFG 0x12
+#define TWL4030_BCIIREF1   0x27
+#define TWL4030_BCIIREF2   0x28
+#define TWL4030_BCIMFKEY   0x11
+#define TWL4030_BCIMFTH8   0x1d
+#define TWL4030_BCIMFTH9   0x1e
 
 #define TWL4030_BCIMFSTS1  0x01
 
@@ -95,6 +100,11 @@ struct twl4030_bci {
int irq_bci;
int usb_enabled;
 
+   /* ichg values in uA. If any are 'large', we set CGAIN to
+* '1' which doubles the range for half the precision.
+*/
+   int ichg_eoc, ichg_lo, ichg_hi, cur;
+
unsigned long   event;
 };
 
@@ -211,6 +221,140 @@ static int ua2regval(int ua, bool cgain)
return ret;
 }
 
+static int twl4030_charger_update_current(struct twl4030_bci *bci)
+{
+   int status;
+   unsigned reg, cur_reg;
+   u8 bcictl1, oldreg, fullreg;
+   int cgain = 0;
+   u8 boot_bci;
+
+   /* First, check thresholds and see if cgain is needed */
+   if (bci-ichg_eoc = 20)
+   cgain = 1;
+   if (bci-ichg_lo = 40)
+   cgain = 1;
+   if (bci-ichg_hi = 82)
+   cgain = 1;
+   if (bci-cur  852000)
+   cgain = 1;
+
+   status = twl4030_bci_read(TWL4030_BCICTL1, bcictl1);
+   if (status  0)
+   return status;
+   if (twl_i2c_read_u8(TWL_MODULE_PM_MASTER, boot_bci,
+   TWL4030_PM_MASTER_BOOT_BCI)  0)
+   boot_bci = 0;
+   boot_bci = 7;
+
+   if ((!!cgain) != !!(bcictl1  TWL4030_CGAIN))
+   /* Need to turn for charging while we change the
+* CGAIN bit.  Leave it off while everything is
+* updated.
+*/
+   twl4030_clear_set_boot_bci(boot_bci, 0);
+
+   /* For ichg_eoc, reg value must be 100000, we only
+* set the  in high nibble.
+*/
+   reg = ua2regval(bci-ichg_eoc, cgain);
+   if (reg  0x278)
+   reg = 0x278;
+   if (reg  0x200)
+   reg = 0x200;
+   reg = (reg  3)  0xf;
+   fullreg = reg  4;
+
+   /* For ichg_lo, reg value must be 10.
+*  is stored in low nibble */
+   reg = ua2regval(bci-ichg_lo, cgain);
+   if (reg  0x2F0)
+   reg = 0x2F0;
+   if (reg  0x200)
+   reg = 0x200;
+   reg = (reg  4)  0xf;
+   fullreg |= reg;
+
+   /* ichg_eoc and ichg_lo live in same register */
+   status = twl4030_bci_read(TWL4030_BCIMFTH8, oldreg);
+   if (status  0)
+   return status;
+   if (oldreg != fullreg) {
+   status = twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE, 0xF4,
+ TWL4030_BCIMFKEY);
+   if (status  0)
+   return status;
+   twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE,
+fullreg, TWL4030_BCIMFTH8);
+   }
+
+   /* ichg_hi threshold must be 101100 (I think) */
+   reg = ua2regval(bci-ichg_hi, cgain);
+   if (reg  0x3E0)
+   reg = 0x3E0;
+   if (reg  0x200)
+   reg = 0x200;
+   fullreg = (reg  5)  0xF;
+   fullreg = 4;
+   status = twl4030_bci_read(TWL4030_BCIMFTH9, oldreg);
+   if (status  0)
+   return status;
+   if ((oldreg  0xF0) != fullreg) {
+   fullreg |= (oldreg  0x0F);
+   status = twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE, 0xE7,
+ TWL4030_BCIMFKEY);
+   if (status  0)
+   return status;
+   twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE,
+fullreg, TWL4030_BCIMFTH9);
+   }
+
+   /* And finally, set the current.  This is stored in
+* two registers. */
+   reg = ua2regval(bci-cur, cgain);
+   /* we have only 10 bit */
+   if (reg  0x3ff)
+   reg = 0x3ff;

[PATCH 04/15] twl4030_charger: use runtime_pm to keep usb phy active while charging.

2015-02-23 Thread NeilBrown
The twl4030 usb phy needs to be active while we are using
the USB VBUS as a current source for charging.
In particular, the usb3v1 regulator must be enabled and the
PHY_PWR_PHYPWD bit must be set to keep the phy powered.

commit ab37813f4093a5f59cb8e083cde277289dc72ed3
twl4030_charger: Allow charger to control the regulator that feeds it

Gave the charger control over the regulator, but didn't resolve
the PHY_PWR_PHYPWD issue.

Now that both of these are controlled by runtime_pm in
phy-twl4030-usb, we can simply take a runtime_pm reference to the USB
phy whenever the charger wants to use it as a current source.

So this patch reverts the above commit, and adds the necessary
runtime_pm calls.

Signed-off-by: NeilBrown ne...@suse.de
---
 drivers/mfd/twl-core.c  |9 -
 drivers/power/twl4030_charger.c |   18 +-
 2 files changed, 9 insertions(+), 18 deletions(-)

diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
index 489674a2497e..831696ee2472 100644
--- a/drivers/mfd/twl-core.c
+++ b/drivers/mfd/twl-core.c
@@ -788,9 +788,8 @@ add_children(struct twl4030_platform_data *pdata, unsigned 
irq_base,
static struct regulator_consumer_supply usb1v8 = {
.supply =   usb1v8,
};
-   static struct regulator_consumer_supply usb3v1[] = {
-   { .supply = usb3v1 },
-   { .supply = bci3v1 },
+   static struct regulator_consumer_supply usb3v1 = {
+   .supply =   usb3v1,
};
 
/* First add the regulators so that they can be used by transceiver */
@@ -818,7 +817,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned 
irq_base,
return PTR_ERR(child);
 
child = add_regulator_linked(TWL4030_REG_VUSB3V1,
- usb_fixed, usb3v1, 2,
+ usb_fixed, usb3v1, 1,
  features);
if (IS_ERR(child))
return PTR_ERR(child);
@@ -838,7 +837,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned 
irq_base,
if (IS_ENABLED(CONFIG_REGULATOR_TWL4030)  child) {
usb1v5.dev_name = dev_name(child);
usb1v8.dev_name = dev_name(child);
-   usb3v1[0].dev_name = dev_name(child);
+   usb3v1.dev_name = dev_name(child);
}
}
 
diff --git a/drivers/power/twl4030_charger.c b/drivers/power/twl4030_charger.c
index 51321f0c5548..11f352a5ef55 100644
--- a/drivers/power/twl4030_charger.c
+++ b/drivers/power/twl4030_charger.c
@@ -22,7 +22,6 @@
 #include linux/power_supply.h
 #include linux/notifier.h
 #include linux/usb/otg.h
-#include linux/regulator/machine.h
 
 #define TWL4030_BCIMSTATEC 0x02
 #define TWL4030_BCIICHG0x08
@@ -94,7 +93,6 @@ struct twl4030_bci {
struct work_struct  work;
int irq_chg;
int irq_bci;
-   struct regulator*usb_reg;
int usb_enabled;
 
unsigned long   event;
@@ -208,7 +206,7 @@ static int twl4030_charger_enable_usb(struct twl4030_bci 
*bci, bool enable)
 {
int ret;
 
-   if (enable) {
+   if (enable  !IS_ERR_OR_NULL(bci-transceiver)) {
/* Check for USB charger connected */
if (!twl4030_bci_have_vbus(bci))
return -ENODEV;
@@ -222,14 +220,9 @@ static int twl4030_charger_enable_usb(struct twl4030_bci 
*bci, bool enable)
return -EACCES;
}
 
-   /* Need to keep regulator on */
+   /* Need to keep phy powered */
if (!bci-usb_enabled) {
-   ret = regulator_enable(bci-usb_reg);
-   if (ret) {
-   dev_err(bci-dev,
-   Failed to enable regulator\n);
-   return ret;
-   }
+   pm_runtime_get_sync(bci-transceiver-dev);
bci-usb_enabled = 1;
}
 
@@ -244,7 +237,8 @@ static int twl4030_charger_enable_usb(struct twl4030_bci 
*bci, bool enable)
} else {
ret = twl4030_clear_set_boot_bci(TWL4030_BCIAUTOUSB, 0);
if (bci-usb_enabled) {
-   regulator_disable(bci-usb_reg);
+   pm_runtime_mark_last_busy(bci-transceiver-dev);
+   pm_runtime_put_autosuspend(bci-transceiver-dev);
bci-usb_enabled = 0;
}
}
@@ -602,8 +596,6 @@ static int __init twl4030_bci_probe(struct platform_device 
*pdev)

[PATCH 06/15] twl4030_charger: split uA calculation into a function.

2015-02-23 Thread NeilBrown
We will need this calculation in other places, so
create functions to map between register value and uA value.

Signed-off-by: NeilBrown ne...@suse.de
---
 drivers/power/twl4030_charger.c |   48 ---
 1 file changed, 35 insertions(+), 13 deletions(-)

diff --git a/drivers/power/twl4030_charger.c b/drivers/power/twl4030_charger.c
index db8931a17541..0b6fb06a0c01 100644
--- a/drivers/power/twl4030_charger.c
+++ b/drivers/power/twl4030_charger.c
@@ -178,6 +178,40 @@ static int twl4030_is_battery_present(struct twl4030_bci 
*bci)
 }
 
 /*
+ * TI provided formulas:
+ * CGAIN == 0: ICHG = (BCIICHG * 1.7) / (2^10 - 1) - 0.85
+ * CGAIN == 1: ICHG = (BCIICHG * 3.4) / (2^10 - 1) - 1.7
+ * Here we use integer approximation of:
+ * CGAIN == 0: val * 1.6618 - 0.85 * 1000
+ * CGAIN == 1: (val * 1.6618 - 0.85 * 1000) * 2
+ */
+/*
+ * convert twl register value for currents into uA
+ */
+static int regval2ua(int regval, bool cgain)
+{
+   if (cgain)
+   return (regval * 16618 - 8500 * 1000) / 5;
+   else
+   return (regval * 16618 - 8500 * 1000) / 10;
+}
+
+/*
+ * convert uA currents into twl register value
+ */
+static int ua2regval(int ua, bool cgain)
+{
+   int ret;
+   if (cgain)
+   ua /= 2;
+   ret = (ua * 10 + 8500 * 1000) / 16618;
+   /* rounding problems */
+   if (ret  512)
+   ret = 512;
+   return ret;
+}
+
+/*
  * Enable/Disable USB Charge functionality.
  */
 static int twl4030_charger_enable_usb(struct twl4030_bci *bci, bool enable)
@@ -366,14 +400,6 @@ static int twl4030_bci_usb_ncb(struct notifier_block *nb, 
unsigned long val,
return NOTIFY_OK;
 }
 
-/*
- * TI provided formulas:
- * CGAIN == 0: ICHG = (BCIICHG * 1.7) / (2^10 - 1) - 0.85
- * CGAIN == 1: ICHG = (BCIICHG * 3.4) / (2^10 - 1) - 1.7
- * Here we use integer approximation of:
- * CGAIN == 0: val * 1.6618 - 0.85
- * CGAIN == 1: (val * 1.6618 - 0.85) * 2
- */
 static int twl4030_charger_get_current(void)
 {
int curr;
@@ -388,11 +414,7 @@ static int twl4030_charger_get_current(void)
if (ret)
return ret;
 
-   ret = (curr * 16618 - 850 * 1) / 10;
-   if (bcictl1  TWL4030_CGAIN)
-   ret *= 2;
-
-   return ret;
+   return regval2ua(curr, bcictl1  TWL4030_CGAIN);
 }
 
 /*


--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 05/15] twl4030_charger: trust phy to determine when USB power is available.

2015-02-23 Thread NeilBrown
The usb phy driver already determines when VBUS is available,
so repeating the test in the charger driver is pointless duplication.

On probe, process the last event from the phy, and from then on,
do whatever the phy tells us without double-checking.

Signed-off-by: NeilBrown ne...@suse.de
---
 drivers/power/twl4030_charger.c |   33 ++---
 1 file changed, 6 insertions(+), 27 deletions(-)

diff --git a/drivers/power/twl4030_charger.c b/drivers/power/twl4030_charger.c
index 11f352a5ef55..db8931a17541 100644
--- a/drivers/power/twl4030_charger.c
+++ b/drivers/power/twl4030_charger.c
@@ -178,28 +178,6 @@ static int twl4030_is_battery_present(struct twl4030_bci 
*bci)
 }
 
 /*
- * Check if VBUS power is present
- */
-static int twl4030_bci_have_vbus(struct twl4030_bci *bci)
-{
-   int ret;
-   u8 hwsts;
-
-   ret = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, hwsts,
- TWL4030_PM_MASTER_STS_HW_CONDITIONS);
-   if (ret  0)
-   return 0;
-
-   dev_dbg(bci-dev, check_vbus: HW_CONDITIONS %02x\n, hwsts);
-
-   /* in case we also have STS_USB_ID, VBUS is driven by TWL itself */
-   if ((hwsts  TWL4030_STS_VBUS)  !(hwsts  TWL4030_STS_USB_ID))
-   return 1;
-
-   return 0;
-}
-
-/*
  * Enable/Disable USB Charge functionality.
  */
 static int twl4030_charger_enable_usb(struct twl4030_bci *bci, bool enable)
@@ -207,10 +185,6 @@ static int twl4030_charger_enable_usb(struct twl4030_bci 
*bci, bool enable)
int ret;
 
if (enable  !IS_ERR_OR_NULL(bci-transceiver)) {
-   /* Check for USB charger connected */
-   if (!twl4030_bci_have_vbus(bci))
-   return -ENODEV;
-
/*
 * Until we can find out what current the device can provide,
 * require a module param to enable USB charging.
@@ -649,7 +623,12 @@ static int __init twl4030_bci_probe(struct platform_device 
*pdev)
dev_warn(pdev-dev, failed to unmask interrupts: %d\n, ret);
 
twl4030_charger_enable_ac(true);
-   twl4030_charger_enable_usb(bci, true);
+   if (!IS_ERR_OR_NULL(bci-transceiver))
+   twl4030_bci_usb_ncb(bci-usb_nb,
+   bci-transceiver-last_event,
+   NULL);
+   else
+   twl4030_charger_enable_usb(bci, false);
if (pdata)
twl4030_charger_enable_backup(pdata-bb_uvolt,
  pdata-bb_uamp);


--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 00/15] Enhance twl4030_charger functionality.

2015-02-23 Thread NeilBrown
These patches make a number of improvements to twl4030_charger.

So are just internal cleanups (e.g. use of devres).  Others allow
better control of charging through both manual and automatic means.

- the maximum current can be configured via sysfs.
- the charger will only draw that current if it can do so without
  the voltage dropping too much
- a 'continuous' mode is available which ignores voltage and just
  takes what it can (to be used with caution, but very useful in
  some circumstances).
- 'ac' and 'usb' power sources can be configured separately.

Some of this functionality requires patch to phy-twl4030-usb.c which
have been sent separately.

Thanks,
NeilBrown


---

NeilBrown (15):
  power_supply core: support use of devres to register/unregister a power 
supply.
  twl4030_charger: use devm_request_threaded_irq
  twl4030_charger: use devres for power_supply_register and kzalloc.
  twl4030_charger: use runtime_pm to keep usb phy active while charging.
  twl4030_charger: trust phy to determine when USB power is available.
  twl4030_charger: split uA calculation into a function.
  twl4030_charger: allow fine control of charger current.
  twl4030_charger: distinguish between USB current and 'AC' current
  twl4030_charger: allow max_current to be managed via sysfs.
  twl4030_charger: only draw USB current as negotiated with host.
  twl4030_charger: enable manual enable/disable of usb charging.
  twl4030_charger: add software controlled linear charging mode.
  twl4030_charger: add ac/mode to match usb/mode
  twl4030_charger: Increase current carefully while watching voltage.
  twl4030_charger: assume a 'charger' can supply maximum current.


 drivers/mfd/twl-core.c|9 -
 drivers/power/power_supply_core.c |   45 +++
 drivers/power/twl4030_charger.c   |  572 +++--
 include/linux/power_supply.h  |4 
 4 files changed, 539 insertions(+), 91 deletions(-)

--
Signature

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: New l3-noc error with CPUFREQ_DT built-in with v4.0-rc1

2015-02-23 Thread Tony Lindgren
* Tony Lindgren t...@atomide.com [150223 19:29]:
 * Felipe Balbi ba...@ti.com [150223 19:19]:
  On Mon, Feb 23, 2015 at 07:01:42PM -0800, Tony Lindgren wrote:
   * Tony Lindgren t...@atomide.com [150223 18:43]:
   
   Looks like the address is 0 for Custom Error. Anyways, reverting
  
  yeah, that's because the error comes from l4per2, not l3 :-)
 
 Right so it seems :)
  
   a fix for similar issue found on omap3 so far seems to help, that's
   3d009c8c61f9 (gpio: omap: Fix bad device access with setup_irq()).
  
  if we revert that, we regress omap3, right ?
 
 Yes we saw that getting triggered on omap3/4 before 3d009c8c61f9.
 
 Now looking at the stack trace again, it actually has something:
 
 ...
 [c05999a4] (__irq_svc) from [c0599164] 
 (_raw_spin_unlock_irqrestore+0x34/0x44)
 [c0599164] (_raw_spin_unlock_irqrestore) from [c0027120] 
 (omap_hwmod_idle+0x34/0x44)
 [c0027120] (omap_hwmod_idle) from [c00283f8] (omap_device_idle+0x38/0x78)
 [c00283f8] (omap_device_idle) from [c0028454] 
 (_od_runtime_suspend+0x1c/0x24)
 [c0028454] (_od_runtime_suspend) from [c03b5214] 
 (__rpm_callback+0x2c/0x60)
 [c03b5214] (__rpm_callback) from [c03b5268] (rpm_callback+0x20/0x80)
 [c03b5268] (rpm_callback) from [c03b56b8] (rpm_suspend+0xe8/0x55c)
 [c03b56b8] (rpm_suspend) from [c03b6bdc] (pm_runtime_work+0x74/0xa8)
 [c03b6bdc] (pm_runtime_work) from [c0054608] 
 (process_one_work+0x1b0/0x4a0)
 ...
 
 If it's the gpio-omap, there's probably some confusion still in
 the driver regarding the GPIO bank idle status. Anyways, will look
 more into it tomorrow.

And now I'm seeing the error with 3d009c8c61f9 reverted, so it
does not seem to be that either..

Regards,

Tony
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: New l3-noc error with CPUFREQ_DT built-in with v4.0-rc1

2015-02-23 Thread Felipe Balbi
Hi,

On Mon, Feb 23, 2015 at 05:59:04PM -0800, Tony Lindgren wrote:
 * Tony Lindgren t...@atomide.com [150223 16:09]:
  Hi Nishanth,
  
  Olof told me about a new L3 error happening on omap5-uevm with
  v4.0-rc1:
  
  WARNING: CPU: 0 PID: 0 at drivers/bus/omap_l3_noc.c:147 
  l3_interrupt_handler+0x214/0x340()
  400.ocp:L3 Custom Error: MASTER MPU TARGET L4PER2 (Idle): Data Access 
  in Supervisor mode during Functional access
  ...
  
  I tried bisecting this with no luck, but narrowed it down to
  having CONFIG_CPUFREQ_DT=y causing it, while =m wont' trigger
  it. This got changed by commit 40d1746d2eee (ARM:
  omap2plus_defconfig: use CONFIG_CPUFREQ_DT).
  
  Any ideas?
 
 Hmm so setting CONFIG_CPUFREQ_DT=m in arch/arm/configs/omap2plus_defconfig
 produces the same output with make omap2plus_defconfig as with =y.. So
 CPUFREQ_DT can't be the real cause of the problem.
 
 It's now looking like the l3-noc warning does not get triggered on
 every boot.
 
 It also seems the zImage triggering the error does not trigger the
 error on every boot. To trigger the error, it seems the device needs to
 be powered down for at least 10 or so seconds between the boots.
 So far no luck reproducing the error on v3.19.
 
 The easy way to reproduce is to power down omap5 for at least 10 seconds,
 make omap2lus_defconfig on v4.0-rc1 and boot it.
 
 And so far it looks like next-20150204 works and next-20150209
 failed at once so far. But of course I would not trust anything
 at this point :)

got a log of the failure ? Is it pointing to a device or one of the L4s?

Might be worth to boot with just the bare minimum (UART  timers) and
disable everything else. You might need to build busybox and append that
to the kernel so you don't need to rely on MMC/USB/etc for rootfs.

After that, you could start enabling modules one by one (as modules, not
built-in) and loading them one by one to see which one causes the
failure. Big PITA, I know, but I can't think of any other way to go
about this.

-- 
balbi


signature.asc
Description: Digital signature


[PATCH 03/15] twl4030_charger: use devres for power_supply_register and kzalloc.

2015-02-23 Thread NeilBrown
Final allocations/registrations are now managed by devres.

Signed-off-by: NeilBrown ne...@suse.de
---
 drivers/power/twl4030_charger.c |   23 ++-
 1 file changed, 6 insertions(+), 17 deletions(-)

diff --git a/drivers/power/twl4030_charger.c b/drivers/power/twl4030_charger.c
index 300dd7a34e80..51321f0c5548 100644
--- a/drivers/power/twl4030_charger.c
+++ b/drivers/power/twl4030_charger.c
@@ -565,7 +565,7 @@ static int __init twl4030_bci_probe(struct platform_device 
*pdev)
int ret;
u32 reg;
 
-   bci = kzalloc(sizeof(*bci), GFP_KERNEL);
+   bci = devm_kzalloc(pdev-dev, sizeof(*bci), GFP_KERNEL);
if (bci == NULL)
return -ENOMEM;
 
@@ -580,7 +580,7 @@ static int __init twl4030_bci_probe(struct platform_device 
*pdev)
ret = twl4030_is_battery_present(bci);
if  (ret) {
dev_crit(pdev-dev, Battery was not detected:%d\n, ret);
-   goto fail_no_battery;
+   goto fail;
}
 
platform_set_drvdata(pdev, bci);
@@ -590,10 +590,10 @@ static int __init twl4030_bci_probe(struct 
platform_device *pdev)
bci-ac.num_properties = ARRAY_SIZE(twl4030_charger_props);
bci-ac.get_property = twl4030_bci_get_property;
 
-   ret = power_supply_register(pdev-dev, bci-ac);
+   ret = devm_power_supply_register(pdev-dev, bci-ac);
if (ret) {
dev_err(pdev-dev, failed to register ac: %d\n, ret);
-   goto fail_register_ac;
+   goto fail;
}
 
bci-usb.name = twl4030_usb;
@@ -604,10 +604,10 @@ static int __init twl4030_bci_probe(struct 
platform_device *pdev)
 
bci-usb_reg = regulator_get(bci-dev, bci3v1);
 
-   ret = power_supply_register(pdev-dev, bci-usb);
+   ret = devm_power_supply_register(pdev-dev, bci-usb);
if (ret) {
dev_err(pdev-dev, failed to register usb: %d\n, ret);
-   goto fail_register_usb;
+   goto fail;
}
 
ret = devm_request_threaded_irq(pdev-dev, bci-irq_chg, NULL,
@@ -667,13 +667,6 @@ static int __init twl4030_bci_probe(struct platform_device 
*pdev)
return 0;
 
 fail:
-   power_supply_unregister(bci-usb);
-fail_register_usb:
-   power_supply_unregister(bci-ac);
-fail_register_ac:
-fail_no_battery:
-   kfree(bci);
-
return ret;
 }
 
@@ -691,10 +684,6 @@ static int __exit twl4030_bci_remove(struct 
platform_device *pdev)
twl_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xff,
 TWL4030_INTERRUPTS_BCIIMR2A);
 
-   power_supply_unregister(bci-usb);
-   power_supply_unregister(bci-ac);
-   kfree(bci);
-
return 0;
 }
 


--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 02/15] twl4030_charger: use devm_request_threaded_irq

2015-02-23 Thread NeilBrown
This simplifies the error paths.

Signed-off-by: NeilBrown ne...@suse.de
---
 drivers/power/twl4030_charger.c |   18 ++
 1 file changed, 6 insertions(+), 12 deletions(-)

diff --git a/drivers/power/twl4030_charger.c b/drivers/power/twl4030_charger.c
index 4cf5ffbc904a..300dd7a34e80 100644
--- a/drivers/power/twl4030_charger.c
+++ b/drivers/power/twl4030_charger.c
@@ -610,21 +610,21 @@ static int __init twl4030_bci_probe(struct 
platform_device *pdev)
goto fail_register_usb;
}
 
-   ret = request_threaded_irq(bci-irq_chg, NULL,
+   ret = devm_request_threaded_irq(pdev-dev, bci-irq_chg, NULL,
twl4030_charger_interrupt, IRQF_ONESHOT, pdev-name,
bci);
if (ret  0) {
dev_err(pdev-dev, could not request irq %d, status %d\n,
bci-irq_chg, ret);
-   goto fail_chg_irq;
+   goto fail;
}
 
-   ret = request_threaded_irq(bci-irq_bci, NULL,
+   ret = devm_request_threaded_irq(pdev-dev, bci-irq_bci, NULL,
twl4030_bci_interrupt, IRQF_ONESHOT, pdev-name, bci);
if (ret  0) {
dev_err(pdev-dev, could not request irq %d, status %d\n,
bci-irq_bci, ret);
-   goto fail_bci_irq;
+   goto fail;
}
 
INIT_WORK(bci-work, twl4030_bci_usb_work);
@@ -647,7 +647,7 @@ static int __init twl4030_bci_probe(struct platform_device 
*pdev)
   TWL4030_INTERRUPTS_BCIIMR1A);
if (ret  0) {
dev_err(pdev-dev, failed to unmask interrupts: %d\n, ret);
-   goto fail_unmask_interrupts;
+   goto fail;
}
 
reg = ~(u32)(TWL4030_VBATOV | TWL4030_VBUSOV | TWL4030_ACCHGOV);
@@ -666,11 +666,7 @@ static int __init twl4030_bci_probe(struct platform_device 
*pdev)
 
return 0;
 
-fail_unmask_interrupts:
-   free_irq(bci-irq_bci, bci);
-fail_bci_irq:
-   free_irq(bci-irq_chg, bci);
-fail_chg_irq:
+fail:
power_supply_unregister(bci-usb);
 fail_register_usb:
power_supply_unregister(bci-ac);
@@ -695,8 +691,6 @@ static int __exit twl4030_bci_remove(struct platform_device 
*pdev)
twl_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xff,
 TWL4030_INTERRUPTS_BCIIMR2A);
 
-   free_irq(bci-irq_bci, bci);
-   free_irq(bci-irq_chg, bci);
power_supply_unregister(bci-usb);
power_supply_unregister(bci-ac);
kfree(bci);


--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 01/15] power_supply core: support use of devres to register/unregister a power supply.

2015-02-23 Thread NeilBrown
Using devm_power_supply_register allows the unregister to happen
automatically on error or final put.

Signed-off-by: NeilBrown ne...@suse.de
---
 drivers/power/power_supply_core.c |   45 +
 include/linux/power_supply.h  |4 +++
 2 files changed, 49 insertions(+)

diff --git a/drivers/power/power_supply_core.c 
b/drivers/power/power_supply_core.c
index 694e8cddd5c1..44c810456212 100644
--- a/drivers/power/power_supply_core.c
+++ b/drivers/power/power_supply_core.c
@@ -617,6 +617,51 @@ int power_supply_register_no_ws(struct device *parent, 
struct power_supply *psy)
 }
 EXPORT_SYMBOL_GPL(power_supply_register_no_ws);
 
+static void devm_power_supply_release(struct device *dev, void *res)
+{
+   struct power_supply **psy = res;
+
+   power_supply_unregister(*psy);
+}
+
+int devm_power_supply_register(struct device *parent, struct power_supply *psy)
+{
+   struct power_supply **ptr = devres_alloc(devm_power_supply_release,
+sizeof(*ptr), GFP_KERNEL);
+   int ret;
+
+   if (!ptr)
+   return -ENOMEM;
+   ret = __power_supply_register(parent, psy, true);
+   if (ret  0)
+   devres_free(ptr);
+   else {
+   *ptr = psy;
+   devres_add(parent, ptr);
+   }
+   return ret;
+}
+EXPORT_SYMBOL_GPL(devm_power_supply_register);
+
+int devm_power_supply_register_no_ws(struct device *parent, struct 
power_supply *psy)
+{
+   struct power_supply **ptr = devres_alloc(devm_power_supply_release,
+sizeof(*ptr), GFP_KERNEL);
+   int ret;
+
+   if (!ptr)
+   return -ENOMEM;
+   ret = __power_supply_register(parent, psy, false);
+   if (ret  0)
+   devres_free(ptr);
+   else {
+   *ptr = psy;
+   devres_add(parent, ptr);
+   }
+   return ret;
+}
+EXPORT_SYMBOL_GPL(devm_power_supply_register_no_ws);
+
 void power_supply_unregister(struct power_supply *psy)
 {
cancel_work_sync(psy-changed_work);
diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h
index 096dbced02ac..f606d6b4bd56 100644
--- a/include/linux/power_supply.h
+++ b/include/linux/power_supply.h
@@ -278,6 +278,10 @@ extern int power_supply_register(struct device *parent,
 struct power_supply *psy);
 extern int power_supply_register_no_ws(struct device *parent,
 struct power_supply *psy);
+extern int devm_power_supply_register(struct device *parent,
+struct power_supply *psy);
+extern int devm_power_supply_register_no_ws(struct device *parent,
+struct power_supply *psy);
 extern void power_supply_unregister(struct power_supply *psy);
 extern int power_supply_powers(struct power_supply *psy, struct device *dev);
 


--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html