* [RFC PATCH] ARM: dts: sun8i: add simplefb node for H3
From: Maxime Ripard @ 2016-11-29 21:59 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161128114218.14d2ed434802a20fa6b62023@free.fr>
On Mon, Nov 28, 2016 at 11:42:18AM +0100, Jean-Francois Moine wrote:
> On Mon, 28 Nov 2016 17:59:00 +0800
> Icenowy Zheng <icenowy@aosc.xyz> wrote:
>
> > As there's currently a fork of U-Boot which provides simplefb support
> > for H3, a simplefb node can be added to the device tree.
> >
> > Signed-off-by: Icenowy Zheng <icenowy@aosc.xyz>
> > ---
> >
> > I'm still not sure which pipeline should I use.
> >
> > And, it seems that HDMI Slow Clock is not needed?
> >
> > (seems that it's only for EDID, but simplefb won't use EDID)
>
> So, I don't see how this may work.
> How can the u-boot know the resolutions of the HDMI display device?
>
> In other words: I have a new H3 board with the last u-boot and kernel.
> I plug my (rather old or brand new) HDMI display device.
> After powering on the system, I hope to get something on the screen.
> How?
If it works like the driver for the first display engine in U-Boot, it
will use the preferred mode reported by the EDID, and will fallback to
1024x768 if it cannot access it.
Maybe it would be worth exchanging on the EDID code that has been done
for the u-boot driver too, so that it can be fixed in your driver.
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161129/94d75cc0/attachment-0001.sig>
^ permalink raw reply
* Unable to use perf in VM
From: Itaru Kitayama @ 2016-11-29 22:04 UTC (permalink / raw)
To: linux-arm-kernel
Hi,
In a VM (virsh controlled, KVM acceleration enabled) on a recent
kvmarm kernel host, I find I am unable to use perf to obtain
performance statistics for a complex task like kernel build.
(I've verified this is seen with a Fedora 25 VM and host combination
as well)
APM folks CC'ed think this might be caused by a bug in the core PMU
framework code, thus I'd like to have experts opinion on this issue.
[root at localhost linux]# perf stat -B make
CHK include/config/kernel.release
[ 119.617684] git[1144]: undefined instruction: pc=fffffc000808ff30
[ 119.623040] Code: 51000442 92401042 d51b9ca2 d5033fdf (d53b9d40)
[ 119.627607] Internal error: undefined instruction: 0 [#1] SMP
[ 119.633600] Modules linked in: ip6t_rpfilter ip6t_REJECT
nf_reject_ipv6 xt_conntrack ip_set nfnetlink ebtable_broute bridge stp
llc ebtable_nat ip6table_nat nf_conntrack_ipv6 nf_defrag_ipv6
nf_nat_ipv6 ip6table_raw ip6table_mangle ip6table_security iptable_nat
nf_conntrack_ipv4 nf_defrag_ipv4 nf_nat_ipv4 nf_nat nf_conntrack
iptable_raw iptable_mangle iptable_security ebtable_filter ebtables
ip6table_filter ip6_tables vfat fat chipreg mtd virtio_net qemu_fw_cfg
nfsd auth_rpcgss nfs_acl lockd grace sunrpc xfs libcrc32c virtio_console
virtio_scsi gpio_keys virtio_mmio virtio_ring virtio
[ 119.677249] CPU: 0 PID: 1144 Comm: git Tainted: P 4.8.0 #3
[ 119.682480] Hardware name: QEMU KVM Virtual Machine, BIOS 0.0.0
02/06/2015
[ 119.687660] task: fffffe00ea96cb00 task.stack: fffffe00e6a60000
[ 119.692167] PC is at armv8pmu_read_counter+0x30/0x68
[ 119.695973] LR is at armpmu_event_update+0x34/0x98
[ 119.699615] pc : [<fffffc000808ff30>] lr : [<fffffc00086fe6c4>]
pstate: 800001c5
[ 119.705137] sp : fffffe00e6a63790
[ 119.707663] x29: fffffe00e6a63790 x28: fffffe00f275ca08
[ 119.711875] x27: 0000000000000000 x26: 0000000000000001
[ 119.716097] x25: fffffe00fff22328 x24: 000000001af18c08
[ 119.720345] x23: fffffe00f275ca00 x22: fffffe00ff8d5c00
[ 119.724589] x21: ffffffff87b2b5f5 x20: fffffe00e6a53800
[ 119.728827] x19: fffffe00e6a539c0 x18: 0000000000000000
[ 119.733018] x17: 000003ff8b323c20 x16: 0000000000000000
[ 119.737274] x15: ffffffffffffffff x14: 726573752f656369
[ 119.741395] x13: 6c732e726573752f x12: 0000000000000000
[ 119.745596] x11: 0000000000010000 x10: 0000000000000001
[ 119.749800] x9 : 0000000000000000 x8 : 0000000000000001
[ 119.754042] x7 : 0000000000000000 x6 : 000000d2ea7d1b28
[ 119.758232] x5 : 0000000000000002 x4 : 00000200f7220000
[ 119.762446] x3 : 0000000000000000 x2 : 0000000000000000
[ 119.766655] x1 : fffffc000808ff00 x0 : 0000000000000004
[ 119.770757]
[ 119.771947] Process git (pid: 1144, stack limit = 0xfffffe00e6a60020)
[ 119.776829] Stack: (0xfffffe00e6a63790 to 0xfffffe00e6a64000)
[ 119.781234] 3780: fffffe00e6a637c0
fffffc00086fe790
[ 119.787139] 37a0: fffffe00e6a53800 fffffe00e6a53800 fffffe00ff8d5c00
0000000000000001
[ 119.793007] 37c0: fffffe00e6a637e0 fffffc00086fe7e4 fffffe00fff22210
fffffe00e6a53800
[ 119.798999] 37e0: fffffe00e6a63810 fffffc00081cc260 fffffe00e6a53800
fffffe00e6a53800
[ 119.804893] 3800: fffffe00fff22418 fffffe00fff2241c fffffe00e6a63860
fffffc00081cc404
[ 119.810826] 3820: fffffe00f275ca00 fffffe00e6a53800 fffffe00fff22418
fffffe00fff2241c
[ 119.816766] 3840: fffffe00f275ca00 fffffe00e6a53800 fffffe00fff22328
0000000000000007
[ 119.822690] 3860: fffffe00e6a638b0 fffffc00081cc900 fffffe00f275ca00
fffffe00e6a53800
[ 119.828597] 3880: fffffe00fff22328 fffffe00f275ca58 fffffe00f275ca48
fffffe00ea96d3b0
[ 119.834537] 38a0: fffffc0008d7ba00 fffffe00fff22328 fffffe00e6a638f0
fffffc00081cca00
[ 119.840379] 38c0: fffffc0008cf7000 fffffe00ea96d3a0 fffffc0008d7c2a0
fffffe00f275ca00
[ 119.846291] 38e0: fffffe00ea96cb00 fffffc00081ce554 fffffe00e6a63900
fffffc00081ce560
[ 119.852112] 3900: fffffe00e6a63990 fffffc000884655c fffffc0008d7ba00
fffffe00fff1ad80
[ 119.858904] 3920: fffffc0008d74000 fffffe00ea96cb00 fffffc00088469b0
0000000000000000
[ 119.864738] 3940: fffffe00ea96d108 fffffe00fff1ad80 0000000000000054
fffffe00e44b39a8
[ 119.870551] 3960: fffffc0008d7ba00 fffffe00fff1ad80 fffffc0008d74000
fffffe00ea96cb00
[ 119.876396] 3980: fffffc00088469b0 fffffe00fff1ad80 fffffe00e6a63a00
fffffc00088469b0
[ 119.882286] 39a0: fffffe00e6a60000 fffffc0008846208 fffffe00fff1b698
7fffffffffffffff
[ 119.888225] 39c0: fffffe00e6a63b70 fffffe00f296ca80 fffffdff80387c80
fffffe00f27f3f00
[ 119.894004] 39e0: 0000000000000054 fffffc00083c6dec fffffe00ee7e7e00
00000000ffffffff
[ 119.899745] 3a00: fffffe00e6a63a20 fffffc00088499ec 7fffffffffffffff
fffffc00083c6df8
[ 119.905577] 3a20: fffffe00e6a63ac0 fffffc0008846208 fffffe00fff1ad80
0000000000000000
[ 119.911378] 3a40: fffffe00fff1b698 7fffffffffffffff fffffe00e6a63b70
fffffe00f296ca80
[ 119.917247] 3a60: fffffdff80387c80 fffffe00f27f3f00 fffffe00e6a63aa0
fffffc000818ac7c
[ 119.923206] 3a80: fffffe00ebdb4d00 0000000000000000 fffffe00ffff5a50
7fffffffffffffff
[ 119.929031] 3aa0: fffffe00e6a63ac0 fffffc0008846200 0000000000000000
0000000000000040
[ 119.934854] 3ac0: fffffe00e6a63af0 fffffc0008847270 0000000000000082
fffffe00e6a63b88
[ 119.940671] 3ae0: fffffe00ffff5a50 fffffc0008847250 fffffe00e6a63b10
fffffc0008846e54
[ 119.946549] 3b00: 0000000000000082 fffffc0008847250 fffffe00e6a63b50
fffffc00081dd688
[ 119.952327] 3b20: 000000000000008a 003fffe000010001 fffffe00f27f3f00
fffffe00f2754900
[ 119.958198] 3b40: fffffe00e6a63cd0 fffffe00f296ca80 fffffe00e6a63bb0
fffffc00081ddf4c
[ 119.964079] 3b60: 0000000000000054 fffffdff80387c80 fffffdff80387c80
0000000000000000
[ 119.969913] 3b80: 0000000000000000 0000000000000000 fffffe00ea96cb00
fffffc000810ce90
[ 119.975650] 3ba0: fffffe00ffff5a58 fffffe00ffff5a58 fffffe00e6a63be0
fffffc00081de310
[ 119.981448] 3bc0: 0000000000000009 fffffe00e44b3b20 0000000000000004
fffffe00e44b3b20
[ 119.987351] 3be0: fffffe00e6a63c50 fffffc0000909ec4 fffffe00e6a63d68
fffffe00e44b3840
[ 119.993135] 3c00: fffffe00e44b39a8 fffffe00f296ca80 fffffe00e6a63cd0
0000000000000024
[ 119.998861] 3c20: 0000000000000054 fffffe00f296ca80 fffffe00f27f3f60
0000000000020000
[ 120.004540] 3c40: fffffe00e44b39a8 024000c0f296ca80 fffffe00e6a63c90
fffffc0008211a68
[ 120.010243] 3c60: fffffe00e6a63d68 fffffe00e6a63d60 0000000000000000
0000000000000000
[ 120.015886] 3c80: 0000000000000009 0000000000000040 fffffe00e6a63d00
fffffc00082174e0
[ 120.021599] 3ca0: fffffe00f296ca80 fffffe00f296ca80 0000000000000040
0000000000000009
[ 120.027289] 3cc0: fffffe00e6a63d68 fffffdff80387c40 024200ca00000054
0000000000000009
[ 120.032992] 3ce0: 000003ff7b940000 0000000000000000 0000000000000000
000002aaf1820000
[ 120.038714] 3d00: fffffe00e6a63da0 fffffc000884cd70 fffffe00e6a63ec0
0000000092000007
[ 120.044401] 3d20: fffffe00ea96cb00 000003ff7b940e54 fffffe00f27f3f00
0000000000000024
[ 120.050125] 3d40: 0000000000000054 fffffc00081d21d4 fffffe00e6a63d70
fffffc000821a26c
[ 120.055824] 3d60: 000003ff7b940e54 fffffe00f296ca80 000003ff7b940000
0000000000000054
[ 120.061514] 3d80: fffffe00e6a8ffd8 0000000000000000 0000000000000000
0000000000000000
[ 120.067304] 3da0: fffffe00e6a63e10 fffffc0008081344 fffffc00088900c8
0000000092000007
[ 120.073004] 3dc0: 000003ff7b940e54 fffffe00e6a63ec0 0000000020000000
0000000000000024
[ 120.078732] 3de0: 0000000092000007 000003ff7b940e54 0000000000000014
fffffe00e6a60000
[ 120.084436] 3e00: fffffe00e6a63e30 0000000000000007 0000000000000000
fffffc0008083038
[ 120.090209] 3e20: 0000000000000000 000002aaf17d5700 ffffffffffffffff
000002aacbd75a6c
[ 120.095903] 3e40: fffffe00e6a63e60 fffffc0008114c64 00000000000000d6
0000000000000004
[ 120.101618] 3e60: fffffe00e6a63e80 fffffc000821d310 000002aaf1820000
00000000000000d6
[ 120.107317] 3e80: fffffe00e6a63ea0 fffffc0008088644 0000000000000008
fffffe00e6a63ec0
[ 120.113005] 3ea0: 0000000000000000 fffffc00080832dc 0000000000000000
0000000000000069
[ 120.118725] 3ec0: 0000000000000000 000003ff7b940e54 0000000000000001
000003ff7b8b0008
[ 120.124410] 3ee0: 000003ffcd064400 ffffffff00000000 000002aacbe4718c
000002aacbde3aa8
[ 120.130144] 3f00: fefefeff64647173 0000000000000000 000002aaf17c6550
0101010101010101
[ 120.135836] 3f20: 0000000000000020 ffffffffffffffff ffffffff00000000
ffffffffffffffff
[ 120.141532] 3f40: 000002aacbe3f9e0 000003ff8b323c20 0000000000000000
000002aacbe4718c
[ 120.147249] 3f60: 000002aaf17d5700 000003ffcd064400 00000000000073b7
000002aaf17d5700
[ 120.152939] 3f80: 0000000000009a0f 0000000000004d60 000003ff7b8b0408
0000000000000014
[ 120.158650] 3fa0: 000002aacbe47000 000003ffcd0641a0 000002aacbd75e1c
000003ffcd0641a0
[ 120.164353] 3fc0: 000002aacbd75a6c 0000000020000000 0000000000000000
ffffffffffffffff
[ 120.170063] 3fe0: 0000000000000000 0000000000000000 0000000000000000
0000000000000000
[ 120.175744] Call trace:
[ 120.177588] Exception stack(0xfffffe00e6a63630 to 0xfffffe00e6a63760)
[ 120.182279] 3620: fffffe00e6a539c0
0000040000000000
[ 120.187964] 3640: fffffe00e6a63790 fffffc000808ff30 00000000800001c5
0000000000000080
[ 120.193657] 3660: 0000000000000004 fffffc000808ff00 0000000000000000
0000000000000000
[ 120.199343] 3680: 00000200f7220000 0000000000000002 000000d2ea7d1b28
0000000000000000
[ 120.205011] 36a0: 0000000000000001 0000000000000000 0000000000000001
0000000000010000
[ 120.210698] 36c0: 0000000000000000 6c732e726573752f 726573752f656369
ffffffffffffffff
[ 120.216366] 36e0: 0000000000000000 000003ff8b323c20 0000000000000000
fffffe00e6a539c0
[ 120.222066] 3700: fffffe00e6a53800 ffffffff87b2b5f5 fffffe00ff8d5c00
fffffe00f275ca00
[ 120.227747] 3720: 000000001af18c08 fffffe00fff22328 0000000000000001
0000000000000000
[ 120.233426] 3740: fffffe00f275ca08 fffffe00e6a63790 fffffc00086fe6c4
fffffe00e6a63790
[ 120.239117] [<fffffc000808ff30>] armv8pmu_read_counter+0x30/0x68
[ 120.243497] [<fffffc00086fe790>] armpmu_stop+0x38/0x50
[ 120.247263] [<fffffc00086fe7e4>] armpmu_del+0x3c/0x78
[ 120.250957] [<fffffc00081cc260>] event_sched_out.isra.49+0x140/0x2a0
[ 120.255610] [<fffffc00081cc404>] group_sched_out+0x44/0xc0
[ 120.259622] [<fffffc00081cc900>] ctx_sched_out+0x100/0x1d8
[ 120.263629] [<fffffc00081cca00>] task_ctx_sched_out+0x28/0x58
[ 120.267822] [<fffffc00081ce560>] __perf_event_task_sched_out+0x128/0x368
[ 120.272704] [<fffffc000884655c>] __schedule+0x2ec/0x708
[ 120.276527] [<fffffc00088469b0>] schedule+0x38/0x98
[ 120.280114] [<fffffc00088499ec>] schedule_timeout+0x29c/0x3c0
[ 120.284479] [<fffffc0008846208>] io_schedule_timeout+0xa0/0x108
[ 120.288822] [<fffffc0008847270>] bit_wait_io+0x20/0x70
[ 120.292584] [<fffffc0008846e54>] __wait_on_bit+0xac/0xe8
[ 120.296448] [<fffffc00081dd688>] wait_on_page_bit_killable+0xe0/0xf0
[ 120.301084] [<fffffc00081ddf4c>] __lock_page_or_retry+0xcc/0xf8
[ 120.305416] [<fffffc00081de310>] filemap_fault+0x398/0x548
[ 120.309680] [<fffffc0000909ec4>] xfs_filemap_fault+0x64/0x140 [xfs]
[ 120.314278] [<fffffc0008211a68>] __do_fault+0x78/0x150
[ 120.318045] [<fffffc00082174e0>] handle_mm_fault+0x5d0/0x9c0
[ 120.322171] [<fffffc000884cd70>] do_page_fault+0x2f8/0x3b0
[ 120.326178] [<fffffc0008081344>] do_mem_abort+0x54/0xb0
[ 120.329987] Exception stack(0xfffffe00e6a63e20 to 0xfffffe00e6a63f50)
[ 120.334670] 3e20: 0000000000000000 000002aaf17d5700 ffffffffffffffff
000002aacbd75a6c
[ 120.340351] 3e40: fffffe00e6a63e60 fffffc0008114c64 00000000000000d6
0000000000000004
[ 120.346050] 3e60: fffffe00e6a63e80 fffffc000821d310 000002aaf1820000
00000000000000d6
[ 120.351720] 3e80: fffffe00e6a63ea0 fffffc0008088644 0000000000000008
fffffe00e6a63ec0
[ 120.357387] 3ea0: 0000000000000000 fffffc00080832dc 0000000000000000
0000000000000069
[ 120.363089] 3ec0: 0000000000000000 000003ff7b940e54 0000000000000001
000003ff7b8b0008
[ 120.368760] 3ee0: 000003ffcd064400 ffffffff00000000 000002aacbe4718c
000002aacbde3aa8
[ 120.374561] 3f00: fefefeff64647173 0000000000000000 000002aaf17c6550
0101010101010101
[ 120.380260] 3f20: 0000000000000020 ffffffffffffffff ffffffff00000000
ffffffffffffffff
[ 120.385981] 3f40: 000002aacbe3f9e0 000003ff8b323c20
[ 120.389526] [<fffffc0008083038>] el0_da+0x18/0x1c
[ 120.392978] Code: 51000442 92401042 d51b9ca2 d5033fdf (d53b9d40)
^ permalink raw reply
* [PATCH V8 2/6] thermal: bcm2835: add thermal driver for bcm2835 soc
From: Eric Anholt @ 2016-11-29 22:12 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161129013436.GA3080@localhost.localdomain>
Eduardo Valentin <edubezval@gmail.com> writes:
> Hello Eric, Martin,
>
> On Mon, Nov 28, 2016 at 12:30:38PM -0800, Eric Anholt wrote:
>> Either the device was initialized by the firmware before handing off to
>> ARM (today's firmware) or it never will be (potential future firmware).
>
> And do you have a way to check if the firmware has the initialization
> code or not? By firmware version, for example. Or even, chip version,
> maybe?
We would know if it's not present because the register would be in its
power-on reset state, which is what the code is checking for.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 832 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161129/63bdda2f/attachment.sig>
^ permalink raw reply
* [PATCH RESEND 2/2] gpio: axp209: add pinctrl support
From: Quentin Schulz @ 2016-11-29 22:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CACRpkdb8cej=AMs2kO1Vks-WYeae+CtAW2YOCc+Pz3E49mcrDQ@mail.gmail.com>
Hi Linus,
On 24/11/2016 15:17, Linus Walleij wrote:
> On Wed, Nov 23, 2016 at 3:11 PM, Quentin Schulz
> <quentin.schulz@free-electrons.com> wrote:
>
>> The GPIOs present in the AXP209 PMIC have multiple functions. They
>> typically allow a pin to be used as GPIO input or output and can also be
>> used as ADC or regulator for example.[1]
>>
>> This adds the possibility to use all functions of the GPIOs present in
>> the AXP209 PMIC thanks to pinctrl subsystem.
>>
>> [1] see registers 90H, 92H and 93H at
>> http://dl.linux-sunxi.org/AXP/AXP209_Datasheet_v1.0en.pdf
>>
>> Signed-off-by: Quentin Schulz <quentin.schulz@free-electrons.com>
>
> I need Maxime's review on this patch.
>
>> .../devicetree/bindings/gpio/gpio-axp209.txt | 28 +-
>
> Also move the bindings to pinctrl/pinctrl-axp209.txt
>
>> drivers/gpio/gpio-axp209.c | 551 ++++++++++++++++++---
>
> Combined drivers should be in drivers/pinctrl/*.
>
> Make a separate patch moving the driver to
> drivers/pinctrl/pinctrl-axp209.c (remember -M to git format-patch)
> augment Kconfig and Makefile in both subsystems and make
> these patches on top of that.
>
So basically:
- first patch for adding pinctrl to the existing driver
- second patch for moving the driver and binding from gpio to pinctrl
subsystem
- third patch for both removing Kconfig entry and Makefile rule from
gpio subsystem, and adding a Kconfig entry and a Makefile rule in
pinctrl subsystem
Is that what you want?
Thanks,
Quentin
> I will deal with cross-merging the result between the GPIO
> and pin control trees.
>
> Yours,
> Linus Walleij
>
--
Quentin Schulz, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
^ permalink raw reply
* [PATCH] soc: ti: qmss: fix the case when !SMP
From: Grygorii Strashko @ 2016-11-29 22:15 UTC (permalink / raw)
To: linux-arm-kernel
The irq_set_affinity_hint() will always fail when !SMP and
Networking will fail on Keystone 2 devices in this case.
Hence, fix by ignoring IRQ affinity settings when !SMP.
Cc: Murali Karicheri <m-karicheri2@ti.com>
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
---
drivers/soc/ti/knav_qmss_queue.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/soc/ti/knav_qmss_queue.c b/drivers/soc/ti/knav_qmss_queue.c
index b73e353..3aa0470 100644
--- a/drivers/soc/ti/knav_qmss_queue.c
+++ b/drivers/soc/ti/knav_qmss_queue.c
@@ -1228,7 +1228,7 @@ static int knav_setup_queue_range(struct knav_device *kdev,
range->num_irqs++;
- if (oirq.args_count == 3)
+ if (IS_ENABLED(SMP) && oirq.args_count == 3)
range->irqs[i].cpu_map =
(oirq.args[2] & 0x0000ff00) >> 8;
}
--
2.10.1
^ permalink raw reply related
* [PATCHv4 06/10] xen: Switch to using __pa_symbol
From: Boris Ostrovsky @ 2016-11-29 22:26 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1480445729-27130-7-git-send-email-labbott@redhat.com>
On 11/29/2016 01:55 PM, Laura Abbott wrote:
> __pa_symbol is the correct macro to use on kernel
> symbols. Switch to this from __pa.
>
> Signed-off-by: Laura Abbott <labbott@redhat.com>
> ---
> Found during a sweep of the kernel. Untested.
> ---
> drivers/xen/xenbus/xenbus_dev_backend.c | 2 +-
> drivers/xen/xenfs/xenstored.c | 2 +-
> 2 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/xen/xenbus/xenbus_dev_backend.c b/drivers/xen/xenbus/xenbus_dev_backend.c
> index 4a41ac9..31ca2bf 100644
> --- a/drivers/xen/xenbus/xenbus_dev_backend.c
> +++ b/drivers/xen/xenbus/xenbus_dev_backend.c
> @@ -99,7 +99,7 @@ static int xenbus_backend_mmap(struct file *file, struct vm_area_struct *vma)
> return -EINVAL;
>
> if (remap_pfn_range(vma, vma->vm_start,
> - virt_to_pfn(xen_store_interface),
> + PHYS_PFN(__pa_symbol(xen_store_interface)),
> size, vma->vm_page_prot))
> return -EAGAIN;
>
> diff --git a/drivers/xen/xenfs/xenstored.c b/drivers/xen/xenfs/xenstored.c
> index fef20db..21009ea 100644
> --- a/drivers/xen/xenfs/xenstored.c
> +++ b/drivers/xen/xenfs/xenstored.c
> @@ -38,7 +38,7 @@ static int xsd_kva_mmap(struct file *file, struct vm_area_struct *vma)
> return -EINVAL;
>
> if (remap_pfn_range(vma, vma->vm_start,
> - virt_to_pfn(xen_store_interface),
> + PHYS_PFN(__pa_symbol(xen_store_interface)),
> size, vma->vm_page_prot))
> return -EAGAIN;
>
I suspect this won't work --- xen_store_interface doesn't point to a
kernel symbol.
-boris
^ permalink raw reply
* [PATCHv4 06/10] xen: Switch to using __pa_symbol
From: Laura Abbott @ 2016-11-29 22:42 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <935fefbf-97dc-83fc-b7c3-ba3f19f2087f@oracle.com>
On 11/29/2016 02:26 PM, Boris Ostrovsky wrote:
> On 11/29/2016 01:55 PM, Laura Abbott wrote:
>> __pa_symbol is the correct macro to use on kernel
>> symbols. Switch to this from __pa.
>>
>> Signed-off-by: Laura Abbott <labbott@redhat.com>
>> ---
>> Found during a sweep of the kernel. Untested.
>> ---
>> drivers/xen/xenbus/xenbus_dev_backend.c | 2 +-
>> drivers/xen/xenfs/xenstored.c | 2 +-
>> 2 files changed, 2 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/xen/xenbus/xenbus_dev_backend.c b/drivers/xen/xenbus/xenbus_dev_backend.c
>> index 4a41ac9..31ca2bf 100644
>> --- a/drivers/xen/xenbus/xenbus_dev_backend.c
>> +++ b/drivers/xen/xenbus/xenbus_dev_backend.c
>> @@ -99,7 +99,7 @@ static int xenbus_backend_mmap(struct file *file, struct vm_area_struct *vma)
>> return -EINVAL;
>>
>> if (remap_pfn_range(vma, vma->vm_start,
>> - virt_to_pfn(xen_store_interface),
>> + PHYS_PFN(__pa_symbol(xen_store_interface)),
>> size, vma->vm_page_prot))
>> return -EAGAIN;
>>
>> diff --git a/drivers/xen/xenfs/xenstored.c b/drivers/xen/xenfs/xenstored.c
>> index fef20db..21009ea 100644
>> --- a/drivers/xen/xenfs/xenstored.c
>> +++ b/drivers/xen/xenfs/xenstored.c
>> @@ -38,7 +38,7 @@ static int xsd_kva_mmap(struct file *file, struct vm_area_struct *vma)
>> return -EINVAL;
>>
>> if (remap_pfn_range(vma, vma->vm_start,
>> - virt_to_pfn(xen_store_interface),
>> + PHYS_PFN(__pa_symbol(xen_store_interface)),
>> size, vma->vm_page_prot))
>> return -EAGAIN;
>>
>
>
> I suspect this won't work --- xen_store_interface doesn't point to a
> kernel symbol.
>
> -boris
>
I reviewed this again and yes you are right. I missed that this
was a pointer and not just a symbol so I think this patch can
just be dropped.
Thanks,
Laura
^ permalink raw reply
* [PATCH] arm: add stat support to fiq
From: Oussama Ghorbel @ 2016-11-29 22:48 UTC (permalink / raw)
To: linux-arm-kernel
This patch allows drivers that uses fiq to have a stat on the
execution number of the fiq handler.
For that three APIs has been defined:
- fiq_kstat_enable: this function enables fiq stat and allocates required
memory for it
- fiq_kstat_disable: this function disable fiq stat and free its allocated
memory
- fiq_kstat_this_cpu_inc: This function increments the fiq stat counter of
the current CPU running the fiq handler
A driver may call fiq_kstat_enable at its initialization to enable fiq
stat and then call fiq_kstat_this_cpu_inc from the fiq handler
When the fiq stat is enabled by a driver, then /proc/interrupts shows the
fiq entry as the following example:
FIQ: 0 21642080 0 0 usb_fiq
If the fiq stat is not enabled, the content will be similar to the old one
as the following example:
FIQ: usb_fiq
The fiq name will be always written on the first column after the last CPU
column
Signed-off-by: Oussama Ghorbel <ghorbel@gmail.com>
---
arch/arm/include/asm/fiq.h | 10 ++++++++++
arch/arm/kernel/fiq.c | 31 +++++++++++++++++++++++++++----
2 files changed, 37 insertions(+), 4 deletions(-)
diff --git a/arch/arm/include/asm/fiq.h b/arch/arm/include/asm/fiq.h
index d493d0b..77f819b 100644
--- a/arch/arm/include/asm/fiq.h
+++ b/arch/arm/include/asm/fiq.h
@@ -31,6 +31,8 @@ struct fiq_handler {
/* data for the relinquish/reacquire functions
*/
void *dev_id;
+ /* fiq stats percpu */
+ unsigned int __percpu *fiq_kstat;
};
extern int claim_fiq(struct fiq_handler *f);
@@ -53,4 +55,12 @@ static inline void get_fiq_regs(struct pt_regs *regs)
__get_fiq_regs(®s->ARM_r8);
}
+extern int fiq_kstat_enable(struct fiq_handler *fh);
+extern void fiq_kstat_disable(struct fiq_handler *fh);
+
+static inline void fiq_kstat_this_cpu_inc(struct fiq_handler *fh)
+{
+ __this_cpu_inc(*fh->fiq_kstat);
+}
+
#endif
diff --git a/arch/arm/kernel/fiq.c b/arch/arm/kernel/fiq.c
index 059c3da..4b606df 100644
--- a/arch/arm/kernel/fiq.c
+++ b/arch/arm/kernel/fiq.c
@@ -83,10 +83,19 @@ static struct fiq_handler *current_fiq = &default_owner;
int show_fiq_list(struct seq_file *p, int prec)
{
- if (current_fiq != &default_owner)
- seq_printf(p, "%*s: %s\n", prec, "FIQ",
- current_fiq->name);
-
+ int j;
+
+ if (current_fiq == &default_owner)
+ return 0;
+ seq_printf(p, "%*s: ", prec, "FIQ");
+ for_each_online_cpu(j) {
+ if (current_fiq->fiq_kstat)
+ seq_printf(p, "%10u ",
+ *per_cpu_ptr(current_fiq->fiq_kstat, j));
+ else
+ seq_printf(p, "%10s ", "");
+ }
+ seq_printf(p, " %s\n", current_fiq->name);
return 0;
}
@@ -162,3 +171,17 @@ void __init init_FIQ(int start)
get_fiq_regs(&dfl_fiq_regs);
fiq_start = start;
}
+
+int fiq_kstat_enable(struct fiq_handler *fh)
+{
+ fh->fiq_kstat = alloc_percpu(unsigned int);
+ return fh->fiq_kstat != 0 ? 0 : 1;
+}
+EXPORT_SYMBOL(fiq_kstat_enable);
+
+void fiq_kstat_disable(struct fiq_handler *fh)
+{
+ free_percpu(fh->fiq_kstat);
+ fh->fiq_kstat = NULL;
+}
+EXPORT_SYMBOL(fiq_kstat_disable);
--
2.7.4
^ permalink raw reply related
* [PATCH v7 0/8] drm: sun8i: Add DE2 HDMI video support
From: Laurent Pinchart @ 2016-11-29 22:56 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <8398357e-5c5e-4d76-9022-1c668aff5076@googlegroups.com>
Hi Jernej,
(CC'ing Kieran Bingham)
On Tuesday 29 Nov 2016 14:47:20 Jernej Skrabec wrote:
> Dne torek, 29. november 2016 22.37.03 UTC+1 je oseba Maxime Ripard napisala:
> > On Tue, Nov 29, 2016 at 11:18:35AM +0100, Jean-Francois Moine wrote:
> >> This patchset series adds HDMI video support to the Allwinner
> >> sun8i SoCs which include the display engine 2 (DE2).
> >> The driver contains the code for the A83T and H3 SoCs, and
> >> some H3 boards, but it could be used/extended for other SoCs
> >> (A64, H2, H5) and boards (Banana PIs, Orange PIs).
> >
> > Honestly, I'm getting a bit worried by the fact that you ignore
> > reviews.
> >
> > On the important reviews that you got that are to be seen as major
> >
> > issues that block the inclusion, we have:
> > - The fact that the HDMI driver is actually just a designware IP,
> > and while you should use the driver that already exists, you just
> > duplicated all that code.
>
> That might be hard thing to do. A83T fits perfectly, but H3 and newer SoCs
> do not. They are using completely different HDMI phy. Decoupling controller
> and phy code means rewritting a good portion of the code, unless some tricks
> are applied, like calling phy function pointers, if they are defined.
Same HDMI TX but different HDMI TX PHY ? Kieran is working on decoupling the
PHY configuration code for a Renesas SoC, that might be of interest to you.
> Register addresses also differ, but that can be easily solved by using
> undocumented magic value to restore them.
I love that :-)
> > - The fact that you ignored Rob (v6) and I (v5) comment on using OF
> > graph to model the connection between the display engine and the
> > TCON. Something that Laurent also pointed out in this version.
> >
> > - The fact that you ignored that you needed an HDMI connector node
> > as a child of the HDMI controller. This has been reported by Rob
> > (v6) and yet again in this version by Laurent.
> >
> > - And finally the fact that we can't have several display engine in
> > parallel, if needs be. This has happened in the past already on
> > Allwinner SoCs, so it's definitely something we should consider in
> > the DT bindings, since we can't break them.
> >
> > Until those are fixed, I cannot see how this driver can be merged,
> > unfortunately.
--
Regards,
Laurent Pinchart
^ permalink raw reply
* [PATCH V8 0/3] irqchip: qcom: Add IRQ combiner driver
From: Agustin Vega-Frias @ 2016-11-29 22:57 UTC (permalink / raw)
To: linux-arm-kernel
Add support for IRQ combiners in the Top-level Control and Status
Registers (TCSR) hardware block in Qualcomm Technologies chips.
The first patch adds support for ResourceSource/IRQ domain mapping
when using Extended IRQ Resources with a specific ResourceSource.
The patch prevents the ACPI core from attempting to map IRQ resources
with a valid ResourceSource as GSIs.
The second patch fixes IRQ probe deferral by allowing platform_device
IRQ resources to be re-initialized if the ACPI core failed to find
the IRQ domain during ACPI bus scan.
Both changes described above are conditional on the ACPI_GENERIC_GSI config.
The third patch takes advantage of the new capabilities to implement
the driver for the IRQ combiners.
Tested on top of v4.9-rc7.
Changes V7 -> V8:
* Reorder patches to allow all new code to be under drivers/acpi/irq.c.
* Change acpi_irq_get implementation to be more similar to of_irq_get
to improve maintainability.
Changes V6 -> V7:
* Consolidate changes for ResourceSource/IRQ domain mapping to the same
source file implementing the generic GSI support, making it conditional
on CONFIG_ACPI_GENERIC_GSI.
* Eliminate some code duplication by implementing acpi_register_gsi in
terms of the new acpi_register_irq API.
Changes V5 -> V6:
* Drop probe table and on-demand probing based on resource_source
* Add patch to fix probe deferral
* Change back combiner driver to use the platform_device/platform_driver
APIs
Agustin Vega-Frias (3):
ACPI: Add support for ResourceSource/IRQ domain mapping
ACPI: Retry IRQ conversion if it failed previously
irqchip: qcom: Add IRQ combiner driver
drivers/acpi/Makefile | 2 +-
drivers/acpi/gsi.c | 98 -----------
drivers/acpi/irq.c | 315 +++++++++++++++++++++++++++++++++
drivers/acpi/resource.c | 29 ++--
drivers/base/platform.c | 9 +-
drivers/irqchip/Kconfig | 8 +
drivers/irqchip/Makefile | 1 +
drivers/irqchip/qcom-irq-combiner.c | 337 ++++++++++++++++++++++++++++++++++++
include/linux/acpi.h | 28 +++
9 files changed, 714 insertions(+), 113 deletions(-)
delete mode 100644 drivers/acpi/gsi.c
create mode 100644 drivers/acpi/irq.c
create mode 100644 drivers/irqchip/qcom-irq-combiner.c
--
Qualcomm Datacenter Technologies, Inc. on behalf of the Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.
^ permalink raw reply
* [PATCH V8 1/3] ACPI: Add support for ResourceSource/IRQ domain mapping
From: Agustin Vega-Frias @ 2016-11-29 22:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1480460259-8585-1-git-send-email-agustinv@codeaurora.org>
When an Extended IRQ Resource contains a valid ResourceSource
use it to map the IRQ on the domain associated with the ACPI
device referenced.
With this in place an irqchip driver can create its domain using
irq_domain_create_linear and pass the device fwnode to create
the domain mapping. When dependent devices are probed these
changes allow the ACPI core find the domain and map the IRQ.
Signed-off-by: Agustin Vega-Frias <agustinv@codeaurora.org>
---
drivers/acpi/Makefile | 2 +-
drivers/acpi/{gsi.c => irq.c} | 99 +++++++++++++++++++++++++++++++++++++------
drivers/acpi/resource.c | 29 +++++++------
include/linux/acpi.h | 19 +++++++++
4 files changed, 122 insertions(+), 27 deletions(-)
rename drivers/acpi/{gsi.c => irq.c} (52%)
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index 9ed0878..a391bbc 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -55,7 +55,7 @@ acpi-$(CONFIG_DEBUG_FS) += debugfs.o
acpi-$(CONFIG_ACPI_NUMA) += numa.o
acpi-$(CONFIG_ACPI_PROCFS_POWER) += cm_sbs.o
acpi-y += acpi_lpat.o
-acpi-$(CONFIG_ACPI_GENERIC_GSI) += gsi.o
+acpi-$(CONFIG_ACPI_GENERIC_GSI) += irq.o
acpi-$(CONFIG_ACPI_WATCHDOG) += acpi_watchdog.o
# These are (potentially) separate modules
diff --git a/drivers/acpi/gsi.c b/drivers/acpi/irq.c
similarity index 52%
rename from drivers/acpi/gsi.c
rename to drivers/acpi/irq.c
index ee9e0f2..e82eb6e 100644
--- a/drivers/acpi/gsi.c
+++ b/drivers/acpi/irq.c
@@ -18,6 +18,45 @@
static struct fwnode_handle *acpi_gsi_domain_id;
/**
+ * acpi_get_irq_source_fwhandle() - Retrieve the fwhandle of the given
+ * acpi_resource_source which is used
+ * to be used as an IRQ domain id
+ * @source: acpi_resource_source to use for the lookup
+ *
+ * Returns: The appropriate IRQ fwhandle domain id
+ * NULL on failure
+ */
+struct fwnode_handle *
+acpi_get_irq_source_fwhandle(const struct acpi_resource_source *source)
+{
+ struct fwnode_handle *result;
+ struct acpi_device *device;
+ acpi_handle handle;
+ acpi_status status;
+
+ if (!source->string_length)
+ return acpi_gsi_domain_id;
+
+ status = acpi_get_handle(NULL, source->string_ptr, &handle);
+ if (ACPI_FAILURE(status)) {
+ pr_warn("Could not find handle for %s\n", source->string_ptr);
+ return NULL;
+ }
+
+ device = acpi_bus_get_acpi_device(handle);
+ if (!device) {
+ pr_warn("Could not get device for %s\n", source->string_ptr);
+ return NULL;
+ }
+
+ result = &device->fwnode;
+ acpi_bus_put_acpi_device(device);
+
+ return result;
+}
+EXPORT_SYMBOL_GPL(acpi_get_irq_source_fwhandle);
+
+/**
* acpi_gsi_to_irq() - Retrieve the linux irq number for a given GSI
* @gsi: GSI IRQ number to map
* @irq: pointer where linux IRQ number is stored
@@ -42,6 +81,51 @@ int acpi_gsi_to_irq(u32 gsi, unsigned int *irq)
EXPORT_SYMBOL_GPL(acpi_gsi_to_irq);
/**
+ * acpi_register_irq() - Map a hardware to a linux IRQ number
+ * @source: IRQ source
+ * @hwirq: Hardware IRQ number
+ * @trigger: trigger type of the IRQ number to be mapped
+ * @polarity: polarity of the IRQ to be mapped
+ *
+ * Returns: a valid linux IRQ number on success
+ * -EINVAL on failure
+ * -EPROBE_DEFER if the IRQ domain lookup failed
+ */
+int acpi_register_irq(struct fwnode_handle *source, u32 hwirq, int trigger,
+ int polarity)
+{
+ struct irq_fwspec fwspec;
+
+ if (!source)
+ source = acpi_gsi_domain_id;
+
+ if (irq_find_matching_fwnode(source, DOMAIN_BUS_ANY) == NULL)
+ return -EPROBE_DEFER;
+
+ fwspec.fwnode = source;
+ fwspec.param[0] = hwirq;
+ fwspec.param[1] = acpi_dev_get_irq_type(trigger, polarity);
+ fwspec.param_count = 2;
+
+ return irq_create_fwspec_mapping(&fwspec);
+}
+EXPORT_SYMBOL_GPL(acpi_register_irq);
+
+/**
+ * acpi_unregister_irq() - Free a Hardware IRQ<->linux IRQ number mapping
+ * @hwirq: Hardware IRQ number
+ */
+void acpi_unregister_irq(struct fwnode_handle *source, u32 hwirq)
+{
+ struct irq_domain *d = irq_find_matching_fwnode(source,
+ DOMAIN_BUS_ANY);
+ int irq = irq_find_mapping(d, hwirq);
+
+ irq_dispose_mapping(irq);
+}
+EXPORT_SYMBOL_GPL(acpi_unregister_irq);
+
+/**
* acpi_register_gsi() - Map a GSI to a linux IRQ number
* @dev: device for which IRQ has to be mapped
* @gsi: GSI IRQ number
@@ -54,19 +138,12 @@ int acpi_gsi_to_irq(u32 gsi, unsigned int *irq)
int acpi_register_gsi(struct device *dev, u32 gsi, int trigger,
int polarity)
{
- struct irq_fwspec fwspec;
-
if (WARN_ON(!acpi_gsi_domain_id)) {
pr_warn("GSI: No registered irqchip, giving up\n");
return -EINVAL;
}
- fwspec.fwnode = acpi_gsi_domain_id;
- fwspec.param[0] = gsi;
- fwspec.param[1] = acpi_dev_get_irq_type(trigger, polarity);
- fwspec.param_count = 2;
-
- return irq_create_fwspec_mapping(&fwspec);
+ return acpi_register_irq(acpi_gsi_domain_id, gsi, trigger, polarity);
}
EXPORT_SYMBOL_GPL(acpi_register_gsi);
@@ -76,11 +153,7 @@ int acpi_register_gsi(struct device *dev, u32 gsi, int trigger,
*/
void acpi_unregister_gsi(u32 gsi)
{
- struct irq_domain *d = irq_find_matching_fwnode(acpi_gsi_domain_id,
- DOMAIN_BUS_ANY);
- int irq = irq_find_mapping(d, gsi);
-
- irq_dispose_mapping(irq);
+ acpi_unregister_irq(acpi_gsi_domain_id, gsi);
}
EXPORT_SYMBOL_GPL(acpi_unregister_gsi);
diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c
index 56241eb..98b94eb 100644
--- a/drivers/acpi/resource.c
+++ b/drivers/acpi/resource.c
@@ -374,21 +374,22 @@ unsigned int acpi_dev_get_irq_type(int triggering, int polarity)
}
EXPORT_SYMBOL_GPL(acpi_dev_get_irq_type);
-static void acpi_dev_irqresource_disabled(struct resource *res, u32 gsi)
+static void acpi_dev_irqresource_disabled(struct resource *res, u32 hwirq)
{
- res->start = gsi;
- res->end = gsi;
+ res->start = hwirq;
+ res->end = hwirq;
res->flags = IORESOURCE_IRQ | IORESOURCE_DISABLED | IORESOURCE_UNSET;
}
-static void acpi_dev_get_irqresource(struct resource *res, u32 gsi,
+static void acpi_dev_get_irqresource(struct resource *res, u32 hwirq,
+ struct fwnode_handle *source,
u8 triggering, u8 polarity, u8 shareable,
bool legacy)
{
int irq, p, t;
- if (!valid_IRQ(gsi)) {
- acpi_dev_irqresource_disabled(res, gsi);
+ if (!source && !valid_IRQ(hwirq)) {
+ acpi_dev_irqresource_disabled(res, hwirq);
return;
}
@@ -402,25 +403,25 @@ static void acpi_dev_get_irqresource(struct resource *res, u32 gsi,
* using extended IRQ descriptors we take the IRQ configuration
* from _CRS directly.
*/
- if (legacy && !acpi_get_override_irq(gsi, &t, &p)) {
+ if (legacy && !acpi_get_override_irq(hwirq, &t, &p)) {
u8 trig = t ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE;
u8 pol = p ? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH;
if (triggering != trig || polarity != pol) {
- pr_warning("ACPI: IRQ %d override to %s, %s\n", gsi,
- t ? "level" : "edge", p ? "low" : "high");
+ pr_warn("ACPI: IRQ %d override to %s, %s\n", hwirq,
+ t ? "level" : "edge", p ? "low" : "high");
triggering = trig;
polarity = pol;
}
}
res->flags = acpi_dev_irq_flags(triggering, polarity, shareable);
- irq = acpi_register_gsi(NULL, gsi, triggering, polarity);
+ irq = acpi_register_irq(source, hwirq, triggering, polarity);
if (irq >= 0) {
res->start = irq;
res->end = irq;
} else {
- acpi_dev_irqresource_disabled(res, gsi);
+ acpi_dev_irqresource_disabled(res, hwirq);
}
}
@@ -448,6 +449,7 @@ bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index,
{
struct acpi_resource_irq *irq;
struct acpi_resource_extended_irq *ext_irq;
+ struct fwnode_handle *src;
switch (ares->type) {
case ACPI_RESOURCE_TYPE_IRQ:
@@ -460,7 +462,7 @@ bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index,
acpi_dev_irqresource_disabled(res, 0);
return false;
}
- acpi_dev_get_irqresource(res, irq->interrupts[index],
+ acpi_dev_get_irqresource(res, irq->interrupts[index], NULL,
irq->triggering, irq->polarity,
irq->sharable, true);
break;
@@ -470,7 +472,8 @@ bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index,
acpi_dev_irqresource_disabled(res, 0);
return false;
}
- acpi_dev_get_irqresource(res, ext_irq->interrupts[index],
+ src = acpi_get_irq_source_fwhandle(&ext_irq->resource_source);
+ acpi_dev_get_irqresource(res, ext_irq->interrupts[index], src,
ext_irq->triggering, ext_irq->polarity,
ext_irq->sharable, false);
break;
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 61a3d90..154e576 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -321,6 +321,25 @@ void acpi_set_irq_model(enum acpi_irq_model_id model,
*/
void acpi_unregister_gsi (u32 gsi);
+#ifdef CONFIG_ACPI_GENERIC_GSI
+struct fwnode_handle *
+acpi_get_irq_source_fwhandle(const struct acpi_resource_source *source);
+int acpi_register_irq(struct fwnode_handle *source, u32 hwirq, int trigger,
+ int polarity);
+void acpi_unregister_irq(struct fwnode_handle *source, u32 hwirq);
+#else
+#define acpi_get_irq_source_fwhandle(source) (NULL)
+static inline int acpi_register_irq(struct fwnode_handle *source, u32 hwirq,
+ int trigger, int polarity)
+{
+ return acpi_register_gsi(NULL, hwirq, trigger, polarity);
+}
+static inline void acpi_unregister_irq(struct fwnode_handle *source, u32 hwirq)
+{
+ acpi_unregister_gsi(hwirq);
+}
+#endif
+
struct pci_dev;
int acpi_pci_irq_enable (struct pci_dev *dev);
--
Qualcomm Datacenter Technologies, Inc. on behalf of the Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.
^ permalink raw reply related
* [PATCH V8 2/3] ACPI: Retry IRQ conversion if it failed previously
From: Agustin Vega-Frias @ 2016-11-29 22:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1480460259-8585-1-git-send-email-agustinv@codeaurora.org>
This allows probe deferral to work properly when a dependent device
fails to get a valid IRQ because the IRQ domain was not registered
at the time the resources were added to the platform_device.
Signed-off-by: Agustin Vega-Frias <agustinv@codeaurora.org>
---
drivers/acpi/irq.c | 144 ++++++++++++++++++++++++++++++++++++++++++++++++
drivers/base/platform.c | 9 ++-
include/linux/acpi.h | 9 +++
3 files changed, 161 insertions(+), 1 deletion(-)
diff --git a/drivers/acpi/irq.c b/drivers/acpi/irq.c
index e82eb6e..9279168 100644
--- a/drivers/acpi/irq.c
+++ b/drivers/acpi/irq.c
@@ -158,6 +158,150 @@ void acpi_unregister_gsi(u32 gsi)
EXPORT_SYMBOL_GPL(acpi_unregister_gsi);
/**
+ * Context for the resource walk used to lookup IRQ resources.
+ */
+struct acpi_irq_parse_one_ctx {
+ int rc;
+ unsigned int index;
+ unsigned long *res_flags;
+ struct irq_fwspec *fwspec;
+};
+
+/**
+ * acpi_irq_parse_one_match - Handle a matching IRQ resource
+ */
+static inline void acpi_irq_parse_one_match(struct fwnode_handle *fwnode,
+ u32 hwirq, u8 triggering,
+ u8 polarity, u8 shareable,
+ struct acpi_irq_parse_one_ctx *ctx)
+{
+ ctx->rc = 0;
+ *ctx->res_flags = acpi_dev_irq_flags(triggering, polarity, shareable);
+ ctx->fwspec->fwnode = fwnode;
+ ctx->fwspec->param[0] = hwirq;
+ ctx->fwspec->param[1] = acpi_dev_get_irq_type(triggering, polarity);
+ ctx->fwspec->param_count = 2;
+}
+
+/**
+ * acpi_irq_parse_one_cb - Handle the given resource
+ * @ares: resource to handle
+ * @context: context for the walk, contains the lookup index and references
+ * to the flags and fwspec where the result is returned
+ *
+ * This is called by acpi_walk_resources passing each resource returned by
+ * the _CRS method. We only inspect IRQ resources. Since IRQ resources
+ * might contain multiple interrupts we check if the index is within this
+ * one's interrupt array, otherwise we subtract the current resource IRQ
+ * count from the lookup index to prepare for the next resource.
+ * Once a match is found we call acpi_irq_parse_one_match to populate
+ * the result and end the walk by returning AE_CTRL_TERMINATE.
+ *
+ * Return AE_OK if the walk should continue, AE_CTRL_TERMINATE if a matching
+ * IRQ resource was found.
+ */
+static acpi_status acpi_irq_parse_one_cb(struct acpi_resource *ares,
+ void *context)
+{
+ struct acpi_irq_parse_one_ctx *ctx = context;
+ struct acpi_resource_irq *irq;
+ struct acpi_resource_extended_irq *eirq;
+ struct fwnode_handle *fwnode;
+
+ switch (ares->type) {
+ case ACPI_RESOURCE_TYPE_IRQ:
+ irq = &ares->data.irq;
+ if (ctx->index >= irq->interrupt_count) {
+ ctx->index -= irq->interrupt_count;
+ return AE_OK;
+ }
+ fwnode = acpi_gsi_domain_id;
+ acpi_irq_parse_one_match(fwnode, irq->interrupts[ctx->index],
+ irq->triggering, irq->polarity,
+ irq->sharable, ctx);
+ return AE_CTRL_TERMINATE;
+ case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
+ eirq = &ares->data.extended_irq;
+ if (ctx->index >= eirq->interrupt_count) {
+ ctx->index -= eirq->interrupt_count;
+ return AE_OK;
+ }
+ fwnode = acpi_get_irq_source_fwhandle(&eirq->resource_source);
+ acpi_irq_parse_one_match(fwnode, eirq->interrupts[ctx->index],
+ eirq->triggering, eirq->polarity,
+ eirq->sharable, ctx);
+ return AE_CTRL_TERMINATE;
+ }
+
+ return AE_OK;
+}
+
+/**
+ * acpi_irq_parse_one - Resolve an interrupt for a device
+ * @handle: the device whose interrupt is to be resolved
+ * @index: index of the interrupt to resolve
+ * @fwspec: structure irq_fwspec filled by this function
+ * @flags: resource flags filled by this function
+ *
+ * This function resolves an interrupt for a device by walking its CRS resources
+ * to find the appropriate ACPI IRQ resource and populating the given structure
+ * which can be used to retrieve a Linux IRQ number.
+ *
+ * Returns the result stored in ctx.rc by the callback, or -EINVAL if the given
+ * index is out of range.
+ */
+static int acpi_irq_parse_one(acpi_handle handle, unsigned int index,
+ struct irq_fwspec *fwspec, unsigned long *flags)
+{
+ struct acpi_irq_parse_one_ctx ctx = { -EINVAL, index, flags, fwspec };
+ acpi_status status;
+
+ status = acpi_walk_resources(handle, METHOD_NAME__CRS,
+ acpi_irq_parse_one_cb, &ctx);
+ if (ACPI_FAILURE(status))
+ return -EINVAL;
+ return ctx.rc;
+}
+
+/**
+ * acpi_irq_get - Look for the ACPI IRQ resource with the given index and
+ * use it to initialize the given Linux IRQ resource.
+ * @handle ACPI device handle
+ * @index ACPI IRQ resource index to lookup
+ * @res Linux IRQ resource to initialize
+ *
+ * Return: 0 on success
+ * -EINVAL if an error occurs
+ * -EPROBE_DEFER if the IRQ lookup/conversion failed
+ */
+int acpi_irq_get(acpi_handle handle, unsigned int index, struct resource *res)
+{
+ int rc;
+ struct irq_fwspec fwspec;
+ struct irq_domain *domain;
+ unsigned long flags;
+
+ rc = acpi_irq_parse_one(handle, index, &fwspec, &flags);
+ if (rc)
+ return rc;
+
+ domain = irq_find_matching_fwnode(fwspec.fwnode, DOMAIN_BUS_ANY);
+ if (!domain)
+ return -EPROBE_DEFER;
+
+ rc = irq_create_fwspec_mapping(&fwspec);
+ if (rc <= 0)
+ return -EINVAL;
+
+ res->start = rc;
+ res->end = rc;
+ res->flags = flags;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(acpi_irq_get);
+
+/**
* acpi_set_irq_model - Setup the GSI irqdomain information
* @model: the value assigned to acpi_irq_model
* @fwnode: the irq_domain identifier for mapping and looking up
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index c4af003..61423d2 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -102,6 +102,14 @@ int platform_get_irq(struct platform_device *dev, unsigned int num)
}
r = platform_get_resource(dev, IORESOURCE_IRQ, num);
+ if (r && r->flags & IORESOURCE_DISABLED && ACPI_COMPANION(&dev->dev)) {
+ int ret;
+
+ ret = acpi_irq_get(ACPI_HANDLE(&dev->dev), num, r);
+ if (ret)
+ return ret;
+ }
+
/*
* The resources may pass trigger flags to the irqs that need
* to be set up. It so happens that the trigger flags for
@@ -1450,4 +1458,3 @@ void __init early_platform_cleanup(void)
memset(&pd->dev.devres_head, 0, sizeof(pd->dev.devres_head));
}
}
-
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 154e576..6919bfd 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -327,6 +327,7 @@ struct fwnode_handle *
int acpi_register_irq(struct fwnode_handle *source, u32 hwirq, int trigger,
int polarity);
void acpi_unregister_irq(struct fwnode_handle *source, u32 hwirq);
+int acpi_irq_get(acpi_handle handle, unsigned int index, struct resource *res);
#else
#define acpi_get_irq_source_fwhandle(source) (NULL)
static inline int acpi_register_irq(struct fwnode_handle *source, u32 hwirq,
@@ -785,6 +786,14 @@ static inline int acpi_reconfig_notifier_unregister(struct notifier_block *nb)
#endif /* !CONFIG_ACPI */
+#ifndef CONFIG_ACPI_GENERIC_GSI
+static inline int acpi_irq_get(acpi_handle handle, unsigned int index,
+ struct resource *res)
+{
+ return -EINVAL;
+}
+#endif /* CONFIG_ACPI_GENERIC_GSI */
+
#ifdef CONFIG_ACPI_HOTPLUG_IOAPIC
int acpi_ioapic_add(acpi_handle root);
#else
--
Qualcomm Datacenter Technologies, Inc. on behalf of the Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.
^ permalink raw reply related
* [PATCH V8 3/3] irqchip: qcom: Add IRQ combiner driver
From: Agustin Vega-Frias @ 2016-11-29 22:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1480460259-8585-1-git-send-email-agustinv@codeaurora.org>
Driver for interrupt combiners in the Top-level Control and Status
Registers (TCSR) hardware block in Qualcomm Technologies chips.
An interrupt combiner in this block combines a set of interrupts by
OR'ing the individual interrupt signals into a summary interrupt
signal routed to a parent interrupt controller, and provides read-
only, 32-bit registers to query the status of individual interrupts.
The status bit for IRQ n is bit (n % 32) within register (n / 32)
of the given combiner. Thus, each combiner can be described as a set
of register offsets and the number of IRQs managed.
Signed-off-by: Agustin Vega-Frias <agustinv@codeaurora.org>
---
drivers/irqchip/Kconfig | 8 +
drivers/irqchip/Makefile | 1 +
drivers/irqchip/qcom-irq-combiner.c | 337 ++++++++++++++++++++++++++++++++++++
3 files changed, 346 insertions(+)
create mode 100644 drivers/irqchip/qcom-irq-combiner.c
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index bc0af33..610f902 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -279,3 +279,11 @@ config EZNPS_GIC
config STM32_EXTI
bool
select IRQ_DOMAIN
+
+config QCOM_IRQ_COMBINER
+ bool "QCOM IRQ combiner support"
+ depends on ARCH_QCOM
+ select IRQ_DOMAIN
+ help
+ Say yes here to add support for the IRQ combiner devices embedded
+ in Qualcomm Technologies chips.
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index e4dbfc8..1818a0b 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -74,3 +74,4 @@ obj-$(CONFIG_LS_SCFG_MSI) += irq-ls-scfg-msi.o
obj-$(CONFIG_EZNPS_GIC) += irq-eznps.o
obj-$(CONFIG_ARCH_ASPEED) += irq-aspeed-vic.o
obj-$(CONFIG_STM32_EXTI) += irq-stm32-exti.o
+obj-$(CONFIG_QCOM_IRQ_COMBINER) += qcom-irq-combiner.o
diff --git a/drivers/irqchip/qcom-irq-combiner.c b/drivers/irqchip/qcom-irq-combiner.c
new file mode 100644
index 0000000..fc25251
--- /dev/null
+++ b/drivers/irqchip/qcom-irq-combiner.c
@@ -0,0 +1,337 @@
+/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/*
+ * Driver for interrupt combiners in the Top-level Control and Status
+ * Registers (TCSR) hardware block in Qualcomm Technologies chips.
+ * An interrupt combiner in this block combines a set of interrupts by
+ * OR'ing the individual interrupt signals into a summary interrupt
+ * signal routed to a parent interrupt controller, and provides read-
+ * only, 32-bit registers to query the status of individual interrupts.
+ * The status bit for IRQ n is bit (n % 32) within register (n / 32)
+ * of the given combiner. Thus, each combiner can be described as a set
+ * of register offsets and the number of IRQs managed.
+ */
+
+#include <linux/acpi.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/irqdomain.h>
+#include <linux/platform_device.h>
+
+#define REG_SIZE 32
+
+struct combiner_reg {
+ void __iomem *addr;
+ unsigned long mask;
+};
+
+struct combiner {
+ struct irq_chip irq_chip;
+ struct irq_domain *domain;
+ int parent_irq;
+ u32 nirqs;
+ u32 nregs;
+ struct combiner_reg regs[0];
+};
+
+static inline u32 irq_register(int irq)
+{
+ return irq / REG_SIZE;
+}
+
+static inline u32 irq_bit(int irq)
+{
+ return irq % REG_SIZE;
+
+}
+
+static inline int irq_nr(u32 reg, u32 bit)
+{
+ return reg * REG_SIZE + bit;
+}
+
+/*
+ * Handler for the cascaded IRQ.
+ */
+static void combiner_handle_irq(struct irq_desc *desc)
+{
+ struct combiner *combiner = irq_desc_get_handler_data(desc);
+ struct irq_chip *chip = irq_desc_get_chip(desc);
+ u32 reg;
+
+ chained_irq_enter(chip, desc);
+
+ for (reg = 0; reg < combiner->nregs; reg++) {
+ int virq;
+ int hwirq;
+ u32 bit;
+ u32 status;
+
+ if (combiner->regs[reg].mask == 0)
+ continue;
+
+ status = readl_relaxed(combiner->regs[reg].addr);
+ status &= combiner->regs[reg].mask;
+
+ while (status) {
+ bit = __ffs(status);
+ status &= ~(1 << bit);
+ hwirq = irq_nr(reg, bit);
+ virq = irq_find_mapping(combiner->domain, hwirq);
+ if (virq >= 0)
+ generic_handle_irq(virq);
+
+ }
+ }
+
+ chained_irq_exit(chip, desc);
+}
+
+/*
+ * irqchip callbacks
+ */
+
+static void combiner_irq_chip_mask_irq(struct irq_data *data)
+{
+ struct combiner *combiner = irq_data_get_irq_chip_data(data);
+ struct combiner_reg *reg = combiner->regs + irq_register(data->hwirq);
+
+ clear_bit(irq_bit(data->hwirq), ®->mask);
+}
+
+static void combiner_irq_chip_unmask_irq(struct irq_data *data)
+{
+ struct combiner *combiner = irq_data_get_irq_chip_data(data);
+ struct combiner_reg *reg = combiner->regs + irq_register(data->hwirq);
+
+ set_bit(irq_bit(data->hwirq), ®->mask);
+}
+
+/*
+ * irq_domain_ops callbacks
+ */
+
+static int combiner_irq_map(struct irq_domain *domain, unsigned int irq,
+ irq_hw_number_t hwirq)
+{
+ struct combiner *combiner = domain->host_data;
+
+ if (hwirq >= combiner->nirqs)
+ return -EINVAL;
+
+ irq_set_chip_and_handler(irq, &combiner->irq_chip, handle_level_irq);
+ irq_set_chip_data(irq, combiner);
+ irq_set_parent(irq, combiner->parent_irq);
+ irq_set_noprobe(irq);
+ return 0;
+}
+
+static void combiner_irq_unmap(struct irq_domain *domain, unsigned int irq)
+{
+ irq_set_chip_and_handler(irq, NULL, NULL);
+ irq_set_chip_data(irq, NULL);
+ irq_set_parent(irq, -1);
+}
+
+#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
+static int combiner_irq_translate(struct irq_domain *d, struct irq_fwspec *fws,
+ unsigned long *hwirq, unsigned int *type)
+{
+ if (is_acpi_node(fws->fwnode)) {
+ if (fws->param_count != 2)
+ return -EINVAL;
+
+ *hwirq = fws->param[0];
+ *type = fws->param[1];
+ return 0;
+ }
+
+ return -EINVAL;
+}
+#endif
+
+static const struct irq_domain_ops domain_ops = {
+ .map = combiner_irq_map,
+ .unmap = combiner_irq_unmap,
+#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
+ .translate = combiner_irq_translate
+#endif
+};
+
+/*
+ * Device probing
+ */
+
+#ifdef CONFIG_ACPI
+
+static acpi_status count_registers_cb(struct acpi_resource *ares, void *context)
+{
+ int *count = context;
+
+ if (ares->type == ACPI_RESOURCE_TYPE_GENERIC_REGISTER)
+ ++(*count);
+ return AE_OK;
+}
+
+static int count_registers(struct platform_device *pdev)
+{
+ struct acpi_device *adev = ACPI_COMPANION(&pdev->dev);
+ acpi_status status;
+ int count = 0;
+
+ if (!acpi_has_method(adev->handle, METHOD_NAME__CRS))
+ return -EINVAL;
+
+ status = acpi_walk_resources(adev->handle, METHOD_NAME__CRS,
+ count_registers_cb, &count);
+ if (ACPI_FAILURE(status))
+ return -EINVAL;
+ return count;
+}
+
+struct get_registers_context {
+ struct device *dev;
+ struct combiner *combiner;
+ int err;
+};
+
+static acpi_status get_registers_cb(struct acpi_resource *ares, void *context)
+{
+ struct get_registers_context *ctx = context;
+ struct acpi_resource_generic_register *reg;
+ phys_addr_t paddr;
+ void __iomem *vaddr;
+
+ if (ares->type != ACPI_RESOURCE_TYPE_GENERIC_REGISTER)
+ return AE_OK;
+
+ reg = &ares->data.generic_reg;
+ paddr = reg->address;
+ if ((reg->space_id != ACPI_SPACE_MEM) ||
+ (reg->bit_offset != 0) ||
+ (reg->bit_width > REG_SIZE)) {
+ dev_err(ctx->dev, "Bad register resource @%pa\n", &paddr);
+ ctx->err = -EINVAL;
+ return AE_ERROR;
+ }
+
+ vaddr = devm_ioremap(ctx->dev, reg->address, REG_SIZE);
+ if (IS_ERR(vaddr)) {
+ dev_err(ctx->dev, "Can't map register @%pa\n", &paddr);
+ ctx->err = PTR_ERR(vaddr);
+ return AE_ERROR;
+ }
+
+ ctx->combiner->regs[ctx->combiner->nregs].addr = vaddr;
+ ctx->combiner->nirqs += reg->bit_width;
+ ctx->combiner->nregs++;
+ return AE_OK;
+}
+
+static int get_registers(struct platform_device *pdev, struct combiner *comb)
+{
+ struct acpi_device *adev = ACPI_COMPANION(&pdev->dev);
+ acpi_status status;
+ struct get_registers_context ctx;
+
+ if (!acpi_has_method(adev->handle, METHOD_NAME__CRS))
+ return -EINVAL;
+
+ ctx.dev = &pdev->dev;
+ ctx.combiner = comb;
+ ctx.err = 0;
+
+ status = acpi_walk_resources(adev->handle, METHOD_NAME__CRS,
+ get_registers_cb, &ctx);
+ if (ACPI_FAILURE(status))
+ return ctx.err;
+ return 0;
+}
+
+#else /* !CONFIG_ACPI */
+
+static int count_registers(struct platform_device *pdev)
+{
+ return -EINVAL;
+}
+
+static int get_registers(struct platform_device *pdev, struct combiner *comb)
+{
+ return -EINVAL;
+}
+
+#endif
+
+static int __init combiner_probe(struct platform_device *pdev)
+{
+ struct combiner *combiner;
+ size_t alloc_sz;
+ u32 nregs;
+ int err;
+
+ nregs = count_registers(pdev);
+ if (nregs <= 0) {
+ dev_err(&pdev->dev, "Error reading register resources\n");
+ return -EINVAL;
+ }
+
+ alloc_sz = sizeof(*combiner) + sizeof(struct combiner_reg) * nregs;
+ combiner = devm_kzalloc(&pdev->dev, alloc_sz, GFP_KERNEL);
+ if (!combiner)
+ return -ENOMEM;
+
+ err = get_registers(pdev, combiner);
+ if (err < 0)
+ return err;
+
+ combiner->parent_irq = platform_get_irq(pdev, 0);
+ if (combiner->parent_irq <= 0) {
+ dev_err(&pdev->dev, "Error getting IRQ resource\n");
+ return -EINVAL;
+ }
+
+ combiner->domain = irq_domain_create_linear(
+ pdev->dev.fwnode, combiner->nirqs, &domain_ops, combiner);
+ if (!combiner->domain)
+ /* Errors printed by irq_domain_create_linear */
+ return -ENODEV;
+
+ irq_set_chained_handler_and_data(combiner->parent_irq,
+ combiner_handle_irq, combiner);
+ combiner->irq_chip.irq_mask = combiner_irq_chip_mask_irq;
+ combiner->irq_chip.irq_unmask = combiner_irq_chip_unmask_irq;
+ combiner->irq_chip.name = pdev->name;
+
+ dev_info(&pdev->dev, "Initialized with [p=%d,n=%d,r=%p]\n",
+ combiner->parent_irq, combiner->nirqs, combiner->regs[0].addr);
+ return 0;
+}
+
+static const struct acpi_device_id qcom_irq_combiner_acpi_match[] = {
+ { "QCOM80B1", },
+ { }
+};
+
+static struct platform_driver qcom_irq_combiner_probe = {
+ .driver = {
+ .name = "qcom-irq-combiner",
+ .owner = THIS_MODULE,
+ .acpi_match_table = ACPI_PTR(qcom_irq_combiner_acpi_match),
+ },
+ .probe = combiner_probe,
+};
+
+static int __init register_qcom_irq_combiner(void)
+{
+ return platform_driver_register(&qcom_irq_combiner_probe);
+}
+device_initcall(register_qcom_irq_combiner);
--
Qualcomm Datacenter Technologies, Inc. on behalf of the Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.
^ permalink raw reply related
* [PATCH] arm: add stat support to fiq
From: Oussama Ghorbel @ 2016-11-29 23:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1480459715-19496-1-git-send-email-ghorbel@gmail.com>
This patch has been tested on the raspberry pi 2/3 boards with 4.6.y kernel.
Another patch written for dwc_otg driver (not in mainline) that uses the
features provided by this patch. it's available here
https://www.osadl.org/monitoring/patches/r7s3s/0002-usb-dwc_otg-enable-fiq-stat.patch
To see both patches in action, you may viewed it on OSALD QA Farm here:
https://www.osadl.org/Profile-of-system-in-rack-7-slot-3.qa-profile-r7s3.0.html?shadow=1
Oussama
On Tue, Nov 29, 2016 at 11:48 PM, Oussama Ghorbel <ghorbel@gmail.com> wrote:
> This patch allows drivers that uses fiq to have a stat on the
> execution number of the fiq handler.
> For that three APIs has been defined:
> - fiq_kstat_enable: this function enables fiq stat and allocates required
> memory for it
> - fiq_kstat_disable: this function disable fiq stat and free its allocated
> memory
> - fiq_kstat_this_cpu_inc: This function increments the fiq stat counter of
> the current CPU running the fiq handler
>
> A driver may call fiq_kstat_enable at its initialization to enable fiq
> stat and then call fiq_kstat_this_cpu_inc from the fiq handler
>
> When the fiq stat is enabled by a driver, then /proc/interrupts shows the
> fiq entry as the following example:
> FIQ: 0 21642080 0 0 usb_fiq
> If the fiq stat is not enabled, the content will be similar to the old one
> as the following example:
> FIQ: usb_fiq
> The fiq name will be always written on the first column after the last CPU
> column
>
> Signed-off-by: Oussama Ghorbel <ghorbel@gmail.com>
> ---
> arch/arm/include/asm/fiq.h | 10 ++++++++++
> arch/arm/kernel/fiq.c | 31 +++++++++++++++++++++++++++----
> 2 files changed, 37 insertions(+), 4 deletions(-)
>
> diff --git a/arch/arm/include/asm/fiq.h b/arch/arm/include/asm/fiq.h
> index d493d0b..77f819b 100644
> --- a/arch/arm/include/asm/fiq.h
> +++ b/arch/arm/include/asm/fiq.h
> @@ -31,6 +31,8 @@ struct fiq_handler {
> /* data for the relinquish/reacquire functions
> */
> void *dev_id;
> + /* fiq stats percpu */
> + unsigned int __percpu *fiq_kstat;
> };
>
> extern int claim_fiq(struct fiq_handler *f);
> @@ -53,4 +55,12 @@ static inline void get_fiq_regs(struct pt_regs *regs)
> __get_fiq_regs(®s->ARM_r8);
> }
>
> +extern int fiq_kstat_enable(struct fiq_handler *fh);
> +extern void fiq_kstat_disable(struct fiq_handler *fh);
> +
> +static inline void fiq_kstat_this_cpu_inc(struct fiq_handler *fh)
> +{
> + __this_cpu_inc(*fh->fiq_kstat);
> +}
> +
> #endif
> diff --git a/arch/arm/kernel/fiq.c b/arch/arm/kernel/fiq.c
> index 059c3da..4b606df 100644
> --- a/arch/arm/kernel/fiq.c
> +++ b/arch/arm/kernel/fiq.c
> @@ -83,10 +83,19 @@ static struct fiq_handler *current_fiq = &default_owner;
>
> int show_fiq_list(struct seq_file *p, int prec)
> {
> - if (current_fiq != &default_owner)
> - seq_printf(p, "%*s: %s\n", prec, "FIQ",
> - current_fiq->name);
> -
> + int j;
> +
> + if (current_fiq == &default_owner)
> + return 0;
> + seq_printf(p, "%*s: ", prec, "FIQ");
> + for_each_online_cpu(j) {
> + if (current_fiq->fiq_kstat)
> + seq_printf(p, "%10u ",
> + *per_cpu_ptr(current_fiq->fiq_kstat, j));
> + else
> + seq_printf(p, "%10s ", "");
> + }
> + seq_printf(p, " %s\n", current_fiq->name);
> return 0;
> }
>
> @@ -162,3 +171,17 @@ void __init init_FIQ(int start)
> get_fiq_regs(&dfl_fiq_regs);
> fiq_start = start;
> }
> +
> +int fiq_kstat_enable(struct fiq_handler *fh)
> +{
> + fh->fiq_kstat = alloc_percpu(unsigned int);
> + return fh->fiq_kstat != 0 ? 0 : 1;
> +}
> +EXPORT_SYMBOL(fiq_kstat_enable);
> +
> +void fiq_kstat_disable(struct fiq_handler *fh)
> +{
> + free_percpu(fh->fiq_kstat);
> + fh->fiq_kstat = NULL;
> +}
> +EXPORT_SYMBOL(fiq_kstat_disable);
> --
> 2.7.4
>
^ permalink raw reply
* [PATCH v2] PCI: Add information about describing PCI in ACPI
From: Linus Torvalds @ 2016-11-29 23:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161129212816.15663.28100.stgit@bhelgaas-glaptop.roam.corp.google.com>
Bjorn, this email was marked as spam, because:
It has a from address in google.com but has failed google.com's
required tests for authentication
in particular, it looks like you used a non-google smtp server
(kernel.org) to send the email, so there is no DKIM hash (or perhaps
google just uses some other non-standard marker for "this actually
came from google"). So gmail marks it as spam because dmarc fails:
dmarc=fail (p=REJECT dis=NONE) header.from=google.com
Just to let you know. If you use your google.com email, you do need to
go through the google smtp server.
This may or may not be new - I didn't go and look at old messages of
yours, but it is possible that google.com enabled dmarc/dkim recently.
Linus
On Tue, Nov 29, 2016 at 1:39 PM, Bjorn Helgaas <bhelgaas@google.com> wrote:
> Here's another stab at this writeup. I'd appreciate any comments!
^ permalink raw reply
* [PATCH V6 1/1] ARM64/PCI: Manage controller-specific information on the host controller basis
From: Bjorn Helgaas @ 2016-11-29 23:40 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1479985523-10006-1-git-send-email-tn@semihalf.com>
On Thu, Nov 24, 2016 at 12:05:23PM +0100, Tomasz Nowicki wrote:
> Currently we use one shared global acpi_pci_root_ops structure to keep
> controller-specific ops. Then its pointer is passed to acpi_pci_root_create()
> and associated with host bridge instance for good. Such design implies
> serious drawback. Any potential manipulation on the single system-wide
> acpi_pci_root_ops leads to kernel crash. The structure content is not
> really changing even across multiple host bridges creation thus it was not
> the issue so far.
>
> In preparation for adding ECAM quirks mechanism (where controller-specific
> PCI ops may be different for each host bridge) allocate new
> acpi_pci_root_ops and fill in with data for each bridge. Now it is safe
> to have different controller-specific info. As a consequence free
> acpi_pci_root_ops when host bridge is released.
>
> No functional changes in this patch.
>
> Signed-off-by: Tomasz Nowicki <tn@semihalf.com>
Applied to pci/ecam for v4.10, thanks, Tomasz!
> ---
> arch/arm64/kernel/pci.c | 17 ++++++++++-------
> 1 file changed, 10 insertions(+), 7 deletions(-)
>
> diff --git a/arch/arm64/kernel/pci.c b/arch/arm64/kernel/pci.c
> index fb439c7..5c08baf 100644
> --- a/arch/arm64/kernel/pci.c
> +++ b/arch/arm64/kernel/pci.c
> @@ -152,33 +152,36 @@ static void pci_acpi_generic_release_info(struct acpi_pci_root_info *ci)
>
> ri = container_of(ci, struct acpi_pci_generic_root_info, common);
> pci_ecam_free(ri->cfg);
> + kfree(ci->ops);
> kfree(ri);
> }
>
> -static struct acpi_pci_root_ops acpi_pci_root_ops = {
> - .release_info = pci_acpi_generic_release_info,
> -};
> -
> /* Interface called from ACPI code to setup PCI host controller */
> struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
> {
> int node = acpi_get_node(root->device->handle);
> struct acpi_pci_generic_root_info *ri;
> struct pci_bus *bus, *child;
> + struct acpi_pci_root_ops *root_ops;
>
> ri = kzalloc_node(sizeof(*ri), GFP_KERNEL, node);
> if (!ri)
> return NULL;
>
> + root_ops = kzalloc_node(sizeof(*root_ops), GFP_KERNEL, node);
> + if (!root_ops)
> + return NULL;
> +
> ri->cfg = pci_acpi_setup_ecam_mapping(root);
> if (!ri->cfg) {
> kfree(ri);
> + kfree(root_ops);
> return NULL;
> }
>
> - acpi_pci_root_ops.pci_ops = &ri->cfg->ops->pci_ops;
> - bus = acpi_pci_root_create(root, &acpi_pci_root_ops, &ri->common,
> - ri->cfg);
> + root_ops->release_info = pci_acpi_generic_release_info;
> + root_ops->pci_ops = &ri->cfg->ops->pci_ops;
> + bus = acpi_pci_root_create(root, root_ops, &ri->common, ri->cfg);
> if (!bus)
> return NULL;
>
> --
> 2.7.4
>
^ permalink raw reply
* question about irq_enter()/irq_exit() calling policy
From: Grygorii Strashko @ 2016-11-29 23:47 UTC (permalink / raw)
To: linux-arm-kernel
Hi All,
Sorry for the may be dumb question, but what is the calling policy for irq_enter()/irq_exit()?
1) Should these function be called each time system enter/exit IRQ context?
HW IRQ:
switch (IRQ mode)
...
irq_enter()
handle irq - execute hw_irq_hadler
irq_exit()
...
switch
2) Should these function be called for each processed irq?
HW IRQ:
switch (IRQ mode)
...
while (irq = get_pending_irq()) {
...
irq_enter()
handle(irq) - execute hw_irq_hadler
irq_exit()
}
...
switch
--
regards,
-grygorii
^ permalink raw reply
* [PATCH v4 0/4] davinci: VPIF: add DT support
From: Kevin Hilman @ 2016-11-29 23:57 UTC (permalink / raw)
To: linux-arm-kernel
Add DT support, including getting subdevs from DT ports/endpoints.
Tested video capture to memory on da850-lcdk board using composite
input.
Changes since v3:
- move to a single VPIF node, DT binding updated accordingly
- misc fixes/updates based on reviews from Sakari
Changes since v2:
- DT binding doc: fix example to use correct compatible
Changes since v1:
- more specific compatible strings, based on SoC: ti,da850-vpif*
- fix locking bug when unlocking over subdev s_stream
Kevin Hilman (4):
[media] davinci: vpif_capture: don't lock over s_stream
[media] davinci: VPIF: add basic support for DT init
[media] davinci: vpif_capture: get subdevs from DT
[media] dt-bindings: add TI VPIF documentation
.../devicetree/bindings/media/ti,da850-vpif.txt | 67 ++++++++++
drivers/media/platform/davinci/vpif.c | 48 ++++++-
drivers/media/platform/davinci/vpif_capture.c | 147 ++++++++++++++++++++-
drivers/media/platform/davinci/vpif_display.c | 6 +
include/media/davinci/vpif_types.h | 9 +-
5 files changed, 270 insertions(+), 7 deletions(-)
create mode 100644 Documentation/devicetree/bindings/media/ti,da850-vpif.txt
--
2.9.3
^ permalink raw reply
* [PATCH v4 1/4] [media] davinci: vpif_capture: don't lock over s_stream
From: Kevin Hilman @ 2016-11-29 23:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161129235712.29846-1-khilman@baylibre.com>
Video capture subdevs may be over I2C and may sleep during xfer, so we
cannot do IRQ-disabled locking when calling the subdev.
Signed-off-by: Kevin Hilman <khilman@baylibre.com>
---
drivers/media/platform/davinci/vpif_capture.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/media/platform/davinci/vpif_capture.c b/drivers/media/platform/davinci/vpif_capture.c
index 5104cc0ee40e..9f8f41c0f251 100644
--- a/drivers/media/platform/davinci/vpif_capture.c
+++ b/drivers/media/platform/davinci/vpif_capture.c
@@ -193,7 +193,10 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
}
}
+ spin_unlock_irqrestore(&common->irqlock, flags);
ret = v4l2_subdev_call(ch->sd, video, s_stream, 1);
+ spin_lock_irqsave(&common->irqlock, flags);
+
if (ret && ret != -ENOIOCTLCMD && ret != -ENODEV) {
vpif_dbg(1, debug, "stream on failed in subdev\n");
goto err;
--
2.9.3
^ permalink raw reply related
* [PATCH v4 2/4] [media] davinci: VPIF: add basic support for DT init
From: Kevin Hilman @ 2016-11-29 23:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161129235712.29846-1-khilman@baylibre.com>
Add basic support for initialization via DT.
Because existing capture and display devices are implemented as separate
platform_devices, and in order to preserve that legacy support, during
DT boot, manually create capture and display platform devices to
initialize capture and display support.
Signed-off-by: Kevin Hilman <khilman@baylibre.com>
---
drivers/media/platform/davinci/vpif.c | 48 ++++++++++++++++++++++++++-
drivers/media/platform/davinci/vpif_capture.c | 6 ++++
drivers/media/platform/davinci/vpif_display.c | 6 ++++
3 files changed, 59 insertions(+), 1 deletion(-)
diff --git a/drivers/media/platform/davinci/vpif.c b/drivers/media/platform/davinci/vpif.c
index 0380cf2e5775..528b30d52208 100644
--- a/drivers/media/platform/davinci/vpif.c
+++ b/drivers/media/platform/davinci/vpif.c
@@ -420,7 +420,8 @@ EXPORT_SYMBOL(vpif_channel_getfid);
static int vpif_probe(struct platform_device *pdev)
{
- static struct resource *res;
+ static struct resource *res, *res_irq;
+ struct platform_device *pdev_capture, *pdev_display;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
vpif_base = devm_ioremap_resource(&pdev->dev, res);
@@ -432,6 +433,42 @@ static int vpif_probe(struct platform_device *pdev)
spin_lock_init(&vpif_lock);
dev_info(&pdev->dev, "vpif probe success\n");
+
+ if (!pdev->dev.of_node)
+ return 0;
+
+ /*
+ * For DT platforms, manually create platform_devices for
+ * capture/display drivers.
+ */
+ res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (!res_irq) {
+ dev_warn(&pdev->dev, "Missing IRQ resource.\n");
+ return -EINVAL;
+ }
+
+ pdev_capture = devm_kzalloc(&pdev->dev, sizeof(*pdev_capture),
+ GFP_KERNEL);
+ pdev_capture->name = "vpif_capture";
+ pdev_capture->id = -1;
+ pdev_capture->resource = res_irq;
+ pdev_capture->num_resources = 1;
+ pdev_capture->dev.dma_mask = pdev->dev.dma_mask;
+ pdev_capture->dev.coherent_dma_mask = pdev->dev.coherent_dma_mask;
+ pdev_capture->dev.parent = &pdev->dev;
+ platform_device_register(pdev_capture);
+
+ pdev_display = devm_kzalloc(&pdev->dev, sizeof(*pdev_display),
+ GFP_KERNEL);
+ pdev_display->name = "vpif_display";
+ pdev_display->id = -1;
+ pdev_display->resource = res_irq;
+ pdev_display->num_resources = 1;
+ pdev_display->dev.dma_mask = pdev->dev.dma_mask;
+ pdev_display->dev.coherent_dma_mask = pdev->dev.coherent_dma_mask;
+ pdev_display->dev.parent = &pdev->dev;
+ platform_device_register(pdev_display);
+
return 0;
}
@@ -464,8 +501,17 @@ static const struct dev_pm_ops vpif_pm = {
#define vpif_pm_ops NULL
#endif
+#if IS_ENABLED(CONFIG_OF)
+static const struct of_device_id vpif_of_match[] = {
+ { .compatible = "ti,da850-vpif", },
+ { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, vpif_of_match);
+#endif
+
static struct platform_driver vpif_driver = {
.driver = {
+ .of_match_table = of_match_ptr(vpif_of_match),
.name = "vpif",
.pm = vpif_pm_ops,
},
diff --git a/drivers/media/platform/davinci/vpif_capture.c b/drivers/media/platform/davinci/vpif_capture.c
index 9f8f41c0f251..a83df07e4051 100644
--- a/drivers/media/platform/davinci/vpif_capture.c
+++ b/drivers/media/platform/davinci/vpif_capture.c
@@ -45,6 +45,7 @@ module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "Debug level 0-1");
#define VPIF_DRIVER_NAME "vpif_capture"
+MODULE_ALIAS("platform:" VPIF_DRIVER_NAME);
/* global variables */
static struct vpif_device vpif_obj = { {NULL} };
@@ -1438,6 +1439,11 @@ static __init int vpif_probe(struct platform_device *pdev)
int res_idx = 0;
int i, err;
+ if (!pdev->dev.platform_data) {
+ dev_warn(&pdev->dev, "Missing platform data. Giving up.\n");
+ return -EINVAL;
+ }
+
vpif_dev = &pdev->dev;
err = initialize_vpif();
diff --git a/drivers/media/platform/davinci/vpif_display.c b/drivers/media/platform/davinci/vpif_display.c
index 75b27233ec2f..7f632b757d32 100644
--- a/drivers/media/platform/davinci/vpif_display.c
+++ b/drivers/media/platform/davinci/vpif_display.c
@@ -42,6 +42,7 @@ module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "Debug level 0-1");
#define VPIF_DRIVER_NAME "vpif_display"
+MODULE_ALIAS("platform:" VPIF_DRIVER_NAME);
/* Is set to 1 in case of SDTV formats, 2 in case of HDTV formats. */
static int ycmux_mode;
@@ -1249,6 +1250,11 @@ static __init int vpif_probe(struct platform_device *pdev)
int res_idx = 0;
int i, err;
+ if (!pdev->dev.platform_data) {
+ dev_warn(&pdev->dev, "Missing platform data. Giving up.\n");
+ return -EINVAL;
+ }
+
vpif_dev = &pdev->dev;
err = initialize_vpif();
--
2.9.3
^ permalink raw reply related
* [PATCH v4 3/4] [media] davinci: vpif_capture: get subdevs from DT
From: Kevin Hilman @ 2016-11-29 23:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161129235712.29846-1-khilman@baylibre.com>
Allow getting of subdevs from DT ports and endpoints.
The _get_pdata() function was larely inspired by (i.e. stolen from)
am437x-vpfe.c
Signed-off-by: Kevin Hilman <khilman@baylibre.com>
---
drivers/media/platform/davinci/vpif_capture.c | 138 +++++++++++++++++++++++++-
include/media/davinci/vpif_types.h | 9 +-
2 files changed, 141 insertions(+), 6 deletions(-)
diff --git a/drivers/media/platform/davinci/vpif_capture.c b/drivers/media/platform/davinci/vpif_capture.c
index a83df07e4051..4e363da2c21f 100644
--- a/drivers/media/platform/davinci/vpif_capture.c
+++ b/drivers/media/platform/davinci/vpif_capture.c
@@ -26,6 +26,8 @@
#include <linux/slab.h>
#include <media/v4l2-ioctl.h>
+#include <media/v4l2-of.h>
+#include <media/i2c/tvp514x.h>
#include "vpif.h"
#include "vpif_capture.h"
@@ -651,6 +653,10 @@ static int vpif_input_to_subdev(
vpif_dbg(2, debug, "vpif_input_to_subdev\n");
+ if (!chan_cfg)
+ return -1;
+ if (input_index >= chan_cfg->input_count)
+ return -1;
subdev_name = chan_cfg->inputs[input_index].subdev_name;
if (subdev_name == NULL)
return -1;
@@ -658,7 +664,7 @@ static int vpif_input_to_subdev(
/* loop through the sub device list to get the sub device info */
for (i = 0; i < vpif_cfg->subdev_count; i++) {
subdev_info = &vpif_cfg->subdev_info[i];
- if (!strcmp(subdev_info->name, subdev_name))
+ if (subdev_info && !strcmp(subdev_info->name, subdev_name))
return i;
}
return -1;
@@ -1328,6 +1334,21 @@ static int vpif_async_bound(struct v4l2_async_notifier *notifier,
{
int i;
+ for (i = 0; i < vpif_obj.config->asd_sizes[0]; i++) {
+ struct v4l2_async_subdev *_asd = vpif_obj.config->asd[i];
+ const struct device_node *node = _asd->match.of.node;
+
+ if (node == subdev->of_node) {
+ vpif_obj.sd[i] = subdev;
+ vpif_obj.config->chan_config->inputs[i].subdev_name =
+ (char *)subdev->of_node->full_name;
+ vpif_dbg(2, debug,
+ "%s: setting input %d subdev_name = %s\n",
+ __func__, i, subdev->of_node->full_name);
+ return 0;
+ }
+ }
+
for (i = 0; i < vpif_obj.config->subdev_count; i++)
if (!strcmp(vpif_obj.config->subdev_info[i].name,
subdev->name)) {
@@ -1423,6 +1444,118 @@ static int vpif_async_complete(struct v4l2_async_notifier *notifier)
return vpif_probe_complete();
}
+static struct vpif_capture_config *
+vpif_capture_get_pdata(struct platform_device *pdev)
+{
+ struct device_node *endpoint = NULL;
+ struct v4l2_of_endpoint bus_cfg;
+ struct vpif_capture_config *pdata;
+ struct vpif_subdev_info *sdinfo;
+ struct vpif_capture_chan_config *chan;
+ unsigned int i;
+
+ dev_dbg(&pdev->dev, "vpif_get_pdata\n");
+
+ /*
+ * DT boot: OF node from parent device contains
+ * video ports & endpoints data.
+ */
+ if (pdev->dev.parent && pdev->dev.parent->of_node)
+ pdev->dev.of_node = pdev->dev.parent->of_node;
+ if (!IS_ENABLED(CONFIG_OF) || !pdev->dev.of_node)
+ return pdev->dev.platform_data;
+
+ pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+ if (!pdata)
+ return NULL;
+ pdata->subdev_info =
+ devm_kzalloc(&pdev->dev, sizeof(*pdata->subdev_info) *
+ VPIF_CAPTURE_NUM_CHANNELS, GFP_KERNEL);
+
+ if (!pdata->subdev_info)
+ return NULL;
+
+ for (i = 0; i < VPIF_CAPTURE_NUM_CHANNELS; i++) {
+ struct device_node *rem;
+ unsigned int flags;
+ int err;
+
+ endpoint = of_graph_get_next_endpoint(pdev->dev.of_node,
+ endpoint);
+ if (!endpoint)
+ break;
+
+ sdinfo = &pdata->subdev_info[i];
+ chan = &pdata->chan_config[i];
+ chan->inputs = devm_kzalloc(&pdev->dev,
+ sizeof(*chan->inputs) *
+ VPIF_CAPTURE_NUM_CHANNELS,
+ GFP_KERNEL);
+
+ chan->input_count++;
+ chan->inputs[i].input.type = V4L2_INPUT_TYPE_CAMERA;
+ chan->inputs[i].input.std = V4L2_STD_ALL;
+ chan->inputs[i].input.capabilities = V4L2_IN_CAP_STD;
+
+ /*
+ * FIXME: need a new property for input/output routing?
+ * All known boards are using ch0:composite ch1: s-video.
+ */
+ if (i == 0)
+ chan->inputs[i].input_route = INPUT_CVBS_VI2B;
+ else
+ chan->inputs[i].input_route = INPUT_SVIDEO_VI2C_VI1C;
+ chan->inputs[i].output_route = OUTPUT_10BIT_422_EMBEDDED_SYNC;
+
+ err = v4l2_of_parse_endpoint(endpoint, &bus_cfg);
+ if (err) {
+ dev_err(&pdev->dev, "Could not parse the endpoint\n");
+ goto done;
+ }
+ dev_dbg(&pdev->dev, "Endpoint %s, bus_width = %d\n",
+ endpoint->full_name, bus_cfg.bus.parallel.bus_width);
+ flags = bus_cfg.bus.parallel.flags;
+
+ if (flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH)
+ chan->vpif_if.hd_pol = 1;
+
+ if (flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH)
+ chan->vpif_if.vd_pol = 1;
+
+ chan->vpif_if.if_type = VPIF_IF_BT656;
+ rem = of_graph_get_remote_port_parent(endpoint);
+ if (!rem) {
+ dev_dbg(&pdev->dev, "Remote device at %s not found\n",
+ endpoint->full_name);
+ goto done;
+ }
+
+ dev_dbg(&pdev->dev, "Remote device %s, %s found\n",
+ rem->name, rem->full_name);
+ sdinfo->name = rem->full_name;
+
+ pdata->asd[i] = devm_kzalloc(&pdev->dev,
+ sizeof(struct v4l2_async_subdev),
+ GFP_KERNEL);
+ if (!pdata->asd[i]) {
+ of_node_put(rem);
+ pdata = NULL;
+ goto done;
+ }
+
+ pdata->asd[i]->match_type = V4L2_ASYNC_MATCH_OF;
+ pdata->asd[i]->match.of.node = rem;
+ of_node_put(rem);
+ }
+
+done:
+ pdata->asd_sizes[0] = i;
+ pdata->subdev_count = i;
+ pdata->card_name = "DA850/OMAP-L138 Video Capture";
+
+ return pdata;
+}
+
/**
* vpif_probe : This function probes the vpif capture driver
* @pdev: platform device pointer
@@ -1439,6 +1572,7 @@ static __init int vpif_probe(struct platform_device *pdev)
int res_idx = 0;
int i, err;
+ pdev->dev.platform_data = vpif_capture_get_pdata(pdev);
if (!pdev->dev.platform_data) {
dev_warn(&pdev->dev, "Missing platform data. Giving up.\n");
return -EINVAL;
@@ -1481,7 +1615,7 @@ static __init int vpif_probe(struct platform_device *pdev)
goto vpif_unregister;
}
- if (!vpif_obj.config->asd_sizes) {
+ if (!vpif_obj.config->asd_sizes[0]) {
i2c_adap = i2c_get_adapter(1);
for (i = 0; i < subdev_count; i++) {
subdevdata = &vpif_obj.config->subdev_info[i];
diff --git a/include/media/davinci/vpif_types.h b/include/media/davinci/vpif_types.h
index 3cb1704a0650..4ee3b41975db 100644
--- a/include/media/davinci/vpif_types.h
+++ b/include/media/davinci/vpif_types.h
@@ -65,14 +65,14 @@ struct vpif_display_config {
struct vpif_input {
struct v4l2_input input;
- const char *subdev_name;
+ char *subdev_name;
u32 input_route;
u32 output_route;
};
struct vpif_capture_chan_config {
struct vpif_interface vpif_if;
- const struct vpif_input *inputs;
+ struct vpif_input *inputs;
int input_count;
};
@@ -83,7 +83,8 @@ struct vpif_capture_config {
struct vpif_subdev_info *subdev_info;
int subdev_count;
const char *card_name;
- struct v4l2_async_subdev **asd; /* Flat array, arranged in groups */
- int *asd_sizes; /* 0-terminated array of asd group sizes */
+
+ struct v4l2_async_subdev *asd[VPIF_CAPTURE_MAX_CHANNELS];
+ int asd_sizes[VPIF_CAPTURE_MAX_CHANNELS];
};
#endif /* _VPIF_TYPES_H */
--
2.9.3
^ permalink raw reply related
* [PATCH v4 4/4] [media] dt-bindings: add TI VPIF documentation
From: Kevin Hilman @ 2016-11-29 23:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161129235712.29846-1-khilman@baylibre.com>
Signed-off-by: Kevin Hilman <khilman@baylibre.com>
---
.../devicetree/bindings/media/ti,da850-vpif.txt | 67 ++++++++++++++++++++++
1 file changed, 67 insertions(+)
create mode 100644 Documentation/devicetree/bindings/media/ti,da850-vpif.txt
diff --git a/Documentation/devicetree/bindings/media/ti,da850-vpif.txt b/Documentation/devicetree/bindings/media/ti,da850-vpif.txt
new file mode 100644
index 000000000000..fa06dfdb6898
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/ti,da850-vpif.txt
@@ -0,0 +1,67 @@
+Texas Instruments VPIF
+----------------------
+
+The TI Video Port InterFace (VPIF) is the primary component for video
+capture and display on the DA850/AM18x family of TI DaVinci/Sitara
+SoCs.
+
+TI Document reference: SPRUH82C, Chapter 35
+http://www.ti.com/lit/pdf/spruh82
+
+Required properties:
+- compatible: must be "ti,da850-vpif"
+- reg: physical base address and length of the registers set for the device;
+- interrupts: should contain IRQ line for the VPIF
+
+Video Capture:
+
+VPIF has a 16-bit parallel bus input, supporting 2 8-bit channels or a
+single 16-bit channel. It should contain at least one port child node
+with child 'endpoint' node. Please refer to the bindings defined in
+Documentation/devicetree/bindings/media/video-interfaces.txt.
+
+Example using 2 8-bit input channels, one of which is connected to an
+I2C-connected TVP5147 decoder:
+
+ vpif: vpif at 217000 {
+ compatible = "ti,da850-vpif";
+ reg = <0x217000 0x1000>;
+ interrupts = <92>;
+
+ port {
+ vpif_ch0: endpoint at 0 {
+ reg = <0>;
+ bus-width = <8>;
+ remote-endpoint = <&composite>;
+ };
+
+ vpif_ch1: endpoint at 1 {
+ reg = <1>;
+ bus-width = <8>;
+ data-shift = <8>;
+ };
+ };
+ };
+
+[ ... ]
+
+&i2c0 {
+
+ tvp5147 at 5d {
+ compatible = "ti,tvp5147";
+ reg = <0x5d>;
+ status = "okay";
+
+ port {
+ composite: endpoint {
+ hsync-active = <1>;
+ vsync-active = <1>;
+ pclk-sample = <0>;
+
+ /* VPIF channel 0 (lower 8-bits) */
+ remote-endpoint = <&vpif_ch0>;
+ bus-width = <8>;
+ };
+ };
+ };
+};
--
2.9.3
^ permalink raw reply related
* [PATCH v4 00/10] IOMMU probe deferral support
From: Sricharan R @ 2016-11-30 0:22 UTC (permalink / raw)
To: linux-arm-kernel
This series calls the dma ops configuration for the devices
at a generic place so that it works for all busses.
The dma_configure_ops for a device is now called during
the device_attach callback just before the probe of the
bus/driver is called. Similarly dma_deconfigure is called during
device/driver_detach path.
pci_bus_add_devices (platform/amba)(_device_create/driver_register)
| |
pci_bus_add_device (device_add/driver_register)
| |
device_attach device_initial_probe
| |
__device_attach_driver __device_attach_driver
|
driver_probe_device
|
really_probe
|
dma_configure
Similarly on the device/driver_unregister path __device_release_driver is
called which inturn calls dma_deconfigure.
Took the reworked patches [2] from Robin's branch and
rebased on top of Lorenzo's ACPI IORT ARM support series [3].
Tested with platform and pci devices for probe deferral
and reprobe on arm64 based platform. Added the patches [9,10],
drivers: acpi: Configure acpi devices dma operation at probe time
drivers: acpi: Handle IOMMU lookup failure with deferred probing or error
for doing the dma ops configuration at probe time for acpi based platform
as well. Did not have a acpi based platform to test the changes and with
my still catching up knowledge on acpi/enumeration those two patches needs
to be reviewed/tested more.
Previous post of this series [5].
[V4]
* Took the reworked patches [2] from Robin's branch and
rebased on top of Lorenzo's ACPI IORT ARM support series [3].
* Added the patches for moving the dma ops configuration of
acpi based devices to probe time as well.
[V3]
* Removed the patch to split dma_masks/dma_ops configuration
separately based on review comments that both masks and ops are
required only during the device probe time.
* Reworked the series based on Generic DT bindings series.
* Added call to iommu's remove_device in the cleanup path for arm and
arm64.
* Removed the notifier trick in arm64 to handle early device
registration.
* Added reset of dma_ops in cleanup path for arm based on comments.
* Fixed the pci_iommu_configure path and tested with PCI device as
well.
* Fixed a bug to return the correct iommu_ops from patch 7 [4] in
last post.
* Fixed few other cosmetic comments.
[V2]
* Updated the Initial post to call dma_configure/deconfigure from
generic code
* Added iommu add_device callback from of_iommu_configure path
[V1]
* Initial post from Laurent Pinchart [1]
[1] http://lists.linuxfoundation.org/pipermail/iommu/2015-May/013016.html
[2] http://www.linux-arm.org/git?p=linux-rm.git;a=shortlog;h=refs/heads/iommu/defer
[3] https://lkml.org/lkml/2016/11/21/141
[4] https://www.mail-archive.com/iommu at lists.linux-foundation.org/msg13940.html
[5] http://lists.infradead.org/pipermail/linux-arm-kernel/2016-October/460832.html
Laurent Pinchart (3):
of: dma: Move range size workaround to of_dma_get_range()
of: dma: Make of_dma_deconfigure() public
iommu: of: Handle IOMMU lookup failure with deferred probing or error
Robin Murphy (3):
iommu/of: Refactor of_iommu_configure() for error handling
iommu/of: Prepare for deferred IOMMU configuration
iommu/arm-smmu: Clean up early-probing workarounds
Sricharan R (4):
drivers: platform: Configure dma operations at probe time
arm64: dma-mapping: Remove the notifier trick to handle early setting
of dma_ops
drivers: acpi: Configure acpi devices dma operation at probe time
drivers: acpi: Handle IOMMU lookup failure with deferred probing or
error
arch/arm64/mm/dma-mapping.c | 132 ++++----------------------------------------
drivers/acpi/arm64/iort.c | 17 +++++-
drivers/acpi/glue.c | 6 --
drivers/acpi/scan.c | 7 ++-
drivers/base/dd.c | 10 ++++
drivers/base/dma-mapping.c | 32 +++++++++++
drivers/iommu/arm-smmu-v3.c | 35 +-----------
drivers/iommu/arm-smmu.c | 58 +++----------------
drivers/iommu/dma-iommu.c | 1 +
drivers/iommu/of_iommu.c | 114 +++++++++++++++++++++++++++-----------
drivers/of/address.c | 20 ++++++-
drivers/of/device.c | 36 ++++++------
drivers/of/platform.c | 10 +---
drivers/pci/probe.c | 17 +++---
include/acpi/acpi_bus.h | 2 +-
include/linux/acpi.h | 7 ++-
include/linux/dma-mapping.h | 3 +
include/linux/of_device.h | 10 +++-
include/linux/pci.h | 5 ++
19 files changed, 238 insertions(+), 284 deletions(-)
--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
^ permalink raw reply
* [PATCH 01/10] iommu/of: Refactor of_iommu_configure() for error handling
From: Sricharan R @ 2016-11-30 0:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1480465344-11862-1-git-send-email-sricharan@codeaurora.org>
From: Robin Murphy <robin.murphy@arm.com>
In preparation for some upcoming cleverness, rework the control flow in
of_iommu_configure() to minimise duplication and improve the propogation
of errors. It's also as good a time as any to switch over from the
now-just-a-compatibility-wrapper of_iommu_get_ops() to using the generic
IOMMU instance interface directly.
Signed-off-by: Robin Murphy <robin.murphy@arm.com>
---
drivers/iommu/of_iommu.c | 83 +++++++++++++++++++++++++++++++-----------------
1 file changed, 53 insertions(+), 30 deletions(-)
diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index 0f57ddc..ee49081 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -96,6 +96,28 @@ int of_get_dma_window(struct device_node *dn, const char *prefix, int index,
}
EXPORT_SYMBOL_GPL(of_get_dma_window);
+static const struct iommu_ops
+*of_iommu_xlate(struct device *dev, struct of_phandle_args *iommu_spec)
+{
+ const struct iommu_ops *ops;
+ struct fwnode_handle *fwnode = &iommu_spec->np->fwnode;
+ int err;
+
+ ops = iommu_get_instance(fwnode);
+ if (!ops || !ops->of_xlate)
+ return NULL;
+
+ err = iommu_fwspec_init(dev, &iommu_spec->np->fwnode, ops);
+ if (err)
+ return ERR_PTR(err);
+
+ err = ops->of_xlate(dev, iommu_spec);
+ if (err)
+ return ERR_PTR(err);
+
+ return ops;
+}
+
static int __get_pci_rid(struct pci_dev *pdev, u16 alias, void *data)
{
struct of_phandle_args *iommu_spec = data;
@@ -105,10 +127,11 @@ static int __get_pci_rid(struct pci_dev *pdev, u16 alias, void *data)
}
static const struct iommu_ops
-*of_pci_iommu_configure(struct pci_dev *pdev, struct device_node *bridge_np)
+*of_pci_iommu_init(struct pci_dev *pdev, struct device_node *bridge_np)
{
const struct iommu_ops *ops;
struct of_phandle_args iommu_spec;
+ int err;
/*
* Start by tracing the RID alias down the PCI topology as
@@ -123,56 +146,56 @@ static int __get_pci_rid(struct pci_dev *pdev, u16 alias, void *data)
* bus into the system beyond, and which IOMMU it ends up at.
*/
iommu_spec.np = NULL;
- if (of_pci_map_rid(bridge_np, iommu_spec.args[0], "iommu-map",
- "iommu-map-mask", &iommu_spec.np, iommu_spec.args))
- return NULL;
+ err = of_pci_map_rid(bridge_np, iommu_spec.args[0], "iommu-map",
+ "iommu-map-mask", &iommu_spec.np,
+ iommu_spec.args);
+ if (err)
+ return ERR_PTR(err);
- ops = of_iommu_get_ops(iommu_spec.np);
- if (!ops || !ops->of_xlate ||
- iommu_fwspec_init(&pdev->dev, &iommu_spec.np->fwnode, ops) ||
- ops->of_xlate(&pdev->dev, &iommu_spec))
- ops = NULL;
+ ops = of_iommu_xlate(&pdev->dev, &iommu_spec);
of_node_put(iommu_spec.np);
return ops;
}
-const struct iommu_ops *of_iommu_configure(struct device *dev,
- struct device_node *master_np)
+static const struct iommu_ops
+*of_platform_iommu_init(struct device *dev, struct device_node *np)
{
struct of_phandle_args iommu_spec;
- struct device_node *np;
const struct iommu_ops *ops = NULL;
int idx = 0;
- if (dev_is_pci(dev))
- return of_pci_iommu_configure(to_pci_dev(dev), master_np);
-
/*
* We don't currently walk up the tree looking for a parent IOMMU.
* See the `Notes:' section of
* Documentation/devicetree/bindings/iommu/iommu.txt
*/
- while (!of_parse_phandle_with_args(master_np, "iommus",
- "#iommu-cells", idx,
- &iommu_spec)) {
- np = iommu_spec.np;
- ops = of_iommu_get_ops(np);
-
- if (!ops || !ops->of_xlate ||
- iommu_fwspec_init(dev, &np->fwnode, ops) ||
- ops->of_xlate(dev, &iommu_spec))
- goto err_put_node;
-
- of_node_put(np);
+ while (!of_parse_phandle_with_args(np, "iommus", "#iommu-cells",
+ idx, &iommu_spec)) {
+ ops = of_iommu_xlate(dev, &iommu_spec);
+ of_node_put(iommu_spec.np);
idx++;
+ if (IS_ERR_OR_NULL(ops))
+ break;
}
return ops;
+}
+
+const struct iommu_ops *of_iommu_configure(struct device *dev,
+ struct device_node *master_np)
+{
+ const struct iommu_ops *ops;
+
+ if (!master_np)
+ return NULL;
+
+ if (dev_is_pci(dev))
+ ops = of_pci_iommu_init(to_pci_dev(dev), master_np);
+ else
+ ops = of_platform_iommu_init(dev, master_np);
-err_put_node:
- of_node_put(np);
- return NULL;
+ return IS_ERR(ops) ? NULL : ops;
}
static int __init of_iommu_init(void)
--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
^ permalink raw reply related
* [PATCH 02/10] iommu/of: Prepare for deferred IOMMU configuration
From: Sricharan R @ 2016-11-30 0:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1480465344-11862-1-git-send-email-sricharan@codeaurora.org>
From: Robin Murphy <robin.murphy@arm.com>
IOMMU configuration represents unchanging properties of the hardware,
and as such should only need happen once in a device's lifetime, but
the necessary interaction with the IOMMU device and driver complicates
exactly when that point should be.
Since the only reasonable tool available for handling the inter-device
dependency is probe deferral, we need to prepare of_iommu_configure()
to run later than it is currently called (i.e. at driver probe rather
than device creation), to handle being retried, and to tell whether a
not-yet present IOMMU should be waited for or skipped (by virtue of
having declared a built-in driver or not).
Signed-off-by: Robin Murphy <robin.murphy@arm.com>
---
drivers/iommu/of_iommu.c | 30 +++++++++++++++++++++++++++++-
1 file changed, 29 insertions(+), 1 deletion(-)
diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index ee49081..349bd1d 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -104,12 +104,20 @@ int of_get_dma_window(struct device_node *dn, const char *prefix, int index,
int err;
ops = iommu_get_instance(fwnode);
- if (!ops || !ops->of_xlate)
+ if ((ops && !ops->of_xlate) ||
+ (!ops && !of_match_node(&__iommu_of_table, iommu_spec->np)))
return NULL;
err = iommu_fwspec_init(dev, &iommu_spec->np->fwnode, ops);
if (err)
return ERR_PTR(err);
+ /*
+ * The otherwise-empty fwspec handily serves to indicate the specific
+ * IOMMU device we're waiting for, which will be useful if we ever get
+ * a proper probe-ordering dependency mechanism in future.
+ */
+ if (!ops)
+ return ERR_PTR(-EPROBE_DEFER);
err = ops->of_xlate(dev, iommu_spec);
if (err)
@@ -186,14 +194,34 @@ const struct iommu_ops *of_iommu_configure(struct device *dev,
struct device_node *master_np)
{
const struct iommu_ops *ops;
+ struct iommu_fwspec *fwspec = dev->iommu_fwspec;
if (!master_np)
return NULL;
+ if (fwspec) {
+ if (fwspec->ops)
+ return fwspec->ops;
+
+ /* In the deferred case, start again from scratch */
+ iommu_fwspec_free(dev);
+ }
+
if (dev_is_pci(dev))
ops = of_pci_iommu_init(to_pci_dev(dev), master_np);
else
ops = of_platform_iommu_init(dev, master_np);
+ /*
+ * If we have reason to believe the IOMMU driver missed the initial
+ * add_device callback for dev, replay it to get things in order.
+ */
+ if (!IS_ERR_OR_NULL(ops) && ops->add_device &&
+ dev->bus && !dev->iommu_group) {
+ int err = ops->add_device(dev);
+
+ if (err)
+ ops = ERR_PTR(err);
+ }
return IS_ERR(ops) ? NULL : ops;
}
--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox