From: Aleksandar Markovic <[email protected]>
v1->v2:
- patch on RTC driver cleaned up
- added drivers for virtio console and net to the Ranchu board
- minor improvements in commit messages
- updated recipient lists using get_maintainer.pl
- rebased to the latest code
This series adds Mips Ranchu virtual machine used by Android emulator.
The board relies on the concept of Mips generic boards, and utilizes
generic board framework for build and device organization.
The Ranchu board is intended to be used by Android emulator.The name
"Ranchu" originates from Android development community. "Goldfish" and
"Ranchu" are names for two generations of virtual boards used by
Android emulator. "Ranchu" is a newer one among the two, and this
series deals with Ranchu. However, for historical reasons, some file,
device, and variable names in this series still contain the word
"Goldfish".
Mips Ranchu machine includes a number of Goldfish devices. The
support for Virtio devices is also included. Ranchu board supports
up to 16 virtio devices which can be attached using virtio MMIO Bus.
This is summarized in the following picture:
ABUS
||----MIPS CPU
|| | IRQs
||----Goldfish PIC------------(32)--------
|| | | | | | | | | |
||----Goldfish TTY------ | | | | | | | |
|| | | | | | | | |
||----Goldfish RTC-------- | | | | | | |
|| | | | | | | |
||----Goldfish FB----------- | | | | | |
|| | | | | | |
||----Goldfish Events--------- | | | | |
|| | | | | |
||----Goldfish Audio------------ | | | |
|| | | | |
||----Goldfish Battery------------ | | |
|| | | |
||----Android PIPE------------------ | |
|| | |
||----Virtio MMIO Bus | |
|| | | | | |
|| | | (virtio-block)--------- |
|| (16) | |
|| | (virtio-net)------------------
Device Tree is created on the QEMU side based on the information about
devices IO map and IRQ numbers. Kernel will load this DTB using UHI
boot protocol.
Checkpatch script outputs a small number of warnings if applied to
this series. We did not correct the code, since we think the code is
correct for those particular cases of checkpatch warnings.
Aleksandar Markovic (6):
Documentation: Add device tree binding for Goldfish RTC driver
MIPS: ranchu: Add Goldfish RTC driver
Documentation: Add device tree binding for Goldfish PIC driver
MIPS: ranchu: Add Goldfish PIC driver
Documentation: Add device tree binding for Goldfish FB driver
video: goldfishfb: Add support for device tree bindings
Miodrag Dinic (4):
MIPS: ranchu: Add Ranchu as a new generic-based board
MIPS: Introduce check_legacy_ioport() interface
MIPS: i8042: Probe this device only if it exists
MIPS: generic: Add optional support for Android kernel
.../bindings/goldfish/google,goldfish-fb.txt | 18 +++
.../interrupt-controller/google,goldfish-pic.txt | 18 +++
.../bindings/rtc/google,goldfish-rtc.txt | 17 ++
MAINTAINERS | 19 +++
arch/mips/Makefile | 8 +-
arch/mips/configs/generic/android.config | 173 +++++++++++++++++++++
arch/mips/configs/generic/board-ranchu.config | 25 +++
arch/mips/generic/Kconfig | 11 ++
arch/mips/generic/Makefile | 1 +
arch/mips/generic/board-ranchu.c | 83 ++++++++++
arch/mips/include/asm/io.h | 5 +
arch/mips/kernel/setup.c | 41 +++++
drivers/input/serio/i8042-io.h | 2 +-
drivers/irqchip/Kconfig | 9 ++
drivers/irqchip/Makefile | 1 +
drivers/irqchip/irq-goldfish-pic.c | 169 ++++++++++++++++++++
drivers/rtc/Kconfig | 6 +
drivers/rtc/Makefile | 1 +
drivers/rtc/rtc-goldfish.c | 136 ++++++++++++++++
drivers/video/fbdev/goldfishfb.c | 8 +-
20 files changed, 747 insertions(+), 4 deletions(-)
create mode 100644 Documentation/devicetree/bindings/goldfish/google,goldfish-fb.txt
create mode 100644 Documentation/devicetree/bindings/interrupt-controller/google,goldfish-pic.txt
create mode 100644 Documentation/devicetree/bindings/rtc/google,goldfish-rtc.txt
create mode 100644 arch/mips/configs/generic/android.config
create mode 100644 arch/mips/configs/generic/board-ranchu.config
create mode 100644 arch/mips/generic/board-ranchu.c
create mode 100644 drivers/irqchip/irq-goldfish-pic.c
create mode 100644 drivers/rtc/rtc-goldfish.c
--
2.7.4
From: Miodrag Dinic <[email protected]>
Provide amendments to the Mips generic platform framework so that
the new generic-based board Ranchu can be chosen to be built.
Signed-off-by: Miodrag Dinic <[email protected]>
Signed-off-by: Goran Ferenc <[email protected]>
Signed-off-by: Aleksandar Markovic <[email protected]>
---
MAINTAINERS | 6 ++
arch/mips/configs/generic/board-ranchu.config | 25 ++++++++
arch/mips/generic/Kconfig | 11 ++++
arch/mips/generic/Makefile | 1 +
arch/mips/generic/board-ranchu.c | 83 +++++++++++++++++++++++++++
5 files changed, 126 insertions(+)
create mode 100644 arch/mips/configs/generic/board-ranchu.config
create mode 100644 arch/mips/generic/board-ranchu.c
diff --git a/MAINTAINERS b/MAINTAINERS
index fb4c6ea..35dfdd0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -10678,6 +10678,12 @@ S: Maintained
F: Documentation/blockdev/ramdisk.txt
F: drivers/block/brd.c
+RANCHU VIRTUAL BOARD FOR MIPS
+M: Miodrag Dinic <[email protected]>
+L: [email protected]
+S: Supported
+F: arch/mips/generic/board-ranchu.c
+
RANDOM NUMBER DRIVER
M: "Theodore Ts'o" <[email protected]>
S: Maintained
diff --git a/arch/mips/configs/generic/board-ranchu.config b/arch/mips/configs/generic/board-ranchu.config
new file mode 100644
index 0000000..63bac23
--- /dev/null
+++ b/arch/mips/configs/generic/board-ranchu.config
@@ -0,0 +1,25 @@
+CONFIG_VIRT_BOARD_RANCHU=y
+
+CONFIG_BATTERY_GOLDFISH=y
+CONFIG_FB_GOLDFISH=y
+CONFIG_GOLDFISH=y
+CONFIG_GOLDFISH_AUDIO=y
+CONFIG_GOLDFISH_PIC=y
+CONFIG_GOLDFISH_PIPE=y
+CONFIG_GOLDFISH_TTY=y
+CONFIG_RTC_DRV_GOLDFISH=y
+
+CONFIG_INPUT_EVDEV=y
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_GOLDFISH_EVENTS=y
+
+CONFIG_POWER_SUPPLY=y
+CONFIG_POWER_RESET=y
+CONFIG_POWER_RESET_SYSCON=y
+CONFIG_POWER_RESET_SYSCON_POWEROFF=y
+
+CONFIG_VIRTIO_BLK=y
+CONFIG_VIRTIO_CONSOLE=y
+CONFIG_VIRTIO_MMIO=y
+CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y
+CONFIG_VIRTIO_NET=y
diff --git a/arch/mips/generic/Kconfig b/arch/mips/generic/Kconfig
index a606b3f..15be3f9 100644
--- a/arch/mips/generic/Kconfig
+++ b/arch/mips/generic/Kconfig
@@ -16,4 +16,15 @@ config LEGACY_BOARD_SEAD3
Enable this to include support for booting on MIPS SEAD-3 FPGA-based
development boards, which boot using a legacy boot protocol.
+config VIRT_BOARD_RANCHU
+ bool "Ranchu platform for Android emulator"
+ select LEGACY_BOARDS
+ help
+ This enables support for the platform used by Android emulator.
+
+ Ranchu platform consists of a set of virtual devices. This platform
+ enables emulation of variety of virtual configurations while using
+ Android emulator. Android emulator is based on Qemu, and contains
+ the support for the same set of virtual devices.
+
endif
diff --git a/arch/mips/generic/Makefile b/arch/mips/generic/Makefile
index acb9b6d..4ae52f3 100644
--- a/arch/mips/generic/Makefile
+++ b/arch/mips/generic/Makefile
@@ -13,4 +13,5 @@ obj-y += irq.o
obj-y += proc.o
obj-$(CONFIG_LEGACY_BOARD_SEAD3) += board-sead3.o
+obj-$(CONFIG_VIRT_BOARD_RANCHU) += board-ranchu.o
obj-$(CONFIG_KEXEC) += kexec.o
diff --git a/arch/mips/generic/board-ranchu.c b/arch/mips/generic/board-ranchu.c
new file mode 100644
index 0000000..5dc96e5
--- /dev/null
+++ b/arch/mips/generic/board-ranchu.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2017 Imagination Technologies Ltd.
+ * Author: Miodrag Dinic <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <asm/machine.h>
+#include <asm/time.h>
+
+#define GOLDFISH_TIMER_LOW 0x00
+#define GOLDFISH_TIMER_HIGH 0x04
+#define GOLDFISH_TIMER_BASE 0x1f005000
+
+static __init uint64_t read_rtc_time(void __iomem *base)
+{
+ uint64_t time_low;
+ uint64_t time_high;
+ uint64_t time_high_prev;
+
+ time_high = readl(base + GOLDFISH_TIMER_HIGH);
+ do {
+ time_high_prev = time_high;
+ time_low = readl(base + GOLDFISH_TIMER_LOW);
+ time_high = readl(base + GOLDFISH_TIMER_HIGH);
+ } while (time_high != time_high_prev);
+
+ return ((int64_t)time_high << 32) | time_low;
+}
+
+static __init unsigned int ranchu_measure_hpt_freq(void)
+{
+ uint64_t rtc_start, rtc_current, rtc_delta;
+ unsigned int start, count;
+ unsigned int prid = read_c0_prid() & 0xffff00;
+ void __iomem *rtc_base = ioremap(GOLDFISH_TIMER_BASE, 0x1000);
+
+ if (!rtc_base)
+ panic("%s(): Failed to ioremap Goldfish timer base %p!",
+ __func__, (void *)GOLDFISH_TIMER_BASE);
+
+ /*
+ * poll the nanosecond resolution RTC for 1 second
+ * to calibrate the CPU frequency
+ */
+
+ rtc_start = read_rtc_time(rtc_base);
+ start = read_c0_count();
+
+ do {
+ rtc_current = read_rtc_time(rtc_base);
+ rtc_delta = rtc_current - rtc_start;
+ } while (rtc_delta < NSEC_PER_SEC);
+
+ count = read_c0_count() - start;
+
+ mips_hpt_frequency = count;
+ if ((prid != (PRID_COMP_MIPS | PRID_IMP_20KC)) &&
+ (prid != (PRID_COMP_MIPS | PRID_IMP_25KF)))
+ count *= 2;
+
+ count += 5000; /* round */
+ count -= count%10000;
+
+ return count;
+}
+
+static const struct of_device_id ranchu_of_match[];
+
+MIPS_MACHINE(ranchu) = {
+ .matches = ranchu_of_match,
+ .measure_hpt_freq = ranchu_measure_hpt_freq,
+};
+
+static const struct of_device_id ranchu_of_match[] = {
+ {
+ .compatible = "mti,ranchu",
+ .data = &__mips_mach_ranchu,
+ },
+};
--
2.7.4
From: Aleksandar Markovic <[email protected]>
Add documentation for DT binding of Goldfish PIC driver. The compatible
string used by OS for binding the driver is "google,goldfish-pic".
Signed-off-by: Miodrag Dinic <[email protected]>
Signed-off-by: Goran Ferenc <[email protected]>
Signed-off-by: Aleksandar Markovic <[email protected]>
---
.../interrupt-controller/google,goldfish-pic.txt | 18 ++++++++++++++++++
MAINTAINERS | 5 +++++
2 files changed, 23 insertions(+)
create mode 100644 Documentation/devicetree/bindings/interrupt-controller/google,goldfish-pic.txt
diff --git a/Documentation/devicetree/bindings/interrupt-controller/google,goldfish-pic.txt b/Documentation/devicetree/bindings/interrupt-controller/google,goldfish-pic.txt
new file mode 100644
index 0000000..f198762
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/google,goldfish-pic.txt
@@ -0,0 +1,18 @@
+Android Goldfish PIC
+
+Android Goldfish programmable interrupt device used by Android
+emulator.
+
+Required properties:
+
+- compatible : should contain "google,goldfish-pic"
+- reg : <registers mapping>
+- interrupts : <interrupt mapping>
+
+Example:
+
+ goldfish_pic@9020000 {
+ compatible = "google,goldfish-pic";
+ reg = <0x9020000 0x1000>;
+ interrupts = <0x3>;
+ };
diff --git a/MAINTAINERS b/MAINTAINERS
index 26a1267..85da9f0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -841,6 +841,11 @@ S: Supported
F: drivers/android/
F: drivers/staging/android/
+ANDROID GOLDFISH PIC DRIVER
+M: Miodrag Dinic <[email protected]>
+S: Supported
+F: Documentation/devicetree/bindings/interrupt-controller/google,goldfish-pic.txt
+
ANDROID GOLDFISH RTC DRIVER
M: Miodrag Dinic <[email protected]>
S: Supported
--
2.7.4
From: Miodrag Dinic <[email protected]>
This commit adds new android.config configuration file including
the most common prerequisites for running Android operating system.
The selected set of platform independent configuration parameters
have been taken from the official Android kernel repo:
https://android.googlesource.com/kernel/common/+
/android-4.4/android/configs/android-base.cfg
android.config will be merged with the selected generic kernel
configuration only if explicitly specified through environment
variable OS=android.
Example:
make ARCH=mips 64r6el_defconfig BOARDS="list of boards" OS=android
android.config file should be occasionally revisited and updated
with latest requirements from Google.
Signed-off-by: Miodrag Dinic <[email protected]>
Signed-off-by: Goran Ferenc <[email protected]>
Signed-off-by: Aleksandar Markovic <[email protected]>
---
MAINTAINERS | 1 +
arch/mips/Makefile | 8 +-
arch/mips/configs/generic/android.config | 173 +++++++++++++++++++++++++++++++
3 files changed, 180 insertions(+), 2 deletions(-)
create mode 100644 arch/mips/configs/generic/android.config
diff --git a/MAINTAINERS b/MAINTAINERS
index 35dfdd0..0b141eb 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -10683,6 +10683,7 @@ M: Miodrag Dinic <[email protected]>
L: [email protected]
S: Supported
F: arch/mips/generic/board-ranchu.c
+F: arch/mips/configs/generic/android.config
RANDOM NUMBER DRIVER
M: "Theodore Ts'o" <[email protected]>
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index 02a1787..bc96c39 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -448,7 +448,10 @@ define archhelp
echo ' If you are targeting a system supported by generic kernels you may'
echo ' configure the kernel for a given architecture target like so:'
echo
- echo ' {micro32,32,64}{r1,r2,r6}{el,}_defconfig <BOARDS="list of boards">'
+ echo ' {micro32,32,64}{r1,r2,r6}{el,}_defconfig <BOARDS="list of boards"> <OS=android>'
+ echo
+ echo ' By setting OS=android, the generic kernel configuration will enable common'
+ echo ' prerequisites for running Android OS.'
echo
echo ' Otherwise, the following default configurations are available:'
endef
@@ -488,7 +491,8 @@ $(eval $(call gen_generic_defconfigs,micro32,r2,eb el))
$(generic_defconfigs):
$(Q)$(CONFIG_SHELL) $(srctree)/scripts/kconfig/merge_config.sh \
-m -O $(objtree) $(srctree)/arch/$(ARCH)/configs/generic_defconfig $^ \
- $(foreach board,$(BOARDS),$(generic_config_dir)/board-$(board).config)
+ $(foreach board,$(BOARDS),$(generic_config_dir)/board-$(board).config) \
+ $(foreach os,$(OS),$(generic_config_dir)/$(os).config)
$(Q)$(MAKE) -f $(srctree)/Makefile olddefconfig
#
diff --git a/arch/mips/configs/generic/android.config b/arch/mips/configs/generic/android.config
new file mode 100644
index 0000000..8d0c93f
--- /dev/null
+++ b/arch/mips/configs/generic/android.config
@@ -0,0 +1,173 @@
+# CONFIG_DEVKMEM is not set
+# CONFIG_DEVMEM is not set
+# CONFIG_FHANDLE is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_SYSVIPC is not set
+# CONFIG_USELIB is not set
+CONFIG_ANDROID=y
+CONFIG_ANDROID_BINDER_DEVICES="binder,hwbinder,vndbinder"
+CONFIG_ANDROID_BINDER_IPC=y
+CONFIG_ANDROID_LOW_MEMORY_KILLER=y
+CONFIG_ASHMEM=y
+CONFIG_AUDIT=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_CGROUP_DEBUG=y
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CGROUP_SCHED=y
+CONFIG_CGROUPS=y
+CONFIG_DEFAULT_SECURITY_SELINUX=y
+CONFIG_EMBEDDED=y
+CONFIG_FB=y
+CONFIG_HARDENED_USERCOPY=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_INET6_AH=y
+CONFIG_INET6_ESP=y
+CONFIG_INET6_IPCOMP=y
+CONFIG_INET=y
+CONFIG_INET_DIAG_DESTROY=y
+CONFIG_INET_ESP=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_IP6_NF_FILTER=y
+CONFIG_IP6_NF_IPTABLES=y
+CONFIG_IP6_NF_MANGLE=y
+CONFIG_IP6_NF_RAW=y
+CONFIG_IP6_NF_TARGET_REJECT=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_NF_ARP_MANGLE=y
+CONFIG_IP_NF_ARPFILTER=y
+CONFIG_IP_NF_ARPTABLES=y
+CONFIG_IP_NF_FILTER=y
+CONFIG_IP_NF_IPTABLES=y
+CONFIG_IP_NF_MANGLE=y
+CONFIG_IP_NF_MATCH_AH=y
+CONFIG_IP_NF_MATCH_ECN=y
+CONFIG_IP_NF_MATCH_TTL=y
+CONFIG_IP_NF_NAT=y
+CONFIG_IP_NF_RAW=y
+CONFIG_IP_NF_SECURITY=y
+CONFIG_IP_NF_TARGET_MASQUERADE=y
+CONFIG_IP_NF_TARGET_NETMAP=y
+CONFIG_IP_NF_TARGET_REDIRECT=y
+CONFIG_IP_NF_TARGET_REJECT=y
+CONFIG_IPV6=y
+CONFIG_IPV6_MIP6=y
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_IPV6_OPTIMISTIC_DAD=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULES=y
+CONFIG_MODVERSIONS=y
+CONFIG_NET=y
+CONFIG_NET_CLS_ACT=y
+CONFIG_NET_CLS_U32=y
+CONFIG_NET_EMATCH=y
+CONFIG_NET_EMATCH_U32=y
+CONFIG_NET_KEY=y
+CONFIG_NET_SCH_HTB=y
+CONFIG_NET_SCHED=y
+CONFIG_NETDEVICES=y
+CONFIG_NETFILTER=y
+CONFIG_NETFILTER_XT_MATCH_COMMENT=y
+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=y
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y
+CONFIG_NETFILTER_XT_MATCH_HELPER=y
+CONFIG_NETFILTER_XT_MATCH_IPRANGE=y
+CONFIG_NETFILTER_XT_MATCH_LENGTH=y
+CONFIG_NETFILTER_XT_MATCH_LIMIT=y
+CONFIG_NETFILTER_XT_MATCH_MAC=y
+CONFIG_NETFILTER_XT_MATCH_MARK=y
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
+CONFIG_NETFILTER_XT_MATCH_POLICY=y
+CONFIG_NETFILTER_XT_MATCH_QTAGUID=y
+CONFIG_NETFILTER_XT_MATCH_QUOTA2=y
+CONFIG_NETFILTER_XT_MATCH_QUOTA2_LOG=y
+CONFIG_NETFILTER_XT_MATCH_QUOTA=y
+CONFIG_NETFILTER_XT_MATCH_SOCKET=y
+CONFIG_NETFILTER_XT_MATCH_STATE=y
+CONFIG_NETFILTER_XT_MATCH_STATISTIC=y
+CONFIG_NETFILTER_XT_MATCH_STRING=y
+CONFIG_NETFILTER_XT_MATCH_TIME=y
+CONFIG_NETFILTER_XT_MATCH_U32=y
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y
+CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y
+CONFIG_NETFILTER_XT_TARGET_MARK=y
+CONFIG_NETFILTER_XT_TARGET_NFLOG=y
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y
+CONFIG_NETFILTER_XT_TARGET_SECMARK=y
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=y
+CONFIG_NETFILTER_XT_TARGET_TPROXY=y
+CONFIG_NETFILTER_XT_TARGET_TRACE=y
+CONFIG_NF_CONNTRACK=y
+CONFIG_NF_CONNTRACK_AMANDA=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CONNTRACK_FTP=y
+CONFIG_NF_CONNTRACK_H323=y
+CONFIG_NF_CONNTRACK_IPV4=y
+CONFIG_NF_CONNTRACK_IPV6=y
+CONFIG_NF_CONNTRACK_IRC=y
+CONFIG_NF_CONNTRACK_NETBIOS_NS=y
+CONFIG_NF_CONNTRACK_PPTP=y
+CONFIG_NF_CONNTRACK_SANE=y
+CONFIG_NF_CONNTRACK_SECMARK=y
+CONFIG_NF_CONNTRACK_TFTP=y
+CONFIG_NF_CT_NETLINK=y
+CONFIG_NF_CT_PROTO_DCCP=y
+CONFIG_NF_CT_PROTO_SCTP=y
+CONFIG_NF_CT_PROTO_UDPLITE=y
+CONFIG_NF_NAT=y
+CONFIG_NO_HZ=y
+CONFIG_PACKET=y
+CONFIG_PM_AUTOSLEEP=y
+CONFIG_PM_WAKELOCKS=y
+CONFIG_PPP=y
+CONFIG_PPP_BSDCOMP=y
+CONFIG_PPP_DEFLATE=y
+CONFIG_PPP_MPPE=y
+CONFIG_PPPOLAC=y
+CONFIG_PPPOPNS=y
+CONFIG_PREEMPT=y
+CONFIG_PROFILING=y
+CONFIG_QFMT_V2=y
+CONFIG_QUOTA=y
+CONFIG_QUOTA_NETLINK_INTERFACE=y
+CONFIG_QUOTA_TREE=y
+CONFIG_QUOTACTL=y
+CONFIG_RANDOMIZE_BASE=y
+CONFIG_RT_GROUP_SCHED=y
+CONFIG_RTC_CLASS=y
+CONFIG_SECCOMP=y
+CONFIG_SECURITY=y
+CONFIG_SECURITY_NETWORK=y
+CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y
+CONFIG_SECURITY_SELINUX=y
+CONFIG_SETEND_EMULATION=y
+CONFIG_STAGING=y
+CONFIG_SWP_EMULATION=y
+CONFIG_SYNC=y
+CONFIG_TASK_IO_ACCOUNTING=y
+CONFIG_TASK_XACCT=y
+CONFIG_TASKSTATS=y
+CONFIG_TUN=y
+CONFIG_UID_SYS_STATS=y
+CONFIG_UNIX=y
+CONFIG_USB_CONFIGFS=y
+CONFIG_USB_CONFIGFS_F_ACC=y
+CONFIG_USB_CONFIGFS_F_AUDIO_SRC=y
+CONFIG_USB_CONFIGFS_F_FS=y
+CONFIG_USB_CONFIGFS_F_MIDI=y
+CONFIG_USB_CONFIGFS_F_MTP=y
+CONFIG_USB_CONFIGFS_F_PTP=y
+CONFIG_USB_CONFIGFS_UEVENT=y
+CONFIG_USB_GADGET=y
+CONFIG_XFRM_USER=y
--
2.7.4
From: Miodrag Dinic <[email protected]>
ARCH_MIGHT_HAVE_PC_SERIO is selected by default for MIPS platforms.
As a consequence SERIO_I8042 would be automatically selected for any
MIPS board which wants to enable input support like keyboard
(INPUT_KEYBOARD) regardless of i8042 controller existence.
The dependency is as follows :
config ARCH_MIGHT_HAVE_PC_SERIO [=y]
Defined at drivers/input/serio/Kconfig:19
Depends on: !UML
Selected by: MIPS [=y]
config SERIO
Defined at drivers/input/serio/Kconfig:4
default y
Depends on: !UML
Selected by: KEYBOARD_ATKBD [=y] && !UML && INPUT [=y] &&
INPUT_KEYBOARD [=y]
config SERIO_I8042
Defined at drivers/input/serio/Kconfig:28
tristate "i8042 PC Keyboard controller"
default y
Depends on: !UML && SERIO [=y] && ARCH_MIGHT_HAVE_PC_SERIO [=y]
Selected by: KEYBOARD_ATKBD [=y] && !UML && INPUT [=y] &&
INPUT_KEYBOARD [=y] && ARCH_MIGHT_HAVE_PC_SERIO [=y]
If this driver probes the I8042_DATA_REG not knowing if the device
exists it can cause a kernel to crash. Using check_legacy_ioport()
interface we can selectively enable this driver only for the MIPS
boards which actually have the i8042 controller.
New "Ranchu" virtual platform does not support i8042 controller
so it's added to the blacklist match table.
Each MIPS machine should update this table with it's compatible strings
if it does not support i8042 controller.
In order to utilize this mechanism, each MIPS machine that do not
have i8042 controller should update the blacklist table with its
compatible strings.
Signed-off-by: Miodrag Dinic <[email protected]>
Signed-off-by: Goran Ferenc <[email protected]>
Signed-off-by: Aleksandar Markovic <[email protected]>
---
arch/mips/kernel/setup.c | 16 ++++++++++++++++
drivers/input/serio/i8042-io.h | 2 +-
2 files changed, 17 insertions(+), 1 deletion(-)
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index c22cde8..c3e0d2b 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -79,6 +79,15 @@ const unsigned long mips_io_port_base = -1;
EXPORT_SYMBOL(mips_io_port_base);
/*
+ * Here we blacklist all MIPS boards which do not have i8042 controller
+ */
+static const struct of_device_id i8042_blacklist_of_match[] = {
+ { .compatible = "mti,ranchu", },
+ {},
+};
+#define I8042_DATA_REG 0x60
+
+/*
* Check for existence of legacy devices
*
* Some drivers may try to probe some I/O ports which can lead to
@@ -90,9 +99,16 @@ EXPORT_SYMBOL(mips_io_port_base);
*/
int check_legacy_ioport(unsigned long base_port)
{
+ struct device_node *np;
int ret = 0;
switch (base_port) {
+ case I8042_DATA_REG:
+ np = of_find_matching_node(NULL, i8042_blacklist_of_match);
+ if (np)
+ ret = -ENODEV;
+ of_node_put(np);
+ break;
default:
/* We will assume that the I/O device port exists if
* not explicitly added to the blacklist match table
diff --git a/drivers/input/serio/i8042-io.h b/drivers/input/serio/i8042-io.h
index 34da81c..ec5fe9e 100644
--- a/drivers/input/serio/i8042-io.h
+++ b/drivers/input/serio/i8042-io.h
@@ -72,7 +72,7 @@ static inline int i8042_platform_init(void)
* On some platforms touching the i8042 data register region can do really
* bad things. Because of this the region is always reserved on such boxes.
*/
-#if defined(CONFIG_PPC)
+#if defined(CONFIG_PPC) || defined(CONFIG_MIPS)
if (check_legacy_ioport(I8042_DATA_REG))
return -ENODEV;
#endif
--
2.7.4
From: Aleksandar Markovic <[email protected]>
Add documentation for DT binding of Goldfish FB driver. The compatible
string used by OS for binding the driver is "google,goldfish-fb".
Signed-off-by: Miodrag Dinic <[email protected]>
Signed-off-by: Goran Ferenc <[email protected]>
Signed-off-by: Aleksandar Markovic <[email protected]>
---
.../bindings/goldfish/google,goldfish-fb.txt | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
create mode 100644 Documentation/devicetree/bindings/goldfish/google,goldfish-fb.txt
diff --git a/Documentation/devicetree/bindings/goldfish/google,goldfish-fb.txt b/Documentation/devicetree/bindings/goldfish/google,goldfish-fb.txt
new file mode 100644
index 0000000..9ce0615
--- /dev/null
+++ b/Documentation/devicetree/bindings/goldfish/google,goldfish-fb.txt
@@ -0,0 +1,18 @@
+Android Goldfish framebuffer
+
+Android Goldfish framebuffer device used by Android emulator.
+
+Required properties:
+
+- compatible : should contain "google,goldfish-fb"
+- reg : <registers mapping>
+- interrupts : <interrupt mapping>
+
+Example:
+
+ goldfish_fb@1f008000 {
+ compatible = "google,goldfish-fb";
+ interrupts = <0x10>;
+ reg = <0x1f008000 0x0 0x100>;
+ compatible = "google,goldfish-fb";
+ };
--
2.7.4
From: Miodrag Dinic <[email protected]>
Some drivers may try to probe some I/O ports which can lead to kernel
panic if the device is not present and mapped. This function should be
used to check for existence of such devices and return 0 for MIPS
boards which implement them, otherwise it should return -ENODEV and
the affected device driver should never try to read/write the
requested I/O port.
This is particularly useful for multiplaform kernels which are board
agnostic and this interface can be used to match drivers against
available devices on a specific board in runtime.
This patch just adds a no-op check_legacy_ioport() function which will
be enriched with logic in a later patch.
Signed-off-by: Miodrag Dinic <[email protected]>
Signed-off-by: Goran Ferenc <[email protected]>
Signed-off-by: Aleksandar Markovic <[email protected]>
---
arch/mips/include/asm/io.h | 5 +++++
arch/mips/kernel/setup.c | 25 +++++++++++++++++++++++++
2 files changed, 30 insertions(+)
diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h
index ecabc00..62b9f89 100644
--- a/arch/mips/include/asm/io.h
+++ b/arch/mips/include/asm/io.h
@@ -78,6 +78,11 @@ static inline void set_io_port_base(unsigned long base)
}
/*
+ * Check for existence of legacy devices
+ */
+extern int check_legacy_ioport(unsigned long base_port);
+
+/*
* Thanks to James van Artsdalen for a better timing-fix than
* the two short jumps: using outb's to a nonexistent port seems
* to guarantee better timings even on fast machines.
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index 01d1dbd..c22cde8 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -78,6 +78,31 @@ static char __initdata builtin_cmdline[COMMAND_LINE_SIZE] = CONFIG_CMDLINE;
const unsigned long mips_io_port_base = -1;
EXPORT_SYMBOL(mips_io_port_base);
+/*
+ * Check for existence of legacy devices
+ *
+ * Some drivers may try to probe some I/O ports which can lead to
+ * kernel panic if the device is not present and mapped. This method
+ * should check for existence of such devices and return 0 for MIPS
+ * boards which actually have them, otherwise it will return -ENODEV
+ * and the affected device driver should never try to read/write the
+ * requested I/O port.
+ */
+int check_legacy_ioport(unsigned long base_port)
+{
+ int ret = 0;
+
+ switch (base_port) {
+ default:
+ /* We will assume that the I/O device port exists if
+ * not explicitly added to the blacklist match table
+ */
+ break;
+ }
+ return ret;
+}
+EXPORT_SYMBOL(check_legacy_ioport);
+
static struct resource code_resource = { .name = "Kernel code", };
static struct resource data_resource = { .name = "Kernel data", };
--
2.7.4
From: Aleksandar Markovic <[email protected]>
Add documentation for DT binding of Goldfish RTC driver. The compatible
string used by OS for binding the driver is "google,goldfish-rtc".
Signed-off-by: Miodrag Dinic <[email protected]>
Signed-off-by: Goran Ferenc <[email protected]>
Signed-off-by: Aleksandar Markovic <[email protected]>
---
.../devicetree/bindings/rtc/google,goldfish-rtc.txt | 17 +++++++++++++++++
MAINTAINERS | 5 +++++
2 files changed, 22 insertions(+)
create mode 100644 Documentation/devicetree/bindings/rtc/google,goldfish-rtc.txt
diff --git a/Documentation/devicetree/bindings/rtc/google,goldfish-rtc.txt b/Documentation/devicetree/bindings/rtc/google,goldfish-rtc.txt
new file mode 100644
index 0000000..634312d
--- /dev/null
+++ b/Documentation/devicetree/bindings/rtc/google,goldfish-rtc.txt
@@ -0,0 +1,17 @@
+Android Goldfish RTC
+
+Android Goldfish RTC device used by Android emulator.
+
+Required properties:
+
+- compatible : should contain "google,goldfish-rtc"
+- reg : <registers mapping>
+- interrupts : <interrupt mapping>
+
+Example:
+
+ goldfish_timer@9020000 {
+ compatible = "google,goldfish-rtc";
+ reg = <0x9020000 0x1000>;
+ interrupts = <0x3>;
+ };
diff --git a/MAINTAINERS b/MAINTAINERS
index 09b5ab6..519cdef 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -841,6 +841,11 @@ S: Supported
F: drivers/android/
F: drivers/staging/android/
+ANDROID GOLDFISH RTC DRIVER
+M: Miodrag Dinic <[email protected]>
+S: Supported
+F: Documentation/devicetree/bindings/rtc/google,goldfish-rtc.txt
+
ANDROID ION DRIVER
M: Laura Abbott <[email protected]>
M: Sumit Semwal <[email protected]>
--
2.7.4
From: Aleksandar Markovic <[email protected]>
Add device driver for a virtual Goldfish RTC clock.
The driver can be built only if CONFIG_MIPS and CONFIG_GOLDFISH are
set. The compatible string used by OS for binding the driver is
defined as "google,goldfish-rtc".
Signed-off-by: Miodrag Dinic <[email protected]>
Signed-off-by: Goran Ferenc <[email protected]>
Signed-off-by: Aleksandar Markovic <[email protected]>
---
MAINTAINERS | 1 +
drivers/rtc/Kconfig | 6 ++
drivers/rtc/Makefile | 1 +
drivers/rtc/rtc-goldfish.c | 136 +++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 144 insertions(+)
create mode 100644 drivers/rtc/rtc-goldfish.c
diff --git a/MAINTAINERS b/MAINTAINERS
index 519cdef..26a1267 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -845,6 +845,7 @@ ANDROID GOLDFISH RTC DRIVER
M: Miodrag Dinic <[email protected]>
S: Supported
F: Documentation/devicetree/bindings/rtc/google,goldfish-rtc.txt
+F: drivers/rtc/rtc-goldfish.c
ANDROID ION DRIVER
M: Laura Abbott <[email protected]>
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 8d3b957..510c5b7 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -1753,5 +1753,11 @@ config RTC_DRV_HID_SENSOR_TIME
If this driver is compiled as a module, it will be named
rtc-hid-sensor-time.
+config RTC_DRV_GOLDFISH
+ tristate "Goldfish Real Time Clock"
+ depends on MIPS
+ depends on GOLDFISH
+ help
+ Say yes here to build support for the Goldfish RTC.
endif # RTC_CLASS
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 13857d2..dfc38f5 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -168,3 +168,4 @@ obj-$(CONFIG_RTC_DRV_WM8350) += rtc-wm8350.o
obj-$(CONFIG_RTC_DRV_X1205) += rtc-x1205.o
obj-$(CONFIG_RTC_DRV_XGENE) += rtc-xgene.o
obj-$(CONFIG_RTC_DRV_ZYNQMP) += rtc-zynqmp.o
+obj-$(CONFIG_RTC_DRV_GOLDFISH) += rtc-goldfish.o
diff --git a/drivers/rtc/rtc-goldfish.c b/drivers/rtc/rtc-goldfish.c
new file mode 100644
index 0000000..e206a98
--- /dev/null
+++ b/drivers/rtc/rtc-goldfish.c
@@ -0,0 +1,136 @@
+/* drivers/rtc/rtc-goldfish.c
+ *
+ * Copyright (C) 2007 Google, Inc.
+ * Copyright (C) 2017 Imagination Technologies Ltd.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/rtc.h>
+
+#define TIMER_TIME_LOW 0x00 /* get low bits of current time */
+ /* and update TIMER_TIME_HIGH */
+#define TIMER_TIME_HIGH 0x04 /* get high bits of time at last */
+ /* TIMER_TIME_LOW read */
+#define TIMER_ALARM_LOW 0x08 /* set low bits of alarm and */
+ /* activate it */
+#define TIMER_ALARM_HIGH 0x0c /* set high bits of next alarm */
+#define TIMER_CLEAR_INTERRUPT 0x10
+#define TIMER_CLEAR_ALARM 0x14
+
+struct goldfish_rtc {
+ void __iomem *base;
+ u32 irq;
+ struct rtc_device *rtc;
+};
+
+static irqreturn_t goldfish_rtc_interrupt(int irq, void *dev_id)
+{
+ struct goldfish_rtc *qrtc = dev_id;
+ unsigned long events = 0;
+ void __iomem *base = qrtc->base;
+
+ writel(1, base + TIMER_CLEAR_INTERRUPT);
+ events = RTC_IRQF | RTC_AF;
+
+ rtc_update_irq(qrtc->rtc, 1, events);
+
+ return IRQ_HANDLED;
+}
+
+static int goldfish_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+ u64 time;
+ u64 time_low;
+ u64 time_high;
+ u64 time_high_prev;
+
+ struct goldfish_rtc *qrtc =
+ platform_get_drvdata(to_platform_device(dev));
+ void __iomem *base = qrtc->base;
+
+ time_high = readl(base + TIMER_TIME_HIGH);
+ do {
+ time_high_prev = time_high;
+ time_low = readl(base + TIMER_TIME_LOW);
+ time_high = readl(base + TIMER_TIME_HIGH);
+ } while (time_high != time_high_prev);
+ time = (time_high << 32) | time_low;
+
+ do_div(time, NSEC_PER_SEC);
+
+ rtc_time_to_tm(time, tm);
+
+ return 0;
+}
+
+static const struct rtc_class_ops goldfish_rtc_ops = {
+ .read_time = goldfish_rtc_read_time,
+};
+
+static int goldfish_rtc_probe(struct platform_device *pdev)
+{
+ struct resource *r;
+ struct goldfish_rtc *qrtc;
+ unsigned long rtc_dev_len;
+ unsigned long rtc_dev_addr;
+ int err;
+
+ qrtc = devm_kzalloc(&pdev->dev, sizeof(*qrtc), GFP_KERNEL);
+ if (qrtc == NULL)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, qrtc);
+
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (r == NULL)
+ return -ENODEV;
+
+ rtc_dev_addr = r->start;
+ rtc_dev_len = resource_size(r);
+ qrtc->base = devm_ioremap(&pdev->dev, rtc_dev_addr, rtc_dev_len);
+ if (IS_ERR(qrtc->base))
+ return -ENODEV;
+
+ qrtc->irq = platform_get_irq(pdev, 0);
+ if (qrtc->irq < 0)
+ return -ENODEV;
+
+ qrtc->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
+ &goldfish_rtc_ops, THIS_MODULE);
+ if (IS_ERR(qrtc->rtc))
+ return PTR_ERR(qrtc->rtc);
+
+ err = devm_request_irq(&pdev->dev, qrtc->irq, goldfish_rtc_interrupt,
+ 0, pdev->name, qrtc);
+ if (err)
+ return err;
+
+ return 0;
+}
+
+static const struct of_device_id goldfish_rtc_of_match[] = {
+ { .compatible = "google,goldfish-rtc", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, goldfish_rtc_of_match);
+
+static struct platform_driver goldfish_rtc = {
+ .probe = goldfish_rtc_probe,
+ .driver = {
+ .name = "goldfish_rtc",
+ .of_match_table = goldfish_rtc_of_match,
+ }
+};
+
+module_platform_driver(goldfish_rtc);
--
2.7.4
From: Aleksandar Markovic <[email protected]>
Add ability to the Goldfish FB driver to be recognized by OS via DT.
Signed-off-by: Miodrag Dinic <[email protected]>
Signed-off-by: Goran Ferenc <[email protected]>
Signed-off-by: Aleksandar Markovic <[email protected]>
---
drivers/video/fbdev/goldfishfb.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/video/fbdev/goldfishfb.c b/drivers/video/fbdev/goldfishfb.c
index 7f6c9e6..3b70044 100644
--- a/drivers/video/fbdev/goldfishfb.c
+++ b/drivers/video/fbdev/goldfishfb.c
@@ -304,12 +304,18 @@ static int goldfish_fb_remove(struct platform_device *pdev)
return 0;
}
+static const struct of_device_id goldfish_fb_of_match[] = {
+ { .compatible = "google,goldfish-fb", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, goldfish_fb_of_match);
static struct platform_driver goldfish_fb_driver = {
.probe = goldfish_fb_probe,
.remove = goldfish_fb_remove,
.driver = {
- .name = "goldfish_fb"
+ .name = "goldfish_fb",
+ .of_match_table = goldfish_fb_of_match,
}
};
--
2.7.4
From: Aleksandar Markovic <[email protected]>
Add device driver for a virtual programmable interrupt controller
The virtual PIC is designed as a device tree-based interrupt controller.
The compatible string used by OS for binding the driver is
"google,goldfish-pic".
Signed-off-by: Miodrag Dinic <[email protected]>
Signed-off-by: Goran Ferenc <[email protected]>
Signed-off-by: Aleksandar Markovic <[email protected]>
---
MAINTAINERS | 1 +
drivers/irqchip/Kconfig | 9 ++
drivers/irqchip/Makefile | 1 +
drivers/irqchip/irq-goldfish-pic.c | 169 +++++++++++++++++++++++++++++++++++++
4 files changed, 180 insertions(+)
create mode 100644 drivers/irqchip/irq-goldfish-pic.c
diff --git a/MAINTAINERS b/MAINTAINERS
index 85da9f0..fb4c6ea 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -845,6 +845,7 @@ ANDROID GOLDFISH PIC DRIVER
M: Miodrag Dinic <[email protected]>
S: Supported
F: Documentation/devicetree/bindings/interrupt-controller/google,goldfish-pic.txt
+F: drivers/irqchip/irq-goldfish-pic.c
ANDROID GOLDFISH RTC DRIVER
M: Miodrag Dinic <[email protected]>
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 478f8ac..6c2f924 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -301,3 +301,12 @@ config QCOM_IRQ_COMBINER
help
Say yes here to add support for the IRQ combiner devices embedded
in Qualcomm Technologies chips.
+
+config GOLDFISH_PIC
+ bool "Goldfish programmable interrupt controller"
+ depends on MIPS
+ depends on GOLDFISH
+ select IRQ_DOMAIN
+ help
+ Say yes here to enable Goldfish interrupt controller driver used
+ for Goldfish based virtual platforms.
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index b64c59b..5e73932 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -76,3 +76,4 @@ 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
+obj-$(CONFIG_GOLDFISH_PIC) += irq-goldfish-pic.o
diff --git a/drivers/irqchip/irq-goldfish-pic.c b/drivers/irqchip/irq-goldfish-pic.c
new file mode 100644
index 0000000..d0e4c2d
--- /dev/null
+++ b/drivers/irqchip/irq-goldfish-pic.c
@@ -0,0 +1,169 @@
+/* drivers/irqchip/irq-goldfish-pic.c
+ *
+ * Copyright (C) 2007 Google, Inc.
+ * Copyright (C) 2017 Imagination Technologies Ltd.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/interrupt.h>
+#include <linux/irqchip.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#include <asm/setup.h>
+
+/* 0..7 MIPS CPU interrupts */
+#define GOLDFISH_CPU_IRQ_PIC (MIPS_CPU_IRQ_BASE + 2)
+#define GOLDFISH_CPU_IRQ_FIQ (MIPS_CPU_IRQ_BASE + 3) /* Not used? */
+#define GOLDFISH_CPU_IRQ_COMPARE (MIPS_CPU_IRQ_BASE + 7)
+
+#define GOLDFISH_NR_IRQS 40
+/* 8..39 Cascaded Goldfish PIC interrupts */
+#define GOLDFISH_IRQ_OFFSET 8
+
+#define GOLDFISH_PIC_NUMBER 0x04
+#define GOLDFISH_PIC_DISABLE_ALL 0x08
+#define GOLDFISH_PIC_DISABLE 0x0c
+#define GOLDFISH_PIC_ENABLE 0x10
+
+static struct irq_domain *goldfish_pic_domain;
+static void __iomem *goldfish_pic_base;
+
+void goldfish_mask_irq(struct irq_data *d)
+{
+ writel(d->irq - GOLDFISH_IRQ_OFFSET,
+ goldfish_pic_base + GOLDFISH_PIC_DISABLE);
+}
+
+void goldfish_unmask_irq(struct irq_data *d)
+{
+ writel(d->irq - GOLDFISH_IRQ_OFFSET,
+ goldfish_pic_base + GOLDFISH_PIC_ENABLE);
+}
+
+static struct irq_chip goldfish_irq_chip = {
+ .name = "goldfish",
+ .irq_mask = goldfish_mask_irq,
+ .irq_mask_ack = goldfish_mask_irq,
+ .irq_unmask = goldfish_unmask_irq,
+};
+
+void goldfish_irq_dispatch(void)
+{
+ uint32_t irq;
+
+ /*
+ * Disable all interrupt sources
+ */
+ irq = readl(goldfish_pic_base + GOLDFISH_PIC_NUMBER);
+ do_IRQ(GOLDFISH_IRQ_OFFSET + irq);
+}
+
+void goldfish_fiq_dispatch(void)
+{
+ panic("goldfish_fiq_dispatch");
+}
+
+static void goldfish_ip2_irq_dispatch(struct irq_desc *desc)
+{
+ unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
+
+ if (pending & CAUSEF_IP2)
+ goldfish_irq_dispatch();
+ else if (pending & CAUSEF_IP3)
+ goldfish_fiq_dispatch();
+ else if (pending & CAUSEF_IP7)
+ do_IRQ(MIPS_CPU_IRQ_BASE + 7);
+ else
+ spurious_interrupt();
+}
+
+static struct irqaction cascade = {
+ .handler = no_action,
+ .flags = IRQF_NO_THREAD,
+ .name = "cascade",
+};
+
+static void mips_timer_dispatch(void)
+{
+ do_IRQ(MIPS_CPU_IRQ_BASE + GOLDFISH_CPU_IRQ_COMPARE);
+}
+
+static int goldfish_pic_map(struct irq_domain *d, unsigned int irq,
+ irq_hw_number_t hw)
+{
+ struct irq_chip *chip = &goldfish_irq_chip;
+
+ if (hw < GOLDFISH_IRQ_OFFSET)
+ return 0;
+
+ irq_set_chip_and_handler(hw, chip, handle_level_irq);
+
+ return 0;
+}
+
+static const struct irq_domain_ops irq_domain_ops = {
+ .xlate = irq_domain_xlate_onetwocell,
+ .map = goldfish_pic_map,
+};
+
+int __init goldfish_pic_of_init(struct device_node *node,
+ struct device_node *parent)
+{
+ struct resource res;
+
+ if (of_address_to_resource(node, 0, &res)) {
+ pr_err("%s(): Failed to get icu memory range", __func__);
+ return -ENODEV;
+ }
+
+ if (request_mem_region(res.start, resource_size(&res),
+ res.name) < 0) {
+ pr_err("%s(): Failed to request icu memory", __func__);
+ return -ENOMEM;
+ }
+
+ goldfish_pic_base = ioremap_nocache(res.start, resource_size(&res));
+ if (!goldfish_pic_base) {
+ pr_err("%s(): Failed to remap icu memory", __func__);
+ release_mem_region(res.start, resource_size(&res));
+ return -ENOMEM;
+ }
+
+ /*
+ * Disable all interrupt sources
+ */
+ writel(1, goldfish_pic_base + GOLDFISH_PIC_DISABLE_ALL);
+
+ if (cpu_has_vint) {
+ pr_info("Setting up vectored interrupts\n");
+ set_vi_handler(GOLDFISH_CPU_IRQ_PIC, goldfish_irq_dispatch);
+ set_vi_handler(GOLDFISH_CPU_IRQ_FIQ, goldfish_fiq_dispatch);
+ set_vi_handler(GOLDFISH_CPU_IRQ_COMPARE, mips_timer_dispatch);
+ } else {
+ irq_set_chained_handler(GOLDFISH_CPU_IRQ_PIC,
+ goldfish_ip2_irq_dispatch);
+ }
+
+ setup_irq(MIPS_CPU_IRQ_BASE+GOLDFISH_CPU_IRQ_PIC, &cascade);
+ setup_irq(MIPS_CPU_IRQ_BASE+GOLDFISH_CPU_IRQ_FIQ, &cascade);
+
+ goldfish_pic_domain = irq_domain_add_linear(node, GOLDFISH_NR_IRQS,
+ &irq_domain_ops, 0);
+ if (!goldfish_pic_domain)
+ panic("Failed to add IRQ domain");
+
+ return 0;
+}
+
+IRQCHIP_DECLARE(google_goldfish_pic, "google,goldfish-pic",
+ goldfish_pic_of_init);
--
2.7.4
On Wed, Jun 28, 2017 at 05:47:03PM +0200, Aleksandar Markovic wrote:
> From: Miodrag Dinic <[email protected]>
>
> This commit adds new android.config configuration file including
> the most common prerequisites for running Android operating system.
>
> The selected set of platform independent configuration parameters
> have been taken from the official Android kernel repo:
> https://android.googlesource.com/kernel/common/+
> /android-4.4/android/configs/android-base.cfg
>
> android.config will be merged with the selected generic kernel
> configuration only if explicitly specified through environment
> variable OS=android.
>
> Example:
> make ARCH=mips 64r6el_defconfig BOARDS="list of boards" OS=android
>
> android.config file should be occasionally revisited and updated
> with latest requirements from Google.
>
> Signed-off-by: Miodrag Dinic <[email protected]>
> Signed-off-by: Goran Ferenc <[email protected]>
> Signed-off-by: Aleksandar Markovic <[email protected]>
> ---
> MAINTAINERS | 1 +
> arch/mips/Makefile | 8 +-
> arch/mips/configs/generic/android.config | 173 +++++++++++++++++++++++++++++++
Why is this a MIPS config file? What about the "generic" android
configs we already have? Shouldn't they work just as well here?
And finally, does this config file fragment pass the latest tests that
Google has for kernel config requirements?
thanks,
greg k-h
On 28/06/17 16:46, Aleksandar Markovic wrote:
> From: Aleksandar Markovic <[email protected]>
>
> Add device driver for a virtual programmable interrupt controller
>
> The virtual PIC is designed as a device tree-based interrupt controller.
>
> The compatible string used by OS for binding the driver is
> "google,goldfish-pic".
>
> Signed-off-by: Miodrag Dinic <[email protected]>
> Signed-off-by: Goran Ferenc <[email protected]>
> Signed-off-by: Aleksandar Markovic <[email protected]>
> ---
> MAINTAINERS | 1 +
> drivers/irqchip/Kconfig | 9 ++
> drivers/irqchip/Makefile | 1 +
> drivers/irqchip/irq-goldfish-pic.c | 169 +++++++++++++++++++++++++++++++++++++
> 4 files changed, 180 insertions(+)
> create mode 100644 drivers/irqchip/irq-goldfish-pic.c
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 85da9f0..fb4c6ea 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -845,6 +845,7 @@ ANDROID GOLDFISH PIC DRIVER
> M: Miodrag Dinic <[email protected]>
> S: Supported
> F: Documentation/devicetree/bindings/interrupt-controller/google,goldfish-pic.txt
> +F: drivers/irqchip/irq-goldfish-pic.c
>
> ANDROID GOLDFISH RTC DRIVER
> M: Miodrag Dinic <[email protected]>
> diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
> index 478f8ac..6c2f924 100644
> --- a/drivers/irqchip/Kconfig
> +++ b/drivers/irqchip/Kconfig
> @@ -301,3 +301,12 @@ config QCOM_IRQ_COMBINER
> help
> Say yes here to add support for the IRQ combiner devices embedded
> in Qualcomm Technologies chips.
> +
> +config GOLDFISH_PIC
> + bool "Goldfish programmable interrupt controller"
> + depends on MIPS
> + depends on GOLDFISH
> + select IRQ_DOMAIN
> + help
> + Say yes here to enable Goldfish interrupt controller driver used
> + for Goldfish based virtual platforms.
> diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
> index b64c59b..5e73932 100644
> --- a/drivers/irqchip/Makefile
> +++ b/drivers/irqchip/Makefile
> @@ -76,3 +76,4 @@ 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
> +obj-$(CONFIG_GOLDFISH_PIC) += irq-goldfish-pic.o
> diff --git a/drivers/irqchip/irq-goldfish-pic.c b/drivers/irqchip/irq-goldfish-pic.c
> new file mode 100644
> index 0000000..d0e4c2d
> --- /dev/null
> +++ b/drivers/irqchip/irq-goldfish-pic.c
> @@ -0,0 +1,169 @@
> +/* drivers/irqchip/irq-goldfish-pic.c
> + *
> + * Copyright (C) 2007 Google, Inc.
> + * Copyright (C) 2017 Imagination Technologies Ltd.
> + *
> + * This software is licensed under the terms of the GNU General Public
> + * License version 2, as published by the Free Software Foundation, and
> + * may be copied, distributed, and modified under those terms.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + */
> +
> +#include <linux/interrupt.h>
> +#include <linux/irqchip.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +
> +#include <asm/setup.h>
> +
> +/* 0..7 MIPS CPU interrupts */
> +#define GOLDFISH_CPU_IRQ_PIC (MIPS_CPU_IRQ_BASE + 2)
> +#define GOLDFISH_CPU_IRQ_FIQ (MIPS_CPU_IRQ_BASE + 3) /* Not used? */
> +#define GOLDFISH_CPU_IRQ_COMPARE (MIPS_CPU_IRQ_BASE + 7)
> +
> +#define GOLDFISH_NR_IRQS 40
> +/* 8..39 Cascaded Goldfish PIC interrupts */
> +#define GOLDFISH_IRQ_OFFSET 8
> +
> +#define GOLDFISH_PIC_NUMBER 0x04
> +#define GOLDFISH_PIC_DISABLE_ALL 0x08
> +#define GOLDFISH_PIC_DISABLE 0x0c
> +#define GOLDFISH_PIC_ENABLE 0x10
> +
> +static struct irq_domain *goldfish_pic_domain;
> +static void __iomem *goldfish_pic_base;
> +
> +void goldfish_mask_irq(struct irq_data *d)
> +{
> + writel(d->irq - GOLDFISH_IRQ_OFFSET,
> + goldfish_pic_base + GOLDFISH_PIC_DISABLE);
This makes exactly zero sense. You're using the Linux irq, which is just
a random number, and write that to the HW?
> +}
> +
> +void goldfish_unmask_irq(struct irq_data *d)
> +{
> + writel(d->irq - GOLDFISH_IRQ_OFFSET,
> + goldfish_pic_base + GOLDFISH_PIC_ENABLE);
> +}
> +
> +static struct irq_chip goldfish_irq_chip = {
> + .name = "goldfish",
> + .irq_mask = goldfish_mask_irq,
> + .irq_mask_ack = goldfish_mask_irq,
> + .irq_unmask = goldfish_unmask_irq,
> +};
> +
> +void goldfish_irq_dispatch(void)
> +{
> + uint32_t irq;
> +
> + /*
> + * Disable all interrupt sources
> + */
> + irq = readl(goldfish_pic_base + GOLDFISH_PIC_NUMBER);
> + do_IRQ(GOLDFISH_IRQ_OFFSET + irq);
> +}
> +
> +void goldfish_fiq_dispatch(void)
> +{
> + panic("goldfish_fiq_dispatch");
> +}
> +
> +static void goldfish_ip2_irq_dispatch(struct irq_desc *desc)
> +{
> + unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
> +
> + if (pending & CAUSEF_IP2)
> + goldfish_irq_dispatch();
> + else if (pending & CAUSEF_IP3)
> + goldfish_fiq_dispatch();
> + else if (pending & CAUSEF_IP7)
> + do_IRQ(MIPS_CPU_IRQ_BASE + 7);
> + else
> + spurious_interrupt();
> +}
> +
> +static struct irqaction cascade = {
> + .handler = no_action,
> + .flags = IRQF_NO_THREAD,
> + .name = "cascade",
> +};
> +
> +static void mips_timer_dispatch(void)
> +{
> + do_IRQ(MIPS_CPU_IRQ_BASE + GOLDFISH_CPU_IRQ_COMPARE);
> +}
> +
> +static int goldfish_pic_map(struct irq_domain *d, unsigned int irq,
> + irq_hw_number_t hw)
> +{
> + struct irq_chip *chip = &goldfish_irq_chip;
> +
> + if (hw < GOLDFISH_IRQ_OFFSET)
> + return 0;
> +
> + irq_set_chip_and_handler(hw, chip, handle_level_irq);
Ah, right. No. Really. You're completely confusing irq and hwirq. You
really have to chose: either your system is DT driven, and you
completely disassociate irq and hwirq (that's what the irq domain is
for), or it is the same thing, and there is no irq domain (and no DT
either).
As it stands, this looks like a driver that has been DT-ified in a
hurry, without actually trying to make it fit in.
> +
> + return 0;
> +}
> +
> +static const struct irq_domain_ops irq_domain_ops = {
> + .xlate = irq_domain_xlate_onetwocell,
> + .map = goldfish_pic_map,
> +};
> +
> +int __init goldfish_pic_of_init(struct device_node *node,
> + struct device_node *parent)
> +{
> + struct resource res;
> +
> + if (of_address_to_resource(node, 0, &res)) {
> + pr_err("%s(): Failed to get icu memory range", __func__);
> + return -ENODEV;
> + }
> +
> + if (request_mem_region(res.start, resource_size(&res),
> + res.name) < 0) {
> + pr_err("%s(): Failed to request icu memory", __func__);
> + return -ENOMEM;
> + }
> +
> + goldfish_pic_base = ioremap_nocache(res.start, resource_size(&res));
All of the above should replaced by a single of_iomap.
> + if (!goldfish_pic_base) {
> + pr_err("%s(): Failed to remap icu memory", __func__);
> + release_mem_region(res.start, resource_size(&res));
> + return -ENOMEM;
> + }
> +
> + /*
> + * Disable all interrupt sources
> + */
> + writel(1, goldfish_pic_base + GOLDFISH_PIC_DISABLE_ALL);
> +
> + if (cpu_has_vint) {
> + pr_info("Setting up vectored interrupts\n");
> + set_vi_handler(GOLDFISH_CPU_IRQ_PIC, goldfish_irq_dispatch);
> + set_vi_handler(GOLDFISH_CPU_IRQ_FIQ, goldfish_fiq_dispatch);
> + set_vi_handler(GOLDFISH_CPU_IRQ_COMPARE, mips_timer_dispatch);
> + } else {
> + irq_set_chained_handler(GOLDFISH_CPU_IRQ_PIC,
> + goldfish_ip2_irq_dispatch);
> + }
> +
> + setup_irq(MIPS_CPU_IRQ_BASE+GOLDFISH_CPU_IRQ_PIC, &cascade);
> + setup_irq(MIPS_CPU_IRQ_BASE+GOLDFISH_CPU_IRQ_FIQ, &cascade);
The problem here is that you're mixing HW interrupt numbers (the VI
stuff) and things that should never be a HW interrupt number.
> +
> + goldfish_pic_domain = irq_domain_add_linear(node, GOLDFISH_NR_IRQS,
> + &irq_domain_ops, 0);
And if you're going to confuse irq and hwirq, this is definitely not the
irqdomain you want, but a legacy domain instead.
> + if (!goldfish_pic_domain)
> + panic("Failed to add IRQ domain");
> +
> + return 0;
> +}
> +
> +IRQCHIP_DECLARE(google_goldfish_pic, "google,goldfish-pic",
> + goldfish_pic_of_init);
>
As it stands, this needs a major amount of reworking. You're most
probably better off rewriting it from scratch instead of tinkering with
what looks like 10+ year old code...
Thanks,
M.
--
Jazz is not dead. It just smells funny...
On Wed, Jun 28, 2017 at 10:46 AM, Aleksandar Markovic
<[email protected]> wrote:
> From: Aleksandar Markovic <[email protected]>
>
> Add documentation for DT binding of Goldfish FB driver. The compatible
> string used by OS for binding the driver is "google,goldfish-fb".
>
> Signed-off-by: Miodrag Dinic <[email protected]>
> Signed-off-by: Goran Ferenc <[email protected]>
> Signed-off-by: Aleksandar Markovic <[email protected]>
> ---
> .../bindings/goldfish/google,goldfish-fb.txt | 18 ++++++++++++++++++
bindings/display/
I don't know that this should even go upstream. There's no upstream
qemu support for goldfish-fb. Maybe this is a minor driver change, but
FB drivers are being replaced with DRM drivers. And the time for AOSP
supporting framebuffer drivers is limited I think with HWC2 and
explicit fence support in DRM.
Rob
On Wed, Jun 28, 2017 at 10:46 AM, Aleksandar Markovic
<[email protected]> wrote:
> From: Aleksandar Markovic <[email protected]>
>
> Add documentation for DT binding of Goldfish PIC driver. The compatible
> string used by OS for binding the driver is "google,goldfish-pic".
This isn't even supported in Google's common kernel tree. If it's not
important enough for it, why should it be for mainline kernel?
To put it another way, why does goldfish need a special interrupt
controller. Just use one of the many that are already supported in the
kernel and emulated by qemu.
Same comments apply to the RTC patch.
Rob
Hi,
The subject doesn't fit the subsystem style, this needs to be changed.
On 28/06/2017 at 17:46:55 +0200, Aleksandar Markovic wrote:
> From: Aleksandar Markovic <[email protected]>
>
> Add device driver for a virtual Goldfish RTC clock.
>
> The driver can be built only if CONFIG_MIPS and CONFIG_GOLDFISH are
> set. The compatible string used by OS for binding the driver is
> defined as "google,goldfish-rtc".
>
Is it really MIPS specific? I would expect the same driver to work on
the ARM based emulator too.
> +config RTC_DRV_GOLDFISH
> + tristate "Goldfish Real Time Clock"
> + depends on MIPS
> + depends on GOLDFISH
This should be made buildable with COMPILE_TEST to extend coverage.
> + help
> + Say yes here to build support for the Goldfish RTC.
Please, don't expect anybody to actually know what is goldfish can you
add a sentence or two?
> +static irqreturn_t goldfish_rtc_interrupt(int irq, void *dev_id)
> +{
> + struct goldfish_rtc *qrtc = dev_id;
> + unsigned long events = 0;
> + void __iomem *base = qrtc->base;
> +
> + writel(1, base + TIMER_CLEAR_INTERRUPT);
> + events = RTC_IRQF | RTC_AF;
> +
> + rtc_update_irq(qrtc->rtc, 1, events);
I'd say that events is not needed you can pass the flags directly to
rtc_update_irq
> +static int goldfish_rtc_read_time(struct device *dev, struct rtc_time *tm)
> +{
> + u64 time;
> + u64 time_low;
> + u64 time_high;
> + u64 time_high_prev;
> +
> + struct goldfish_rtc *qrtc =
> + platform_get_drvdata(to_platform_device(dev));
> + void __iomem *base = qrtc->base;
> +
> + time_high = readl(base + TIMER_TIME_HIGH);
> + do {
> + time_high_prev = time_high;
> + time_low = readl(base + TIMER_TIME_LOW);
> + time_high = readl(base + TIMER_TIME_HIGH);
> + } while (time_high != time_high_prev);
I'm not sure why you need that loop as the comments for TIMER_TIME_LOW
and TIMER_TIME_HIGH indicate that TIMER_TIME_HIGH is latched when
TIMER_TIME_LOW is read. Note that the original driver from google
doesn't do that.
> + time = (time_high << 32) | time_low;
> +
> + do_div(time, NSEC_PER_SEC);
> +
> + rtc_time_to_tm(time, tm);
> +
> + return 0;
> +}
> +
> +static const struct rtc_class_ops goldfish_rtc_ops = {
> + .read_time = goldfish_rtc_read_time,
> +};
> +
> +static int goldfish_rtc_probe(struct platform_device *pdev)
> +{
> + struct resource *r;
> + struct goldfish_rtc *qrtc;
> + unsigned long rtc_dev_len;
> + unsigned long rtc_dev_addr;
> + int err;
> +
> + qrtc = devm_kzalloc(&pdev->dev, sizeof(*qrtc), GFP_KERNEL);
> + if (qrtc == NULL)
> + return -ENOMEM;
> +
> + platform_set_drvdata(pdev, qrtc);
> +
> + r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> + if (r == NULL)
> + return -ENODEV;
> +
> + rtc_dev_addr = r->start;
> + rtc_dev_len = resource_size(r);
> + qrtc->base = devm_ioremap(&pdev->dev, rtc_dev_addr, rtc_dev_len);
devm_ioremap_resource ?
> + if (IS_ERR(qrtc->base))
> + return -ENODEV;
> +
> + qrtc->irq = platform_get_irq(pdev, 0);
> + if (qrtc->irq < 0)
> + return -ENODEV;
> +
Is the irq so important that you have to fail here even if the driver
doesn't support any alarm?
> + qrtc->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
> + &goldfish_rtc_ops, THIS_MODULE);
> + if (IS_ERR(qrtc->rtc))
> + return PTR_ERR(qrtc->rtc);
> +
> + err = devm_request_irq(&pdev->dev, qrtc->irq, goldfish_rtc_interrupt,
> + 0, pdev->name, qrtc);
> + if (err)
> + return err;
Ditto.
--
Alexandre Belloni, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
Hi Greg,
> Why is this a MIPS config file? What about the "generic" android
> configs we already have? Shouldn't they work just as well here?
You are right, this should not be MIPS specific config.
This patch will be omitted in the next version.
Thanks!
Kind regards,
Miodrag
________________________________________
From: Greg Kroah-Hartman [[email protected]]
Sent: Wednesday, June 28, 2017 6:27 PM
To: Aleksandar Markovic
Cc: [email protected]; Miodrag Dinic; Goran Ferenc; Aleksandar Markovic; David S. Miller; Douglas Leung; James Hogan; [email protected]; Martin K. Petersen; Mauro Carvalho Chehab; Paul Burton; Petar Jovanovic; Raghu Gandham; Ralf Baechle
Subject: Re: [PATCH v2 10/10] MIPS: generic: Add optional support for Android kernel
On Wed, Jun 28, 2017 at 05:47:03PM +0200, Aleksandar Markovic wrote:
> From: Miodrag Dinic <[email protected]>
>
> This commit adds new android.config configuration file including
> the most common prerequisites for running Android operating system.
>
> The selected set of platform independent configuration parameters
> have been taken from the official Android kernel repo:
> https://android.googlesource.com/kernel/common/+
> /android-4.4/android/configs/android-base.cfg
>
> android.config will be merged with the selected generic kernel
> configuration only if explicitly specified through environment
> variable OS=android.
>
> Example:
> make ARCH=mips 64r6el_defconfig BOARDS="list of boards" OS=android
>
> android.config file should be occasionally revisited and updated
> with latest requirements from Google.
>
> Signed-off-by: Miodrag Dinic <[email protected]>
> Signed-off-by: Goran Ferenc <[email protected]>
> Signed-off-by: Aleksandar Markovic <[email protected]>
> ---
> MAINTAINERS | 1 +
> arch/mips/Makefile | 8 +-
> arch/mips/configs/generic/android.config | 173 +++++++++++++++++++++++++++++++
Why is this a MIPS config file? What about the "generic" android
configs we already have? Shouldn't they work just as well here?
And finally, does this config file fragment pass the latest tests that
Google has for kernel config requirements?
thanks,
greg k-h
cc-ing Jin Quian (maintains kernel repo for emulators), Bo Hu & Lingfeng Yang from Google
Hi Rob,
thank you for taking the time to review the patches.
Let me try to answer some of your comments and concerns:
> This isn't even supported in Google's common kernel tree. If it's not
> important enough for it, why should it be for mainline kernel?
Goldfish PIC controller driver is used and maintained currently in a
separate kernel repo Google uses for Android emulator support:
[1] https://android.googlesource.com/kernel/goldfish.git
The referenced device also exist and is maintained in the official
Android emulator repo. This device/driver has been successfully
used for the past many years by MIPS for driving interrupts to
other virtual devices which make Android emulation possible.
I'll try to quote Google on their plans and let Jin correct me if I'm wrong.
The idea is to have the emulator support in the Googles common kernel repo for all
architectures and stop maintaining a separate one just for emulation.
Currently there is emulator kernel support in common repo for Intel & ARM platforms,
MIPS emulator support is still maintained in [1].
The effort of mainlining MIPS Ranchu virtual platform is because we want to
eventually have MIPS emulator support in Googles common kernel repo
backported from upstream in some of their next rebases.
Also, having the emulator support in the upstream kernel would help picking up the latest fixes.
In the matter of fact, many fixes for the MIPS kernel came from Android testing in the emulator.
> To put it another way, why does goldfish need a special interrupt
> controller. Just use one of the many that are already supported in the
> kernel and emulated by qemu.
The reason we are using Goldfish PIC for MIPS emulation is because it
is pretty simple Interrupt controller which is easily maintained and
the infrastructure for it in Android emulator is in place and continuously tested.
> Same comments apply to the RTC patch.
Same reasons apply as for Goldfish PIC.
Kind regards,
Miodrag
________________________________________
From: Rob Herring [[email protected]]
Sent: Friday, June 30, 2017 1:17 AM
To: Aleksandar Markovic
Cc: Linux-MIPS; Aleksandar Markovic; Miodrag Dinic; Goran Ferenc; David S. Miller; [email protected]; Douglas Leung; Greg Kroah-Hartman; James Hogan; Jason Cooper; [email protected]; Marc Zyngier; Mark Rutland; Martin K. Petersen; Mauro Carvalho Chehab; Paul Burton; Petar Jovanovic; Raghu Gandham; Thomas Gleixner
Subject: Re: [PATCH v2 03/10] Documentation: Add device tree binding for Goldfish PIC driver
On Wed, Jun 28, 2017 at 10:46 AM, Aleksandar Markovic
<[email protected]> wrote:
> From: Aleksandar Markovic <[email protected]>
>
> Add documentation for DT binding of Goldfish PIC driver. The compatible
> string used by OS for binding the driver is "google,goldfish-pic".
This isn't even supported in Google's common kernel tree. If it's not
important enough for it, why should it be for mainline kernel?
To put it another way, why does goldfish need a special interrupt
controller. Just use one of the many that are already supported in the
kernel and emulated by qemu.
Same comments apply to the RTC patch.
Rob
cc-ing Arve Hj?nnev?g who originally upstreamed Goldfish FB driver
cc-ing Jin Quian, Bo Hu & Lingfeng Yang from Google
Hi Rob,
Thanks for taking the time to review the patches
> I don't know that this should even go upstream. There's no upstream
> qemu support for goldfish-fb. Maybe this is a minor driver change, but
> FB drivers are being replaced with DRM drivers. And the time for AOSP
> supporting framebuffer drivers is limited I think with HWC2 and
> explicit fence support in DRM.
Goldfish FB is actively used by all supported architectures in Android (Intel/ARM/MIPS)
and is part of Android emulator project and so far, there have been no limitations in
AOSP for using it.
We have already tested this particular version of the driver for MIPS
Ranchu virtual platform (introduced in this series) which is DT based and
therefore we needed to integrate device tree support for this driver.
> bindings/display/
Did you mean to use this location instead of "bindings/goldfish/"?
Kind regards,
Miodrag
________________________________________
From: Rob Herring [[email protected]]
Sent: Friday, June 30, 2017 1:12 AM
To: Aleksandar Markovic
Cc: Linux-MIPS; Aleksandar Markovic; Miodrag Dinic; Goran Ferenc; [email protected]; Douglas Leung; James Hogan; [email protected]; Mark Rutland; Paul Burton; Petar Jovanovic; Raghu Gandham
Subject: Re: [PATCH v2 06/10] Documentation: Add device tree binding for Goldfish FB driver
On Wed, Jun 28, 2017 at 10:46 AM, Aleksandar Markovic
<[email protected]> wrote:
> From: Aleksandar Markovic <[email protected]>
>
> Add documentation for DT binding of Goldfish FB driver. The compatible
> string used by OS for binding the driver is "google,goldfish-fb".
>
> Signed-off-by: Miodrag Dinic <[email protected]>
> Signed-off-by: Goran Ferenc <[email protected]>
> Signed-off-by: Aleksandar Markovic <[email protected]>
> ---
> .../bindings/goldfish/google,goldfish-fb.txt | 18 ++++++++++++++++++
bindings/display/
I don't know that this should even go upstream. There's no upstream
qemu support for goldfish-fb. Maybe this is a minor driver change, but
FB drivers are being replaced with DRM drivers. And the time for AOSP
supporting framebuffer drivers is limited I think with HWC2 and
explicit fence support in DRM.
Rob
cc-ing Jin Quian, Bo Hu & Lingfeng Yang from Google
Hi Alexandre,
thank you for your comments, answers are inline:
>
> On 28/06/2017 at 17:46:55 +0200, Aleksandar Markovic wrote:
> > From: Aleksandar Markovic <[email protected]>
> >
> > Add device driver for a virtual Goldfish RTC clock.
> >
> > The driver can be built only if CONFIG_MIPS and CONFIG_GOLDFISH are
> > set. The compatible string used by OS for binding the driver is
> > defined as "google,goldfish-rtc".
> >
>
> Is it really MIPS specific? I would expect the same driver to work on
> the ARM based emulator too.
This driver can be made to work for ARM/Intel emulator but it is currently
used only by MIPS emulator, so I would prefer to keep it guarded with "MIPS".
If ARM or Intel decide to use this driver for their emulators it can be easily
enabled.
> > +config RTC_DRV_GOLDFISH
> > + tristate "Goldfish Real Time Clock"
> > + depends on MIPS
> > + depends on GOLDFISH
>
> This should be made buildable with COMPILE_TEST to extend coverage.
It will be included in the next version.
> > + help
> > + Say yes here to build support for the Goldfish RTC.
>
> Please, don't expect anybody to actually know what is goldfish can you
> add a sentence or two?
It will be better documented in the next version. Thank you.
> > +static irqreturn_t goldfish_rtc_interrupt(int irq, void *dev_id)
> > +{
> > + struct goldfish_rtc *qrtc = dev_id;
> > + unsigned long events = 0;
> > + void __iomem *base = qrtc->base;
> > +
> > + writel(1, base + TIMER_CLEAR_INTERRUPT);
> > + events = RTC_IRQF | RTC_AF;
> > +
> > + rtc_update_irq(qrtc->rtc, 1, events);
>
> I'd say that events is not needed you can pass the flags directly to
> rtc_update_irq
It will be corrected in the next version.
> > +static int goldfish_rtc_read_time(struct device *dev, struct rtc_time *tm)
> > +{
> > + u64 time;
> > + u64 time_low;
> > + u64 time_high;
> > + u64 time_high_prev;
> > +
> > + struct goldfish_rtc *qrtc =
> > + platform_get_drvdata(to_platform_device(dev));
> > + void __iomem *base = qrtc->base;
> > +
> > + time_high = readl(base + TIMER_TIME_HIGH);
> > + do {
> > + time_high_prev = time_high;
> > + time_low = readl(base + TIMER_TIME_LOW);
> > + time_high = readl(base + TIMER_TIME_HIGH);
> > + } while (time_high != time_high_prev);
>
> I'm not sure why you need that loop as the comments for TIMER_TIME_LOW
> and TIMER_TIME_HIGH indicate that TIMER_TIME_HIGH is latched when
> TIMER_TIME_LOW is read. Note that the original driver from google
> doesn't do that.
This is the way how other HW drivers are doing it, so we used this
approach to make it more in-line with other HW, and it also does not
make any assumptions regarding TIMER_TIME_HIGH is latched or not.
This is the relevant part of code on the RTC device side which emulates these reads:
static uint64_t goldfish_timer_read(void *opaque, hwaddr offset, unsigned size)
{
struct timer_state *s = (struct timer_state *)opaque;
switch(offset) {
case TIMER_TIME_LOW:
s->now_ns = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
return s->now_ns;
case TIMER_TIME_HIGH:
return s->now_ns >> 32;
default:
cpu_abort(current_cpu,
"goldfish_timer_read: Bad offset %" HWADDR_PRIx "\n",
offset);
return 0;
}
}
So theoretically speaking, we could imagine the situation that the kernel pre-empts after the
first TIMER_TIME_LOW read and another request for reading the time gets processed, so
the previous call would end-up having stale TIMER_TIME_LOW value.
This is however very unlikely to happen, but one extra read in the loop doesn't hurt and
actually makes the code less prone to error.
> > + time = (time_high << 32) | time_low;
> > +
> > + do_div(time, NSEC_PER_SEC);
> > +
> > + rtc_time_to_tm(time, tm);
> > +
> > + return 0;
> > +}
> > +
> > +static const struct rtc_class_ops goldfish_rtc_ops = {
> > + .read_time = goldfish_rtc_read_time,
> > +};
> > +
> > +static int goldfish_rtc_probe(struct platform_device *pdev)
> > +{
> > + struct resource *r;
> > + struct goldfish_rtc *qrtc;
> > + unsigned long rtc_dev_len;
> > + unsigned long rtc_dev_addr;
> > + int err;
> > +
> > + qrtc = devm_kzalloc(&pdev->dev, sizeof(*qrtc), GFP_KERNEL);
> > + if (qrtc == NULL)
> > + return -ENOMEM;
> > +
> > + platform_set_drvdata(pdev, qrtc);
> > +
> > + r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > + if (r == NULL)
> > + return -ENODEV;
> > +
> > + rtc_dev_addr = r->start;
> > + rtc_dev_len = resource_size(r);
> > + qrtc->base = devm_ioremap(&pdev->dev, rtc_dev_addr, rtc_dev_len);
>
> devm_ioremap_resource ?
Thanks, it will be fixed in next version to use devm_ioremap_resource().
> > + if (IS_ERR(qrtc->base))
> > + return -ENODEV;
> > +
> > + qrtc->irq = platform_get_irq(pdev, 0);
> > + if (qrtc->irq < 0)
> > + return -ENODEV;
> > +
>
> Is the irq so important that you have to fail here even if the driver
> doesn't support any alarm?
Well currently it does not support alarm features, but we are considering
to implement it in some other iteration. Maybe we will introduce it in the next version
if not we will remove the IRQ handling. Thanks.
> > + qrtc->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
> > + &goldfish_rtc_ops, THIS_MODULE);
> > + if (IS_ERR(qrtc->rtc))
> > + return PTR_ERR(qrtc->rtc);
> > +
> > + err = devm_request_irq(&pdev->dev, qrtc->irq, goldfish_rtc_interrupt,
> > + 0, pdev->name, qrtc);
> > + if (err)
> > + return err;
>
> Ditto.
Kind regards,
Miodrag
________________________________________
From: Alexandre Belloni [[email protected]]
Sent: Wednesday, July 05, 2017 11:56 PM
To: Aleksandar Markovic
Cc: [email protected]; Aleksandar Markovic; Miodrag Dinic; Goran Ferenc; Alessandro Zummo; David S. Miller; Douglas Leung; Greg Kroah-Hartman; James Hogan; [email protected]; [email protected]; Martin K. Petersen; Mauro Carvalho Chehab; Paul Burton; Petar Jovanovic; Raghu Gandham
Subject: Re: [PATCH v2 02/10] MIPS: ranchu: Add Goldfish RTC driver
Hi,
The subject doesn't fit the subsystem style, this needs to be changed.
On 28/06/2017 at 17:46:55 +0200, Aleksandar Markovic wrote:
> From: Aleksandar Markovic <[email protected]>
>
> Add device driver for a virtual Goldfish RTC clock.
>
> The driver can be built only if CONFIG_MIPS and CONFIG_GOLDFISH are
> set. The compatible string used by OS for binding the driver is
> defined as "google,goldfish-rtc".
>
Is it really MIPS specific? I would expect the same driver to work on
the ARM based emulator too.
> +config RTC_DRV_GOLDFISH
> + tristate "Goldfish Real Time Clock"
> + depends on MIPS
> + depends on GOLDFISH
This should be made buildable with COMPILE_TEST to extend coverage.
> + help
> + Say yes here to build support for the Goldfish RTC.
Please, don't expect anybody to actually know what is goldfish can you
add a sentence or two?
> +static irqreturn_t goldfish_rtc_interrupt(int irq, void *dev_id)
> +{
> + struct goldfish_rtc *qrtc = dev_id;
> + unsigned long events = 0;
> + void __iomem *base = qrtc->base;
> +
> + writel(1, base + TIMER_CLEAR_INTERRUPT);
> + events = RTC_IRQF | RTC_AF;
> +
> + rtc_update_irq(qrtc->rtc, 1, events);
I'd say that events is not needed you can pass the flags directly to
rtc_update_irq
> +static int goldfish_rtc_read_time(struct device *dev, struct rtc_time *tm)
> +{
> + u64 time;
> + u64 time_low;
> + u64 time_high;
> + u64 time_high_prev;
> +
> + struct goldfish_rtc *qrtc =
> + platform_get_drvdata(to_platform_device(dev));
> + void __iomem *base = qrtc->base;
> +
> + time_high = readl(base + TIMER_TIME_HIGH);
> + do {
> + time_high_prev = time_high;
> + time_low = readl(base + TIMER_TIME_LOW);
> + time_high = readl(base + TIMER_TIME_HIGH);
> + } while (time_high != time_high_prev);
I'm not sure why you need that loop as the comments for TIMER_TIME_LOW
and TIMER_TIME_HIGH indicate that TIMER_TIME_HIGH is latched when
TIMER_TIME_LOW is read. Note that the original driver from google
doesn't do that.
> + time = (time_high << 32) | time_low;
> +
> + do_div(time, NSEC_PER_SEC);
> +
> + rtc_time_to_tm(time, tm);
> +
> + return 0;
> +}
> +
> +static const struct rtc_class_ops goldfish_rtc_ops = {
> + .read_time = goldfish_rtc_read_time,
> +};
> +
> +static int goldfish_rtc_probe(struct platform_device *pdev)
> +{
> + struct resource *r;
> + struct goldfish_rtc *qrtc;
> + unsigned long rtc_dev_len;
> + unsigned long rtc_dev_addr;
> + int err;
> +
> + qrtc = devm_kzalloc(&pdev->dev, sizeof(*qrtc), GFP_KERNEL);
> + if (qrtc == NULL)
> + return -ENOMEM;
> +
> + platform_set_drvdata(pdev, qrtc);
> +
> + r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> + if (r == NULL)
> + return -ENODEV;
> +
> + rtc_dev_addr = r->start;
> + rtc_dev_len = resource_size(r);
> + qrtc->base = devm_ioremap(&pdev->dev, rtc_dev_addr, rtc_dev_len);
devm_ioremap_resource ?
> + if (IS_ERR(qrtc->base))
> + return -ENODEV;
> +
> + qrtc->irq = platform_get_irq(pdev, 0);
> + if (qrtc->irq < 0)
> + return -ENODEV;
> +
Is the irq so important that you have to fail here even if the driver
doesn't support any alarm?
> + qrtc->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
> + &goldfish_rtc_ops, THIS_MODULE);
> + if (IS_ERR(qrtc->rtc))
> + return PTR_ERR(qrtc->rtc);
> +
> + err = devm_request_irq(&pdev->dev, qrtc->irq, goldfish_rtc_interrupt,
> + 0, pdev->name, qrtc);
> + if (err)
> + return err;
Ditto.
--
Alexandre Belloni, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
Hi Mark,
> As it stands, this needs a major amount of reworking. You're most
> probably better off rewriting it from scratch instead of tinkering with
> what looks like 10+ year old code...
thanks for your valuable comments.
We will try to update this code with regards to the latest kernel standards for
interrupt controller drivers and propose a new version in next patch series.
Kind regards,
Miodrag
________________________________________
From: Marc Zyngier [[email protected]]
Sent: Wednesday, June 28, 2017 7:33 PM
To: Aleksandar Markovic; [email protected]
Cc: Aleksandar Markovic; Miodrag Dinic; Goran Ferenc; David S. Miller; Douglas Leung; Greg Kroah-Hartman; James Hogan; Jason Cooper; [email protected]; Martin K. Petersen; Mauro Carvalho Chehab; Paul Burton; Petar Jovanovic; Raghu Gandham; Thomas Gleixner
Subject: Re: [PATCH v2 04/10] MIPS: ranchu: Add Goldfish PIC driver
On 28/06/17 16:46, Aleksandar Markovic wrote:
> From: Aleksandar Markovic <[email protected]>
>
> Add device driver for a virtual programmable interrupt controller
>
> The virtual PIC is designed as a device tree-based interrupt controller.
>
> The compatible string used by OS for binding the driver is
> "google,goldfish-pic".
>
> Signed-off-by: Miodrag Dinic <[email protected]>
> Signed-off-by: Goran Ferenc <[email protected]>
> Signed-off-by: Aleksandar Markovic <[email protected]>
> ---
> MAINTAINERS | 1 +
> drivers/irqchip/Kconfig | 9 ++
> drivers/irqchip/Makefile | 1 +
> drivers/irqchip/irq-goldfish-pic.c | 169 +++++++++++++++++++++++++++++++++++++
> 4 files changed, 180 insertions(+)
> create mode 100644 drivers/irqchip/irq-goldfish-pic.c
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 85da9f0..fb4c6ea 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -845,6 +845,7 @@ ANDROID GOLDFISH PIC DRIVER
> M: Miodrag Dinic <[email protected]>
> S: Supported
> F: Documentation/devicetree/bindings/interrupt-controller/google,goldfish-pic.txt
> +F: drivers/irqchip/irq-goldfish-pic.c
>
> ANDROID GOLDFISH RTC DRIVER
> M: Miodrag Dinic <[email protected]>
> diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
> index 478f8ac..6c2f924 100644
> --- a/drivers/irqchip/Kconfig
> +++ b/drivers/irqchip/Kconfig
> @@ -301,3 +301,12 @@ config QCOM_IRQ_COMBINER
> help
> Say yes here to add support for the IRQ combiner devices embedded
> in Qualcomm Technologies chips.
> +
> +config GOLDFISH_PIC
> + bool "Goldfish programmable interrupt controller"
> + depends on MIPS
> + depends on GOLDFISH
> + select IRQ_DOMAIN
> + help
> + Say yes here to enable Goldfish interrupt controller driver used
> + for Goldfish based virtual platforms.
> diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
> index b64c59b..5e73932 100644
> --- a/drivers/irqchip/Makefile
> +++ b/drivers/irqchip/Makefile
> @@ -76,3 +76,4 @@ 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
> +obj-$(CONFIG_GOLDFISH_PIC) += irq-goldfish-pic.o
> diff --git a/drivers/irqchip/irq-goldfish-pic.c b/drivers/irqchip/irq-goldfish-pic.c
> new file mode 100644
> index 0000000..d0e4c2d
> --- /dev/null
> +++ b/drivers/irqchip/irq-goldfish-pic.c
> @@ -0,0 +1,169 @@
> +/* drivers/irqchip/irq-goldfish-pic.c
> + *
> + * Copyright (C) 2007 Google, Inc.
> + * Copyright (C) 2017 Imagination Technologies Ltd.
> + *
> + * This software is licensed under the terms of the GNU General Public
> + * License version 2, as published by the Free Software Foundation, and
> + * may be copied, distributed, and modified under those terms.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + */
> +
> +#include <linux/interrupt.h>
> +#include <linux/irqchip.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +
> +#include <asm/setup.h>
> +
> +/* 0..7 MIPS CPU interrupts */
> +#define GOLDFISH_CPU_IRQ_PIC (MIPS_CPU_IRQ_BASE + 2)
> +#define GOLDFISH_CPU_IRQ_FIQ (MIPS_CPU_IRQ_BASE + 3) /* Not used? */
> +#define GOLDFISH_CPU_IRQ_COMPARE (MIPS_CPU_IRQ_BASE + 7)
> +
> +#define GOLDFISH_NR_IRQS 40
> +/* 8..39 Cascaded Goldfish PIC interrupts */
> +#define GOLDFISH_IRQ_OFFSET 8
> +
> +#define GOLDFISH_PIC_NUMBER 0x04
> +#define GOLDFISH_PIC_DISABLE_ALL 0x08
> +#define GOLDFISH_PIC_DISABLE 0x0c
> +#define GOLDFISH_PIC_ENABLE 0x10
> +
> +static struct irq_domain *goldfish_pic_domain;
> +static void __iomem *goldfish_pic_base;
> +
> +void goldfish_mask_irq(struct irq_data *d)
> +{
> + writel(d->irq - GOLDFISH_IRQ_OFFSET,
> + goldfish_pic_base + GOLDFISH_PIC_DISABLE);
This makes exactly zero sense. You're using the Linux irq, which is just
a random number, and write that to the HW?
> +}
> +
> +void goldfish_unmask_irq(struct irq_data *d)
> +{
> + writel(d->irq - GOLDFISH_IRQ_OFFSET,
> + goldfish_pic_base + GOLDFISH_PIC_ENABLE);
> +}
> +
> +static struct irq_chip goldfish_irq_chip = {
> + .name = "goldfish",
> + .irq_mask = goldfish_mask_irq,
> + .irq_mask_ack = goldfish_mask_irq,
> + .irq_unmask = goldfish_unmask_irq,
> +};
> +
> +void goldfish_irq_dispatch(void)
> +{
> + uint32_t irq;
> +
> + /*
> + * Disable all interrupt sources
> + */
> + irq = readl(goldfish_pic_base + GOLDFISH_PIC_NUMBER);
> + do_IRQ(GOLDFISH_IRQ_OFFSET + irq);
> +}
> +
> +void goldfish_fiq_dispatch(void)
> +{
> + panic("goldfish_fiq_dispatch");
> +}
> +
> +static void goldfish_ip2_irq_dispatch(struct irq_desc *desc)
> +{
> + unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
> +
> + if (pending & CAUSEF_IP2)
> + goldfish_irq_dispatch();
> + else if (pending & CAUSEF_IP3)
> + goldfish_fiq_dispatch();
> + else if (pending & CAUSEF_IP7)
> + do_IRQ(MIPS_CPU_IRQ_BASE + 7);
> + else
> + spurious_interrupt();
> +}
> +
> +static struct irqaction cascade = {
> + .handler = no_action,
> + .flags = IRQF_NO_THREAD,
> + .name = "cascade",
> +};
> +
> +static void mips_timer_dispatch(void)
> +{
> + do_IRQ(MIPS_CPU_IRQ_BASE + GOLDFISH_CPU_IRQ_COMPARE);
> +}
> +
> +static int goldfish_pic_map(struct irq_domain *d, unsigned int irq,
> + irq_hw_number_t hw)
> +{
> + struct irq_chip *chip = &goldfish_irq_chip;
> +
> + if (hw < GOLDFISH_IRQ_OFFSET)
> + return 0;
> +
> + irq_set_chip_and_handler(hw, chip, handle_level_irq);
Ah, right. No. Really. You're completely confusing irq and hwirq. You
really have to chose: either your system is DT driven, and you
completely disassociate irq and hwirq (that's what the irq domain is
for), or it is the same thing, and there is no irq domain (and no DT
either).
As it stands, this looks like a driver that has been DT-ified in a
hurry, without actually trying to make it fit in.
> +
> + return 0;
> +}
> +
> +static const struct irq_domain_ops irq_domain_ops = {
> + .xlate = irq_domain_xlate_onetwocell,
> + .map = goldfish_pic_map,
> +};
> +
> +int __init goldfish_pic_of_init(struct device_node *node,
> + struct device_node *parent)
> +{
> + struct resource res;
> +
> + if (of_address_to_resource(node, 0, &res)) {
> + pr_err("%s(): Failed to get icu memory range", __func__);
> + return -ENODEV;
> + }
> +
> + if (request_mem_region(res.start, resource_size(&res),
> + res.name) < 0) {
> + pr_err("%s(): Failed to request icu memory", __func__);
> + return -ENOMEM;
> + }
> +
> + goldfish_pic_base = ioremap_nocache(res.start, resource_size(&res));
All of the above should replaced by a single of_iomap.
> + if (!goldfish_pic_base) {
> + pr_err("%s(): Failed to remap icu memory", __func__);
> + release_mem_region(res.start, resource_size(&res));
> + return -ENOMEM;
> + }
> +
> + /*
> + * Disable all interrupt sources
> + */
> + writel(1, goldfish_pic_base + GOLDFISH_PIC_DISABLE_ALL);
> +
> + if (cpu_has_vint) {
> + pr_info("Setting up vectored interrupts\n");
> + set_vi_handler(GOLDFISH_CPU_IRQ_PIC, goldfish_irq_dispatch);
> + set_vi_handler(GOLDFISH_CPU_IRQ_FIQ, goldfish_fiq_dispatch);
> + set_vi_handler(GOLDFISH_CPU_IRQ_COMPARE, mips_timer_dispatch);
> + } else {
> + irq_set_chained_handler(GOLDFISH_CPU_IRQ_PIC,
> + goldfish_ip2_irq_dispatch);
> + }
> +
> + setup_irq(MIPS_CPU_IRQ_BASE+GOLDFISH_CPU_IRQ_PIC, &cascade);
> + setup_irq(MIPS_CPU_IRQ_BASE+GOLDFISH_CPU_IRQ_FIQ, &cascade);
The problem here is that you're mixing HW interrupt numbers (the VI
stuff) and things that should never be a HW interrupt number.
> +
> + goldfish_pic_domain = irq_domain_add_linear(node, GOLDFISH_NR_IRQS,
> + &irq_domain_ops, 0);
And if you're going to confuse irq and hwirq, this is definitely not the
irqdomain you want, but a legacy domain instead.
> + if (!goldfish_pic_domain)
> + panic("Failed to add IRQ domain");
> +
> + return 0;
> +}
> +
> +IRQCHIP_DECLARE(google_goldfish_pic, "google,goldfish-pic",
> + goldfish_pic_of_init);
>
As it stands, this needs a major amount of reworking. You're most
probably better off rewriting it from scratch instead of tinkering with
what looks like 10+ year old code...
Thanks,
M.
--
Jazz is not dead. It just smells funny...
On 06/07/2017 at 13:25:09 +0000, Miodrag Dinic wrote:
> > > +static int goldfish_rtc_read_time(struct device *dev, struct rtc_time *tm)
> > > +{
> > > + u64 time;
> > > + u64 time_low;
> > > + u64 time_high;
> > > + u64 time_high_prev;
> > > +
> > > + struct goldfish_rtc *qrtc =
> > > + platform_get_drvdata(to_platform_device(dev));
> > > + void __iomem *base = qrtc->base;
> > > +
> > > + time_high = readl(base + TIMER_TIME_HIGH);
> > > + do {
> > > + time_high_prev = time_high;
> > > + time_low = readl(base + TIMER_TIME_LOW);
> > > + time_high = readl(base + TIMER_TIME_HIGH);
> > > + } while (time_high != time_high_prev);
> >
> > I'm not sure why you need that loop as the comments for TIMER_TIME_LOW
> > and TIMER_TIME_HIGH indicate that TIMER_TIME_HIGH is latched when
> > TIMER_TIME_LOW is read. Note that the original driver from google
> > doesn't do that.
>
> This is the way how other HW drivers are doing it, so we used this
> approach to make it more in-line with other HW, and it also does not
> make any assumptions regarding TIMER_TIME_HIGH is latched or not.
> This is the relevant part of code on the RTC device side which emulates these reads:
>
> static uint64_t goldfish_timer_read(void *opaque, hwaddr offset, unsigned size)
> {
> struct timer_state *s = (struct timer_state *)opaque;
> switch(offset) {
> case TIMER_TIME_LOW:
> s->now_ns = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
> return s->now_ns;
> case TIMER_TIME_HIGH:
> return s->now_ns >> 32;
> default:
> cpu_abort(current_cpu,
> "goldfish_timer_read: Bad offset %" HWADDR_PRIx "\n",
> offset);
> return 0;
> }
> }
>
> So theoretically speaking, we could imagine the situation that the kernel pre-empts after the
> first TIMER_TIME_LOW read and another request for reading the time gets processed, so
> the previous call would end-up having stale TIMER_TIME_LOW value.
> This is however very unlikely to happen, but one extra read in the loop doesn't hurt and
> actually makes the code less prone to error.
>
Every call to the RTC callbacks are protected by a mutex so this will
never happen.
Most of the RTCs are actually latching the time on the first register
read and don't require specific handling. I'd prefer to keep the driver
simple.
> > > + qrtc->irq = platform_get_irq(pdev, 0);
> > > + if (qrtc->irq < 0)
> > > + return -ENODEV;
> > > +
> >
> > Is the irq so important that you have to fail here even if the driver
> > doesn't support any alarm?
>
> Well currently it does not support alarm features, but we are considering
> to implement it in some other iteration. Maybe we will introduce it in the next version
> if not we will remove the IRQ handling. Thanks.
>
I'd say that you should probably leave out the whole IRQ handling until
you really handle alarms in the driver or do you have a way to generate
alarms (and so interrupts) without using the driver?
--
Alexandre Belloni, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
On Wed, Jun 28, 2017 at 05:47:02PM +0200, Aleksandar Markovic wrote:
> From: Miodrag Dinic <[email protected]>
>
> ARCH_MIGHT_HAVE_PC_SERIO is selected by default for MIPS platforms.
> As a consequence SERIO_I8042 would be automatically selected for any
> MIPS board which wants to enable input support like keyboard
> (INPUT_KEYBOARD) regardless of i8042 controller existence.
>
> The dependency is as follows :
>
> config ARCH_MIGHT_HAVE_PC_SERIO [=y]
> Defined at drivers/input/serio/Kconfig:19
> Depends on: !UML
> Selected by: MIPS [=y]
>
> config SERIO
> Defined at drivers/input/serio/Kconfig:4
> default y
> Depends on: !UML
> Selected by: KEYBOARD_ATKBD [=y] && !UML && INPUT [=y] &&
> INPUT_KEYBOARD [=y]
>
> config SERIO_I8042
> Defined at drivers/input/serio/Kconfig:28
> tristate "i8042 PC Keyboard controller"
> default y
> Depends on: !UML && SERIO [=y] && ARCH_MIGHT_HAVE_PC_SERIO [=y]
> Selected by: KEYBOARD_ATKBD [=y] && !UML && INPUT [=y] &&
> INPUT_KEYBOARD [=y] && ARCH_MIGHT_HAVE_PC_SERIO [=y]
>
> If this driver probes the I8042_DATA_REG not knowing if the device
> exists it can cause a kernel to crash. Using check_legacy_ioport()
> interface we can selectively enable this driver only for the MIPS
> boards which actually have the i8042 controller.
>
> New "Ranchu" virtual platform does not support i8042 controller
> so it's added to the blacklist match table.
>
> Each MIPS machine should update this table with it's compatible strings
> if it does not support i8042 controller.
>
> In order to utilize this mechanism, each MIPS machine that do not
> have i8042 controller should update the blacklist table with its
> compatible strings.
>
> Signed-off-by: Miodrag Dinic <[email protected]>
> Signed-off-by: Goran Ferenc <[email protected]>
> Signed-off-by: Aleksandar Markovic <[email protected]>
> ---
> arch/mips/kernel/setup.c | 16 ++++++++++++++++
> drivers/input/serio/i8042-io.h | 2 +-
> 2 files changed, 17 insertions(+), 1 deletion(-)
>
> diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
> index c22cde8..c3e0d2b 100644
> --- a/arch/mips/kernel/setup.c
> +++ b/arch/mips/kernel/setup.c
> @@ -79,6 +79,15 @@ const unsigned long mips_io_port_base = -1;
> EXPORT_SYMBOL(mips_io_port_base);
>
> /*
> + * Here we blacklist all MIPS boards which do not have i8042 controller
> + */
> +static const struct of_device_id i8042_blacklist_of_match[] = {
> + { .compatible = "mti,ranchu", },
> + {},
> +};
> +#define I8042_DATA_REG 0x60
> +
> +/*
> * Check for existence of legacy devices
> *
> * Some drivers may try to probe some I/O ports which can lead to
> @@ -90,9 +99,16 @@ EXPORT_SYMBOL(mips_io_port_base);
> */
> int check_legacy_ioport(unsigned long base_port)
> {
> + struct device_node *np;
> int ret = 0;
>
> switch (base_port) {
> + case I8042_DATA_REG:
> + np = of_find_matching_node(NULL, i8042_blacklist_of_match);
> + if (np)
> + ret = -ENODEV;
> + of_node_put(np);
> + break;
Can you simply mark 8042 region as busy when you are setting up the
board, so when i8042 tries to requets it it will fail?
> default:
> /* We will assume that the I/O device port exists if
> * not explicitly added to the blacklist match table
> diff --git a/drivers/input/serio/i8042-io.h b/drivers/input/serio/i8042-io.h
> index 34da81c..ec5fe9e 100644
> --- a/drivers/input/serio/i8042-io.h
> +++ b/drivers/input/serio/i8042-io.h
> @@ -72,7 +72,7 @@ static inline int i8042_platform_init(void)
> * On some platforms touching the i8042 data register region can do really
> * bad things. Because of this the region is always reserved on such boxes.
> */
> -#if defined(CONFIG_PPC)
> +#if defined(CONFIG_PPC) || defined(CONFIG_MIPS)
> if (check_legacy_ioport(I8042_DATA_REG))
> return -ENODEV;
> #endif
> --
> 2.7.4
>
Thanks.
--
Dmitry
Hi,
On 28 June 2017 at 17:47, Aleksandar Markovic
<[email protected]> wrote:
> From: Miodrag Dinic <[email protected]>
>
> ARCH_MIGHT_HAVE_PC_SERIO is selected by default for MIPS platforms.
> As a consequence SERIO_I8042 would be automatically selected for any
> MIPS board which wants to enable input support like keyboard
> (INPUT_KEYBOARD) regardless of i8042 controller existence.
>
> The dependency is as follows :
>
> config ARCH_MIGHT_HAVE_PC_SERIO [=y]
> Defined at drivers/input/serio/Kconfig:19
> Depends on: !UML
> Selected by: MIPS [=y]
>
> config SERIO
> Defined at drivers/input/serio/Kconfig:4
> default y
> Depends on: !UML
> Selected by: KEYBOARD_ATKBD [=y] && !UML && INPUT [=y] &&
> INPUT_KEYBOARD [=y]
>
> config SERIO_I8042
> Defined at drivers/input/serio/Kconfig:28
> tristate "i8042 PC Keyboard controller"
> default y
> Depends on: !UML && SERIO [=y] && ARCH_MIGHT_HAVE_PC_SERIO [=y]
> Selected by: KEYBOARD_ATKBD [=y] && !UML && INPUT [=y] &&
> INPUT_KEYBOARD [=y] && ARCH_MIGHT_HAVE_PC_SERIO [=y]
>
> If this driver probes the I8042_DATA_REG not knowing if the device
> exists it can cause a kernel to crash. Using check_legacy_ioport()
> interface we can selectively enable this driver only for the MIPS
> boards which actually have the i8042 controller.
>
> New "Ranchu" virtual platform does not support i8042 controller
> so it's added to the blacklist match table.
>
> Each MIPS machine should update this table with it's compatible strings
> if it does not support i8042 controller.
>
> In order to utilize this mechanism, each MIPS machine that do not
> have i8042 controller should update the blacklist table with its
> compatible strings.
>
> Signed-off-by: Miodrag Dinic <[email protected]>
> Signed-off-by: Goran Ferenc <[email protected]>
> Signed-off-by: Aleksandar Markovic <[email protected]>
> ---
> arch/mips/kernel/setup.c | 16 ++++++++++++++++
> drivers/input/serio/i8042-io.h | 2 +-
> 2 files changed, 17 insertions(+), 1 deletion(-)
>
> diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
> index c22cde8..c3e0d2b 100644
> --- a/arch/mips/kernel/setup.c
> +++ b/arch/mips/kernel/setup.c
> @@ -79,6 +79,15 @@ const unsigned long mips_io_port_base = -1;
> EXPORT_SYMBOL(mips_io_port_base);
>
> /*
> + * Here we blacklist all MIPS boards which do not have i8042 controller
> + */
> +static const struct of_device_id i8042_blacklist_of_match[] = {
> + { .compatible = "mti,ranchu", },
> + {},
> +};
> +#define I8042_DATA_REG 0x60
> +
> +/*
> * Check for existence of legacy devices
> *
> * Some drivers may try to probe some I/O ports which can lead to
> @@ -90,9 +99,16 @@ EXPORT_SYMBOL(mips_io_port_base);
> */
> int check_legacy_ioport(unsigned long base_port)
> {
> + struct device_node *np;
> int ret = 0;
>
> switch (base_port) {
> + case I8042_DATA_REG:
> + np = of_find_matching_node(NULL, i8042_blacklist_of_match);
> + if (np)
> + ret = -ENODEV;
> + of_node_put(np);
> + break;
Wouldn't it make more sense to require boards to describe their i8042
device(s) in device tree if USE_OF is enabled? And maybe a whitelist
for those preexisting ones that don't. Much less maintenance overhead
for new boards, as I suspect the amount of boards with i8042 support
is much less than those that don't.
At least PowerPC seems to do it this way.
Regards
Jonas