* [PATCH] drm: mediatek: use ERR_CAST inlined function
From: Geliang Tang @ 2016-11-18 14:03 UTC (permalink / raw)
To: linux-arm-kernel
Use ERR_CAST inlined function instead of ERR_PTR(PTR_ERR(...)).
Signed-off-by: Geliang Tang <geliangtang@gmail.com>
---
drivers/gpu/drm/mediatek/mtk_drm_gem.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_gem.c b/drivers/gpu/drm/mediatek/mtk_drm_gem.c
index 7abc550..8d25ff0 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_gem.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_gem.c
@@ -245,7 +245,7 @@ struct drm_gem_object *mtk_gem_prime_import_sg_table(struct drm_device *dev,
mtk_gem = mtk_drm_gem_init(dev, attach->dmabuf->size);
if (IS_ERR(mtk_gem))
- return ERR_PTR(PTR_ERR(mtk_gem));
+ return ERR_CAST(mtk_gem);
expected = sg_dma_address(sg->sgl);
for_each_sg(sg->sgl, s, sg->nents, i) {
--
2.9.3
^ permalink raw reply related
* [PATCH v2 0/2] Support for Axentia TSE-850
From: Peter Rosin @ 2016-11-18 14:08 UTC (permalink / raw)
To: linux-arm-kernel
Hi!
changes v1 -> v2
- squash the fixup into the correct patch, sorry for the noise.
After finally having all essintial drivers upstreamed (the
last ones are currently in -next) I would like to have the
dts and the defconfig also upstreamed.
checkpatch complains about missing docs for some compatible
strings:
axentia,tse850v3 (v3 is the hw version that we currently use)
axentia,tse850 (in case we have future versions with commonality)
axentia,linea (the cpu module, reused in other products as well)
nxp,se97b (temp sensor in the below eeprom module)
nxp,24c02 (eeprom on the main board)
st,24c64 (eeprom on the cpu module)
I don't know where I should document those, or if it's even
needed? I get the feeling that the last three are not "my fault".
Anyway, please advice. Or, even better, apply as-is... :-)
Cheers,
Peter
Peter Rosin (2):
ARM: dts: add devicetree for the Axentia TSE-850
ARM: tse850_defconfig: add Axentia TSE-850
MAINTAINERS | 7 +
arch/arm/boot/dts/Makefile | 1 +
arch/arm/boot/dts/axentia-linea.dtsi | 52 +++++++
arch/arm/boot/dts/axentia-tse850-3.dts | 275 +++++++++++++++++++++++++++++++++
arch/arm/configs/tse850_defconfig | 223 ++++++++++++++++++++++++++
5 files changed, 558 insertions(+)
create mode 100644 arch/arm/boot/dts/axentia-linea.dtsi
create mode 100644 arch/arm/boot/dts/axentia-tse850-3.dts
create mode 100644 arch/arm/configs/tse850_defconfig
--
2.1.4
^ permalink raw reply
* [PATCH v2 1/2] ARM: dts: add devicetree for the Axentia TSE-850
From: Peter Rosin @ 2016-11-18 14:08 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1479478094-20288-1-git-send-email-peda@axentia.se>
Signed-off-by: Peter Rosin <peda@axentia.se>
---
MAINTAINERS | 6 +
arch/arm/boot/dts/Makefile | 1 +
arch/arm/boot/dts/axentia-linea.dtsi | 52 +++++++
arch/arm/boot/dts/axentia-tse850-3.dts | 275 +++++++++++++++++++++++++++++++++
4 files changed, 334 insertions(+)
create mode 100644 arch/arm/boot/dts/axentia-linea.dtsi
create mode 100644 arch/arm/boot/dts/axentia-tse850-3.dts
diff --git a/MAINTAINERS b/MAINTAINERS
index 9fe1bc9b414f..7ecf50e5ab47 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2325,6 +2325,12 @@ S: Maintained
F: Documentation/devicetree/bindings/sound/axentia,*
F: sound/soc/atmel/tse850-pcm5142.c
+AXENTIA ARM DEVICES
+M: Peter Rosin <peda@axentia.se>
+L: linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
+S: Maintained
+F: arch/arm/boot/dts/axentia-*
+
AZ6007 DVB DRIVER
M: Mauro Carvalho Chehab <mchehab@s-opensource.com>
M: Mauro Carvalho Chehab <mchehab@kernel.org>
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index befcd2619902..02cd9b4c55d3 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -48,6 +48,7 @@ dtb-$(CONFIG_SOC_SAM_V7) += \
at91-kizbox2.dtb \
at91-sama5d2_xplained.dtb \
at91-sama5d3_xplained.dtb \
+ axentia-tse850-3.dtb \
sama5d31ek.dtb \
sama5d33ek.dtb \
sama5d34ek.dtb \
diff --git a/arch/arm/boot/dts/axentia-linea.dtsi b/arch/arm/boot/dts/axentia-linea.dtsi
new file mode 100644
index 000000000000..07359f9d7419
--- /dev/null
+++ b/arch/arm/boot/dts/axentia-linea.dtsi
@@ -0,0 +1,52 @@
+/*
+ * axentia-linea.dtsi - Device Tree Include file for the Axentia Linea Module.
+ *
+ * Copyright (C) 2016 Axentia Technologies AB
+ * Peter Rosin <peda@axentia.se>
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#include "sama5d31.dtsi"
+
+/ {
+ compatible = "axentia,linea",
+ "atmel,sama5d31", "atmel,sama5d3", "atmel,sama5";
+
+ memory {
+ reg = <0x20000000 0x20000000>;
+ };
+};
+
+&slow_xtal {
+ clock-frequency = <32768>;
+};
+
+&main_xtal {
+ clock-frequency = <12000000>;
+};
+
+&main {
+ clock-frequency = <12000000>;
+};
+
+&i2c0 {
+ status = "okay";
+
+ eeprom at 51 {
+ compatible = "st,24c64";
+ reg = <0x51>;
+ pagesize = <32>;
+ };
+};
+
+&nand0 {
+ status = "okay";
+
+ nand-bus-width = <8>;
+ nand-ecc-mode = "hw";
+ atmel,has-pmecc;
+ atmel,pmecc-cap = <4>;
+ atmel,pmecc-sector-size = <512>;
+ nand-on-flash-bbt;
+};
diff --git a/arch/arm/boot/dts/axentia-tse850-3.dts b/arch/arm/boot/dts/axentia-tse850-3.dts
new file mode 100644
index 000000000000..517381f89c3d
--- /dev/null
+++ b/arch/arm/boot/dts/axentia-tse850-3.dts
@@ -0,0 +1,275 @@
+/*
+ * axentia-tse850-3.dts - Device Tree file for the Axentia TSE-850 3.0 board
+ *
+ * Copyright (C) 2016 Axentia Technologies AB
+ * Peter Rosin <peda@axentia.se>
+ *
+ * Licensed under GPLv2 or later.
+ */
+/dts-v1/;
+#include <dt-bindings/pwm/pwm.h>
+#include "axentia-linea.dtsi"
+
+/ {
+ model = "Axentia TSE-850 3.0";
+ compatible = "axentia,tse850v3", "axentia,tse850", "axentia,linea",
+ "atmel,sama5d31", "atmel,sama5d3", "atmel,sama5";
+
+ chosen {
+ bootargs = "console=ttyS0,115200 rootfstype=ubifs ubi.mtd=5 root=ubi0:rootfs";
+ };
+
+ ahb {
+ apb {
+ pinctrl at fffff200 {
+ tse850 {
+ pinctrl_usba_vbus: usba-vbus {
+ atmel,pins =
+ <AT91_PIOC 31
+ AT91_PERIPH_GPIO
+ AT91_PINCTRL_DEGLITCH>;
+ };
+ };
+ };
+
+ watchdog at fffffe40 {
+ status = "okay";
+ };
+ };
+ };
+
+ sck: oscillator {
+ compatible = "fixed-clock";
+
+ #clock-cells = <0>;
+ clock-frequency = <16000000>;
+ clock-output-names = "sck";
+ };
+
+ reg_3v3: regulator {
+ compatible = "regulator-fixed";
+
+ regulator-name = "3v3-supply";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ ana: reg-ana {
+ compatible = "pwm-regulator";
+
+ regulator-name = "ANA";
+
+ pwms = <&pwm0 2 1000 PWM_POLARITY_INVERTED>;
+ pwm-dutycycle-unit = <1000>;
+ pwm-dutycycle-range = <100 1000>;
+
+ regulator-min-microvolt = <2000000>;
+ regulator-max-microvolt = <20000000>;
+ regulator-ramp-delay = <1000>;
+ };
+
+ sound {
+ compatible = "axentia,tse850-pcm5142";
+
+ axentia,ssc-controller = <&ssc0>;
+ axentia,audio-codec = <&pcm5142>;
+
+ axentia,add-gpios = <&pioA 8 GPIO_ACTIVE_LOW>;
+ axentia,loop1-gpios = <&pioA 10 GPIO_ACTIVE_LOW>;
+ axentia,loop2-gpios = <&pioA 11 GPIO_ACTIVE_LOW>;
+
+ axentia,ana-supply = <&ana>;
+ };
+
+ dac: dpot-dac {
+ compatible = "dpot-dac";
+ vref-supply = <®_3v3>;
+ io-channels = <&dpot 0>;
+ io-channel-names = "dpot";
+ #io-channel-cells = <1>;
+ };
+
+ envelope-detector {
+ compatible = "axentia,tse850-envelope-detector";
+ io-channels = <&dac 0>;
+ io-channel-names = "dac";
+
+ interrupt-parent = <&pioA>;
+ interrupts = <3 IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "comp";
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ ch1-red {
+ label = "ch-1:red";
+ gpios = <&pioA 23 GPIO_ACTIVE_LOW>;
+ };
+ ch1-green {
+ label = "ch-1:green";
+ gpios = <&pioA 22 GPIO_ACTIVE_LOW>;
+ };
+ ch2-red {
+ label = "ch-2:red";
+ gpios = <&pioA 21 GPIO_ACTIVE_LOW>;
+ };
+ ch2-green {
+ label = "ch-2:green";
+ gpios = <&pioA 20 GPIO_ACTIVE_LOW>;
+ };
+ data-red {
+ label = "data:red";
+ gpios = <&pioA 19 GPIO_ACTIVE_LOW>;
+ };
+ data-green {
+ label = "data:green";
+ gpios = <&pioA 18 GPIO_ACTIVE_LOW>;
+ };
+ alarm-red {
+ label = "alarm:red";
+ gpios = <&pioA 17 GPIO_ACTIVE_LOW>;
+ };
+ alarm-green {
+ label = "alarm:green";
+ gpios = <&pioA 16 GPIO_ACTIVE_LOW>;
+ };
+ };
+};
+
+&nand0 {
+ at91bootstrap at 0 {
+ label = "at91bootstrap";
+ reg = <0x0 0x40000>;
+ };
+
+ barebox at 40000 {
+ label = "bootloader";
+ reg = <0x40000 0x60000>;
+ };
+
+ bareboxenv at c0000 {
+ label = "bareboxenv";
+ reg = <0xc0000 0x40000>;
+ };
+
+ bareboxenv2 at 100000 {
+ label = "bareboxenv2";
+ reg = <0x100000 0x40000>;
+ };
+
+ oftree at 180000 {
+ label = "oftree";
+ reg = <0x180000 0x20000>;
+ };
+
+ kernel at 200000 {
+ label = "kernel";
+ reg = <0x200000 0x500000>;
+ };
+
+ rootfs at 800000 {
+ label = "rootfs";
+ reg = <0x800000 0x0f800000>;
+ };
+
+ ovlfs at 10000000 {
+ label = "ovlfs";
+ reg = <0x10000000 0x10000000>;
+ };
+};
+
+&ssc0 {
+ status = "okay";
+};
+
+&i2c0 {
+ status = "okay";
+
+ jc42 at 18 {
+ compatible = "nxp,se97b", "jedec,jc-42.4-temp";
+ reg = <0x18>;
+ };
+
+ dpot: mcp4651-104 at 28 {
+ compatible = "microchip,mcp4651-104";
+ reg = <0x28>;
+ #io-channel-cells = <1>;
+ };
+
+ pcm5142: pcm5142 at 4c {
+ compatible = "ti,pcm5142";
+
+ reg = <0x4c>;
+
+ AVDD-supply = <®_3v3>;
+ DVDD-supply = <®_3v3>;
+ CPVDD-supply = <®_3v3>;
+
+ clocks = <&sck>;
+
+ pll-in = <3>;
+ pll-out = <6>;
+ };
+
+ eeprom at 50 {
+ compatible = "nxp,24c02";
+ reg = <0x50>;
+ pagesize = <16>;
+ };
+};
+
+&usart0 {
+ status = "okay";
+
+ atmel,use-dma-rx;
+};
+
+&pwm0 {
+ status = "okay";
+
+ pinctrl-0 = <&pinctrl_pwm0_pwml2_1>;
+ pinctrl-names = "default";
+};
+
+&macb1 {
+ status = "okay";
+
+ phy-mode = "rgmii";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ phy0: ethernet-phy at 3 {
+ reg = <3>;
+
+ interrupt-parent = <&pioE>;
+ interrupts = <31 IRQ_TYPE_EDGE_FALLING>;
+ };
+};
+
+&usb0 {
+ status = "okay";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usba_vbus>;
+ atmel,vbus-gpio = <&pioC 31 GPIO_ACTIVE_HIGH>;
+};
+
+&usb1 {
+ status = "okay";
+
+ num-ports = <1>;
+ atmel,vbus-gpio = <&pioD 29 GPIO_ACTIVE_HIGH>;
+ atmel,oc-gpio = <&pioC 15 GPIO_ACTIVE_LOW>;
+};
+
+&usb2 {
+ status = "okay";
+};
+
+&dbgu {
+ status = "okay";
+
+ dmas = <0>, <0>; /* Do not use DMA for dbgu */
+};
--
2.1.4
^ permalink raw reply related
* [PATCH v2 2/2] ARM: tse850_defconfig: add Axentia TSE-850
From: Peter Rosin @ 2016-11-18 14:08 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1479478094-20288-1-git-send-email-peda@axentia.se>
Signed-off-by: Peter Rosin <peda@axentia.se>
---
MAINTAINERS | 1 +
arch/arm/configs/tse850_defconfig | 223 ++++++++++++++++++++++++++++++++++++++
2 files changed, 224 insertions(+)
create mode 100644 arch/arm/configs/tse850_defconfig
diff --git a/MAINTAINERS b/MAINTAINERS
index 7ecf50e5ab47..883d46eb2a06 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2330,6 +2330,7 @@ M: Peter Rosin <peda@axentia.se>
L: linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
S: Maintained
F: arch/arm/boot/dts/axentia-*
+F: arch/arm/configs/tse850_defconfig
AZ6007 DVB DRIVER
M: Mauro Carvalho Chehab <mchehab@s-opensource.com>
diff --git a/arch/arm/configs/tse850_defconfig b/arch/arm/configs/tse850_defconfig
new file mode 100644
index 000000000000..f6076e7e1669
--- /dev/null
+++ b/arch/arm/configs/tse850_defconfig
@@ -0,0 +1,223 @@
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+# CONFIG_FHANDLE is not set
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+# CONFIG_RD_XZ is not set
+# CONFIG_RD_LZO is not set
+# CONFIG_RD_LZ4 is not set
+CONFIG_EMBEDDED=y
+CONFIG_SLAB=y
+# CONFIG_LBDAF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_AT91=y
+CONFIG_SOC_SAMA5D3=y
+# CONFIG_CACHE_L2X0 is not set
+CONFIG_AEABI=y
+CONFIG_UACCESS_WITH_MEMCPY=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="console=ttyS0,115200 initrd=0x21100000,25165824 root=/dev/ram0 rw"
+CONFIG_KEXEC=y
+CONFIG_VFP=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_PACKET_DIAG=y
+CONFIG_UNIX=y
+CONFIG_UNIX_DIAG=y
+CONFIG_XFRM_USER=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+CONFIG_NET_IPGRE_DEMUX=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+CONFIG_INET_UDP_DIAG=y
+# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET6_XFRM_MODE_BEET is not set
+CONFIG_IPV6_SIT_6RD=y
+CONFIG_NETFILTER=y
+CONFIG_NF_CONNTRACK=y
+# CONFIG_NF_CONNTRACK_PROCFS is not set
+CONFIG_NF_CONNTRACK_SNMP=y
+CONFIG_NF_TABLES=y
+CONFIG_NF_TABLES_INET=y
+CONFIG_NF_TABLES_NETDEV=y
+CONFIG_NFT_EXTHDR=y
+CONFIG_NFT_META=y
+CONFIG_NFT_NUMGEN=y
+CONFIG_NFT_CT=y
+CONFIG_NFT_SET_RBTREE=y
+CONFIG_NFT_SET_HASH=y
+CONFIG_NFT_COUNTER=y
+CONFIG_NFT_LOG=y
+CONFIG_NFT_LIMIT=y
+CONFIG_NFT_QUOTA=y
+CONFIG_NFT_REJECT=y
+CONFIG_NFT_HASH=y
+# CONFIG_WIRELESS is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_STANDALONE is not set
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_ATMEL=y
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_GLUEBI=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=4
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_ATMEL_TCLIB=y
+CONFIG_ATMEL_SSC=y
+CONFIG_EEPROM_AT24=y
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_NETDEVICES=y
+# CONFIG_NET_VENDOR_ARC is not set
+CONFIG_MACB=y
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CIRRUS is not set
+# CONFIG_NET_VENDOR_EZCHIP is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_HISILICON is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_QUALCOMM is not set
+# CONFIG_NET_VENDOR_RENESAS is not set
+# CONFIG_NET_VENDOR_ROCKER is not set
+# CONFIG_NET_VENDOR_SAMSUNG is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_SYNOPSYS is not set
+# CONFIG_NET_VENDOR_VIA is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
+CONFIG_MICREL_PHY=y
+# CONFIG_USB_NET_DRIVERS is not set
+# CONFIG_WLAN is not set
+# CONFIG_INPUT_LEDS is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_LEGACY_PTY_COUNT=4
+CONFIG_SERIAL_ATMEL=y
+CONFIG_SERIAL_ATMEL_CONSOLE=y
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_AT91=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_POWER_RESET=y
+CONFIG_SENSORS_JC42=y
+CONFIG_WATCHDOG=y
+CONFIG_AT91SAM9X_WATCHDOG=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_REGULATOR_PWM=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_PCM_OSS=y
+# CONFIG_SND_DRIVERS is not set
+# CONFIG_SND_ARM is not set
+# CONFIG_SND_USB is not set
+CONFIG_SND_SOC=y
+CONFIG_SND_ATMEL_SOC=y
+CONFIG_SND_ATMEL_SOC_TSE850_PCM5142=y
+# CONFIG_HID_GENERIC is not set
+CONFIG_USB=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_STORAGE_REALTEK=y
+CONFIG_USB_STORAGE_DATAFAB=y
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_ISD200=y
+CONFIG_USB_STORAGE_USBAT=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+CONFIG_USB_STORAGE_ALAUDA=y
+CONFIG_USB_STORAGE_ONETOUCH=y
+CONFIG_USB_STORAGE_KARMA=y
+CONFIG_USB_STORAGE_CYPRESS_ATACB=y
+CONFIG_USB_STORAGE_ENE_UB6250=y
+CONFIG_USB_UAS=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_ATMEL_USBA=y
+CONFIG_USB_G_SERIAL=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_GPIO=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_AT91RM9200=y
+CONFIG_DMADEVICES=y
+CONFIG_AT_HDMAC=y
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_IIO=y
+CONFIG_AT91_ADC=y
+CONFIG_ENVELOPE_DETECTOR=y
+CONFIG_DPOT_DAC=y
+CONFIG_MCP4531=y
+CONFIG_PWM=y
+CONFIG_PWM_ATMEL=y
+CONFIG_PWM_ATMEL_TCB=y
+CONFIG_EXT4_FS=y
+CONFIG_FANOTIFY=y
+CONFIG_OVERLAY_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_UBIFS_FS=y
+CONFIG_UBIFS_FS_ADVANCED_COMPR=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_UTF8=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DYNAMIC_DEBUG=y
+CONFIG_DEBUG_INFO=y
+CONFIG_STRIP_ASM_SYMS=y
+CONFIG_DEBUG_FS=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_LOCKUP_DETECTOR=y
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC=y
+# CONFIG_DETECT_HUNG_TASK is not set
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_FTRACE is not set
+CONFIG_DEBUG_USER=y
+CONFIG_CRYPTO_CCM=y
+CONFIG_CRYPTO_GCM=y
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_ARC4=y
+CONFIG_CRYPTO_DEV_ATMEL_AES=y
+CONFIG_CRYPTO_DEV_ATMEL_TDES=y
+CONFIG_CRYPTO_DEV_ATMEL_SHA=y
--
2.1.4
^ permalink raw reply related
* [PATCH 15/20] ARM/hw_breakpoint: Convert to hotplug state machine
From: Will Deacon @ 2016-11-18 14:11 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <alpine.DEB.2.20.1611181447100.3615@nanos>
On Fri, Nov 18, 2016 at 02:59:04PM +0100, Thomas Gleixner wrote:
> On Fri, 18 Nov 2016, Will Deacon wrote:
> > On Fri, Nov 18, 2016 at 02:42:15PM +0100, Thomas Gleixner wrote:
> > > On Fri, 18 Nov 2016, Will Deacon wrote:
> > > > On Fri, Nov 18, 2016 at 02:11:58PM +0100, Thomas Gleixner wrote:
> > > > > But it's guaranteed that cpuhp_setup_state() will not return before the
> > > > > callback has been invoked on each online cpu.
> > > >
> > > > Ok, that's good.
> > > >
> > > > > If cpus are not yet online when that code is invoked, then it's the same
> > > > > behaviour as before. It will be invoked when the cpu comes online.
> > > >
> > > > Just to check, but what stops a CPU from coming online between the call
> > > > to cpuhp_setup_state and the call to cpuhp_remove_state_nocalls in the
> > > > case of failure (debug_err_mask isn't empty)?
> > >
> > > Indeed! I missed that part. So we still need a get/put_online_cpus()
> > > protection around all of this.
> >
> > Yes, that should do it.
> >
> > > Just for curiosity sake. Wouldn't it be simpler and less error prone to
> > > make the ARM_DBG_READ/WRITE macros use the exception table and handle that
> > > in the undefined instruction handler to avoid this hook dance?
> >
> > That would be an option, but it's only the reset sequence that could
> > generate this fault so it's simpler to isolate it there.
>
> ARM_DBG_READ/WRITE_SAFE() then for reset_ctrl_regs()
>
> > We'd also have to take into account SMP if we toggle the handler in the
> > READ/WRITE accessors, since the fault handler framework is system-wide as
> > opposed to per-cpu. The whole thing is grotty as hell.
>
> The exception table is not toggling anything. It's just providing an entry
> in the exception tables, which is scanned by fixup_exception(), which then
> moves PC to the exception code. See __get_user_asm().
Oooh, now I see what you mean. I thought you were on about toggling
using register_undef_hook, but you're actually on about the extable stuff
that we already use for handling faults on user addresses in the kernel.
That's not a bad idea at all.
Will
^ permalink raw reply
* [PATCH] pinctrl: mediatek: use builtin_platform_driver
From: Geliang Tang @ 2016-11-18 14:12 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <7746cfe83ca3e96ccdf503669db3ace0e3081b7f.1479455552.git.geliangtang@gmail.com>
Use builtin_platform_driver() helper to simplify the code.
Signed-off-by: Geliang Tang <geliangtang@gmail.com>
---
drivers/pinctrl/mediatek/pinctrl-mt6397.c | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/drivers/pinctrl/mediatek/pinctrl-mt6397.c b/drivers/pinctrl/mediatek/pinctrl-mt6397.c
index 6eccb85..afcede7 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mt6397.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mt6397.c
@@ -64,8 +64,4 @@ static struct platform_driver mtk_pinctrl_driver = {
},
};
-static int __init mtk_pinctrl_init(void)
-{
- return platform_driver_register(&mtk_pinctrl_driver);
-}
-device_initcall(mtk_pinctrl_init);
+builtin_platform_driver(mtk_pinctrl_driver);
--
2.9.3
^ permalink raw reply related
* [PATCH] pinctrl: stm32: use builtin_platform_driver
From: Geliang Tang @ 2016-11-18 14:12 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <7746cfe83ca3e96ccdf503669db3ace0e3081b7f.1479455552.git.geliangtang@gmail.com>
Use builtin_platform_driver() helper to simplify the code.
Signed-off-by: Geliang Tang <geliangtang@gmail.com>
---
drivers/pinctrl/stm32/pinctrl-stm32f429.c | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/drivers/pinctrl/stm32/pinctrl-stm32f429.c b/drivers/pinctrl/stm32/pinctrl-stm32f429.c
index e9b15dc..990b867 100644
--- a/drivers/pinctrl/stm32/pinctrl-stm32f429.c
+++ b/drivers/pinctrl/stm32/pinctrl-stm32f429.c
@@ -1584,8 +1584,4 @@ static struct platform_driver stm32f429_pinctrl_driver = {
},
};
-static int __init stm32f429_pinctrl_init(void)
-{
- return platform_driver_register(&stm32f429_pinctrl_driver);
-}
-device_initcall(stm32f429_pinctrl_init);
+builtin_platform_driver(stm32f429_pinctrl_driver);
--
2.9.3
^ permalink raw reply related
* [PATCH v2 2/3] devicetree: bindings: nvmem: Add compatible string for imx6ul
From: Rob Herring @ 2016-11-18 14:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1479344899-3141-2-git-send-email-ping.bai@nxp.com>
On Thu, Nov 17, 2016 at 09:08:18AM +0800, Bai Ping wrote:
> Add new compatible string for i.MX6UL SOC.
>
> Signed-off-by: Bai Ping <ping.bai@nxp.com>
> ---
> Changes for V2:
> - reformat the changes suggested by Rob Herring
>
> Documentation/devicetree/bindings/nvmem/imx-ocotp.txt | 6 ++++--
> 1 file changed, 4 insertions(+), 2 deletions(-)
Acked-by: Rob Herring <robh@kernel.org>
^ permalink raw reply
* [PATCH] arm: spin one more cycle in timer-based delays
From: Mason @ 2016-11-18 14:18 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161118125409.GK1041@n2100.armlinux.org.uk>
On 18/11/2016 13:54, Russell King - ARM Linux wrote:
> On Fri, Nov 18, 2016 at 12:06:30PM +0000, Will Deacon wrote:
>> On Tue, Nov 15, 2016 at 02:36:33PM +0100, Mason wrote:
>>> When polling a tick counter in a busy loop, one might sample the
>>> counter just *before* it is updated, and then again just *after*
>>> it is updated. In that case, while mathematically v2-v1 equals 1,
>>> only epsilon has really passed.
>>>
>>> So, if a caller requests an N-cycle delay, we spin until v2-v1
>>> is strictly greater than N to avoid these random corner cases.
>>>
>>> Signed-off-by: Mason <slash.tmp@free.fr>
>>> ---
>>> arch/arm/lib/delay.c | 2 +-
>>> 1 file changed, 1 insertion(+), 1 deletion(-)
>>>
>>> diff --git a/arch/arm/lib/delay.c b/arch/arm/lib/delay.c
>>> index 69aad80a3af4..3f1cd15ca102 100644
>>> --- a/arch/arm/lib/delay.c
>>> +++ b/arch/arm/lib/delay.c
>>> @@ -60,7 +60,7 @@ static void __timer_delay(unsigned long cycles)
>>> {
>>> cycles_t start = get_cycles();
>>>
>>> - while ((get_cycles() - start) < cycles)
>>> + while ((get_cycles() - start) <= cycles)
>>> cpu_relax();
>>> }
>>
>> I thought a bit about this last night. It is well known that the delay
>> routines are not guaranteed to be accurate, and I don't *think* that's
>> limited to over-spinning, so arguably this isn't a bug. However, taking
>> the approach that "drivers should figure it out" is also unhelpful,
>> because the frequency of the underlying counter isn't generally known
>> and so drivers can't simply adjust the delay parameter.
>
> I don't think this change makes any sense whatsoever. udelay() is
> inaccurate, period. It _will_ give delays shorter than requested
> for many reasons, many of which can't be fixed.
If I understand correctly, udelay is, in fact, a wrapper around
several possible implementations. (Run-time decision on arch/arm)
1) The "historical" software loop-based method, which is calibrated
during init.
2) A hardware solution, based on an actual timer, ticking away
at a constant frequency.
3) others?
Solution 1 (which probably dates back to Linux 0.1) suffers from
the inaccuracies you point out, because of interrupt latency
during calibration, DVFS, etc.
On the other hand, it is simple enough to implement solution 2
in a way that guarantees that spin_for_n_cycles(n) spins
/at least/ for n cycles.
On platforms using timer-based delays, there can indeed exist
a function guaranteeing a minimal delay.
> Having a super-accurate version just encourages people to write broken
> drivers which assume (eg) that udelay(10) will give _at least_ a 10us
> delay. However, there is no such guarantee.
You say that calling udelay(10) expecting at least 10 ?s is broken.
This fails the principle of least astonishment in a pretty big way.
(If it returns after 9.9 ?s, I suppose it could be OK. But for
shorter delays, the relative error grows.)
A lot of drivers implement a spec that says
"do this, wait 1 ?s, do that".
Driver writers would typically write
do_this(); udelay(1); do_that();
Do you suggest they should write udelay(2); ?
But then, it's not so easy to follow the spec because everything
has been translated to a different number.
Hide everything behind a macro?
Note that people have been using ndelay too.
(I count 182 in drivers, 288 overall.)
drivers/cpufreq/s3c2440-cpufreq.c: ndelay(20);
I don't think the author expects this to return immediately.
> So, having udelay() for timers return slightly short is actually a good
> thing - it causes people not to make the mistake to be soo accurate
> with their delay specifications.
I disagree that having an implementation which introduces
hard-to-track-down random heisenbugs is a good thing.
> So, NAK on this change. udelay is not super-accurate.
usleep_range() fixed this issue recently.
6c5e9059692567740a4ee51530dffe51a4b9584d
https://git.kernel.org/cgit/linux/kernel/git/tip/tip.git/commit/?h=timers/core&id=6c5e9059692567740a4ee51530dffe51a4b9584d
Do you suggest driver writers should use usleep_range()
instead of udelay?
(When does usleep_range start making sense? Around 50/100 ?s
and above?)
> Reference (and this is the most important one):
>
> http://lists.openwall.net/linux-kernel/2011/01/12/372
Regards.
^ permalink raw reply
* [PATCH] ARM: ixp4xx: drop duplicate header gpio.h
From: Geliang Tang @ 2016-11-18 14:21 UTC (permalink / raw)
To: linux-arm-kernel
Drop duplicate header gpio.h from dsmg600-setup.c.
Signed-off-by: Geliang Tang <geliangtang@gmail.com>
---
arch/arm/mach-ixp4xx/dsmg600-setup.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/arch/arm/mach-ixp4xx/dsmg600-setup.c b/arch/arm/mach-ixp4xx/dsmg600-setup.c
index 43ee06d..b3bd0e1 100644
--- a/arch/arm/mach-ixp4xx/dsmg600-setup.c
+++ b/arch/arm/mach-ixp4xx/dsmg600-setup.c
@@ -26,7 +26,6 @@
#include <linux/reboot.h>
#include <linux/i2c.h>
#include <linux/i2c-gpio.h>
-#include <linux/gpio.h>
#include <mach/hardware.h>
--
2.9.3
^ permalink raw reply related
* [PATCH] ARM: lpc32xx: drop duplicate header device.h
From: Geliang Tang @ 2016-11-18 14:21 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <319a5803aac795e175306d4978134f0247cf87bc.1479457751.git.geliangtang@gmail.com>
Drop duplicate header device.h from phy3250.c.
Signed-off-by: Geliang Tang <geliangtang@gmail.com>
---
arch/arm/mach-lpc32xx/phy3250.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/arch/arm/mach-lpc32xx/phy3250.c b/arch/arm/mach-lpc32xx/phy3250.c
index 0e4cbbe..6c52bd3 100644
--- a/arch/arm/mach-lpc32xx/phy3250.c
+++ b/arch/arm/mach-lpc32xx/phy3250.c
@@ -23,7 +23,6 @@
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/dma-mapping.h>
-#include <linux/device.h>
#include <linux/gpio.h>
#include <linux/amba/bus.h>
#include <linux/amba/clcd.h>
--
2.9.3
^ permalink raw reply related
* [PATCH 1/2] dt-bindings: ahci-fsl-qoriq: added explanation for reg-names
From: Rob Herring @ 2016-11-18 14:21 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1479369560-9188-1-git-send-email-yuantian.tang@nxp.com>
On Thu, Nov 17, 2016 at 03:59:19PM +0800, yuantian.tang at nxp.com wrote:
> From: Tang Yuantian <Yuantian.Tang@nxp.com>
>
> Added explanation for reg-names to make it more clear.
>
> Signed-off-by: Tang Yuantian <yuantian.tang@nxp.com>
> ---
> Documentation/devicetree/bindings/ata/ahci-fsl-qoriq.txt | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/ata/ahci-fsl-qoriq.txt b/Documentation/devicetree/bindings/ata/ahci-fsl-qoriq.txt
> index fc33ca0..80cf10c 100644
> --- a/Documentation/devicetree/bindings/ata/ahci-fsl-qoriq.txt
> +++ b/Documentation/devicetree/bindings/ata/ahci-fsl-qoriq.txt
> @@ -10,6 +10,8 @@ Required properties:
> Optional properties:
> - dma-coherent: Enable AHCI coherent DMA operation.
> - reg-names: register area names when there are more than 1 register area.
> + example: 'ahci' is for sata controller register.
> + 'sata-ecc' is for sata ecc register.
This is not an example, but should be exactly what names are used.
When is there more than one area? That should be defined by the
compatible string and spelled out here.
Rob
^ permalink raw reply
* [RFC PATCH v2 1/2] macb: Add 1588 support in Cadence GEM.
From: Andrei Pistirica @ 2016-11-18 14:21 UTC (permalink / raw)
To: linux-arm-kernel
Cadence GEM provides a 102 bit time counter with 48 bits for seconds,
30 bits for nsecs and 24 bits for sub-nsecs to control 1588 timestamping.
This patch does the following:
- Registers to ptp clock framework
- Timer initialization is done by writing time of day to the timer counter.
- ns increment register is programmed as NSEC_PER_SEC/TSU_CLK.
For a 16 bit subns precision, the subns increment equals
remainder of (NS_PER_SEC/TSU_CLK) * (2^16).
- HW time stamp capabilities are advertised via ethtool and macb ioctl is
updated accordingly.
- Timestamps are obtained from the TX/RX PTP event/PEER registers.
The timestamp obtained thus is updated in skb for upper layers to access.
- The drivers register functions with ptp to perform time and frequency
adjustment.
- Time adjustment is done by writing to the 1558_ADJUST register.
The controller will read the delta in this register and update the timer
counter register. Alternatively, for large time offset adjustments,
the driver reads the secs and nsecs counter values, adds/subtracts the
delta and updates the timer counter.
- Frequency adjustment is not directly supported by this IP.
addend is the initial value ns increment and similarly addendesub.
The ppb (parts per billion) provided is used as
ns_incr = addend +/- (ppb/rate).
Similarly the remainder of the above is used to populate subns increment.
In case the ppb requested is negative AND subns adjustment greater than
the addendsub, ns_incr is reduced by 1 and subns_incr is adjusted in
positive accordingly.
Signed-off-by: Andrei Pistirica <andrei.pistirica@microchip.com>
Signed-off-by: Harini Katakam <harinik@xilinx.com>
---
Version 2 patch for: https://patchwork.kernel.org/patch/9310989/.
Modifications:
- bitfields for TSU are named according to SAMA5D2 data sheet
- identify GEM-PTP support based on platform capability
- add spinlock for TSU access
- change macb_ptp_adjfreq and use fewer 64bit divisions
drivers/net/ethernet/cadence/Kconfig | 10 +-
drivers/net/ethernet/cadence/Makefile | 8 +-
drivers/net/ethernet/cadence/macb.h | 80 +++++++++++
drivers/net/ethernet/cadence/macb_ptp.c | 229 ++++++++++++++++++++++++++++++++
4 files changed, 325 insertions(+), 2 deletions(-)
create mode 100644 drivers/net/ethernet/cadence/macb_ptp.c
diff --git a/drivers/net/ethernet/cadence/Kconfig b/drivers/net/ethernet/cadence/Kconfig
index f0bcb15..ebbc65f 100644
--- a/drivers/net/ethernet/cadence/Kconfig
+++ b/drivers/net/ethernet/cadence/Kconfig
@@ -29,6 +29,14 @@ config MACB
support for the MACB/GEM chip.
To compile this driver as a module, choose M here: the module
- will be called macb.
+ will be called cadence-macb.
+
+config MACB_USE_HWSTAMP
+ bool "Use IEEE 1588 hwstamp"
+ depends on MACB
+ default y
+ select PTP_1588_CLOCK
+ ---help---
+ Enable IEEE 1588 Precision Time Protocol (PTP) support for MACB.
endif # NET_CADENCE
diff --git a/drivers/net/ethernet/cadence/Makefile b/drivers/net/ethernet/cadence/Makefile
index 91f79b1..4402d42 100644
--- a/drivers/net/ethernet/cadence/Makefile
+++ b/drivers/net/ethernet/cadence/Makefile
@@ -2,4 +2,10 @@
# Makefile for the Atmel network device drivers.
#
-obj-$(CONFIG_MACB) += macb.o
+cadence-macb-y := macb.o
+
+ifeq ($(CONFIG_MACB_USE_HWSTAMP),y)
+cadence-macb-y += macb_ptp.o
+endif
+
+obj-$(CONFIG_MACB) += cadence-macb.o
diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h
index 3f385ab..2ee9af8 100644
--- a/drivers/net/ethernet/cadence/macb.h
+++ b/drivers/net/ethernet/cadence/macb.h
@@ -10,6 +10,10 @@
#ifndef _MACB_H
#define _MACB_H
+#include <linux/net_tstamp.h>
+#include <linux/ptp_clock.h>
+#include <linux/ptp_clock_kernel.h>
+
#define MACB_GREGS_NBR 16
#define MACB_GREGS_VERSION 2
#define MACB_MAX_QUEUES 8
@@ -129,6 +133,20 @@
#define GEM_RXIPCCNT 0x01a8 /* IP header Checksum Error Counter */
#define GEM_RXTCPCCNT 0x01ac /* TCP Checksum Error Counter */
#define GEM_RXUDPCCNT 0x01b0 /* UDP Checksum Error Counter */
+#define GEM_TISUBN 0x01bc /* 1588 Timer Increment Sub-ns */
+#define GEM_TSH 0x01c0 /* 1588 Timer Seconds High */
+#define GEM_TSL 0x01d0 /* 1588 Timer Seconds Low */
+#define GEM_TN 0x01d4 /* 1588 Timer Nanoseconds */
+#define GEM_TA 0x01d8 /* 1588 Timer Adjust */
+#define GEM_TI 0x01dc /* 1588 Timer Increment */
+#define GEM_EFTSL 0x01e0 /* PTP Event Frame Tx Seconds Low */
+#define GEM_EFTN 0x01e4 /* PTP Event Frame Tx Nanoseconds */
+#define GEM_EFRSL 0x01e8 /* PTP Event Frame Rx Seconds Low */
+#define GEM_EFRN 0x01ec /* PTP Event Frame Rx Nanoseconds */
+#define GEM_PEFTSL 0x01f0 /* PTP Peer Event Frame Tx Secs Low */
+#define GEM_PEFTN 0x01f4 /* PTP Peer Event Frame Tx Ns */
+#define GEM_PEFRSL 0x01f8 /* PTP Peer Event Frame Rx Sec Low */
+#define GEM_PEFRN 0x01fc /* PTP Peer Event Frame Rx Ns */
#define GEM_DCFG1 0x0280 /* Design Config 1 */
#define GEM_DCFG2 0x0284 /* Design Config 2 */
#define GEM_DCFG3 0x0288 /* Design Config 3 */
@@ -171,6 +189,7 @@
#define MACB_NCR_TPF_SIZE 1
#define MACB_TZQ_OFFSET 12 /* Transmit zero quantum pause frame */
#define MACB_TZQ_SIZE 1
+#define MACB_SRTSM_OFFSET 15
/* Bitfields in NCFGR */
#define MACB_SPD_OFFSET 0 /* Speed */
@@ -312,6 +331,36 @@
#define MACB_PFR_SIZE 1
#define MACB_PTZ_OFFSET 13 /* Enable pause time zero interrupt */
#define MACB_PTZ_SIZE 1
+#define MACB_PFTR_OFFSET 14 /* Pause Frame Transmitted */
+#define MACB_PFTR_SIZE 1
+#define MACB_DRQFR_OFFSET 18 /* PTP Delay Request Frame Received */
+#define MACB_DRQFR_SIZE 1
+#define MACB_SFR_OFFSET 19 /* PTP Sync Frame Received */
+#define MACB_SFR_SIZE 1
+#define MACB_DRQFT_OFFSET 20 /* PTP Delay Request Frame Transmitted */
+#define MACB_DRQFT_SIZE 1
+#define MACB_SFT_OFFSET 21 /* PTP Sync Frame Transmitted */
+#define MACB_SFT_SIZE 1
+#define MACB_PDRQFR_OFFSET 22 /* PDelay Request Frame Received */
+#define MACB_PDRQFR_SIZE 1
+#define MACB_PDRSFR_OFFSET 23 /* PDelay Response Frame Received */
+#define MACB_PDRSFR_SIZE 1
+#define MACB_PDRQFT_OFFSET 24 /* PDelay Request Frame Transmitted */
+#define MACB_PDRQFT_SIZE 1
+#define MACB_PDRSFT_OFFSET 25 /* PDelay Response Frame Transmitted */
+#define MACB_PDRSFT_SIZE 1
+#define MACB_SRI_OFFSET 26 /* TSU Seconds Register Increment */
+#define MACB_SRI_SIZE 1
+#define MACB_WOL_OFFSET 28 /* Wake On LAN */
+#define MACB_WOL_SIZE 1
+
+/* Timer increment fields */
+#define MACB_TI_CNS_OFFSET 0
+#define MACB_TI_CNS_SIZE 8
+#define MACB_TI_ACNS_OFFSET 8
+#define MACB_TI_ACNS_SIZE 8
+#define MACB_TI_NIT_OFFSET 16
+#define MACB_TI_NIT_SIZE 8
/* Bitfields in MAN */
#define MACB_DATA_OFFSET 0 /* data */
@@ -375,6 +424,18 @@
#define GEM_TX_PKT_BUFF_OFFSET 21
#define GEM_TX_PKT_BUFF_SIZE 1
+/* Bitfields in TISUBN */
+#define GEM_SUBNSINCR_OFFSET 0
+#define GEM_SUBNSINCR_SIZE 16
+
+/* Bitfields in TI */
+#define GEM_NSINCR_OFFSET 0
+#define GEM_NSINCR_SIZE 8
+
+/* Bitfields in ADJ */
+#define GEM_ADDSUB_OFFSET 31
+#define GEM_ADDSUB_SIZE 1
+
/* Constants for CLK */
#define MACB_CLK_DIV8 0
#define MACB_CLK_DIV16 1
@@ -405,6 +466,7 @@
#define MACB_CAPS_SG_DISABLED 0x40000000
#define MACB_CAPS_MACB_IS_GEM 0x80000000
#define MACB_CAPS_JUMBO 0x00000010
+#define MACB_CAPS_GEM_HAS_PTP 0x00000020
/* Bit manipulation macros */
#define MACB_BIT(name) \
@@ -840,8 +902,26 @@ struct macb {
unsigned int rx_frm_len_mask;
unsigned int jumbo_max_len;
+
+#ifdef CONFIG_MACB_USE_HWSTAMP
+ unsigned int hwts_tx_en;
+ unsigned int hwts_rx_en;
+ spinlock_t tsu_clk_lock;
+ unsigned int tsu_rate;
+
+ struct ptp_clock *ptp_clock;
+ struct ptp_clock_info ptp_caps;
+ unsigned int ns_incr;
+ unsigned int subns_incr;
+#endif
};
+#ifdef CONFIG_MACB_USE_HWSTAMP
+void macb_ptp_init(struct net_device *ndev);
+#else
+void macb_ptp_init(struct net_device *ndev) { }
+#endif
+
static inline bool macb_is_gem(struct macb *bp)
{
return !!(bp->caps & MACB_CAPS_MACB_IS_GEM);
diff --git a/drivers/net/ethernet/cadence/macb_ptp.c b/drivers/net/ethernet/cadence/macb_ptp.c
new file mode 100644
index 0000000..81ce3a9
--- /dev/null
+++ b/drivers/net/ethernet/cadence/macb_ptp.c
@@ -0,0 +1,229 @@
+/*
+ * PTP 1588 clock for SAMA5D2 platform.
+ *
+ * Copyright (C) 2015 Xilinx Inc.
+ * Copyright (C) 2016 Microchip Technology
+ *
+ * Authors: Harini Katakam <harinik@xilinx.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/etherdevice.h>
+#include <linux/platform_device.h>
+#include <linux/time64.h>
+#include <linux/ptp_classify.h>
+#include <linux/if_ether.h>
+#include <linux/if_vlan.h>
+
+#include "macb.h"
+
+#define GMAC_TIMER_NAME "gmac-gem-ptp"
+
+static inline void macb_tsu_get_time(struct macb *bp, struct timespec64 *ts)
+{
+ u64 sec, sech, secl;
+
+ spin_lock(&bp->tsu_clk_lock);
+
+ /* get GEM internal time */
+ sech = gem_readl(bp, TSH);
+ secl = gem_readl(bp, TSL);
+ ts->tv_nsec = gem_readl(bp, TN);
+ ts->tv_sec = (sech << 32) | secl;
+
+ /* minimize the error */
+ sech = gem_readl(bp, TSH);
+ secl = gem_readl(bp, TSL);
+ sec = (sech << 32) | secl;
+ if (ts->tv_sec != sec) {
+ ts->tv_sec = sec;
+ ts->tv_nsec = gem_readl(bp, TN);
+ }
+
+ spin_unlock(&bp->tsu_clk_lock);
+}
+
+static inline void macb_tsu_set_time(struct macb *bp,
+ const struct timespec64 *ts)
+{
+ u32 ns, sech, secl;
+ s64 word_mask = 0xffffffff;
+
+ sech = (u32)ts->tv_sec;
+ secl = (u32)ts->tv_sec;
+ ns = ts->tv_nsec;
+ if (ts->tv_sec > word_mask)
+ sech = (ts->tv_sec >> 32);
+
+ spin_lock(&bp->tsu_clk_lock);
+
+ /* TSH doesn't latch the time and no atomicity! */
+ gem_writel(bp, TSH, sech);
+ gem_writel(bp, TSL, secl);
+ gem_writel(bp, TN, ns);
+
+ spin_unlock(&bp->tsu_clk_lock);
+}
+
+static int macb_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
+{
+ struct macb *bp = container_of(ptp, struct macb, ptp_caps);
+ u32 addend, addend_frac, rem;
+ u64 drift_tmr, diff, diff_frac = 0;
+ int neg_adj = 0;
+
+ if (ppb < 0) {
+ neg_adj = 1;
+ ppb = -ppb;
+ }
+
+ /* drift/period */
+ drift_tmr = (bp->ns_incr * ppb) +
+ ((bp->subns_incr * ppb) >> 16);
+
+ /* drift/cycle */
+ diff = div_u64_rem(drift_tmr, 1000000000ULL, &rem);
+
+ /* drift fraction/cycle, if necessary */
+ if (rem) {
+ u64 fraction = rem;
+ fraction = fraction << 16;
+
+ diff_frac = div_u64(fraction, 1000000000ULL);
+ }
+
+ /* adjustmets */
+ addend = neg_adj ? (bp->ns_incr - diff) : (bp->ns_incr + diff);
+ addend_frac = neg_adj ? (bp->subns_incr - diff_frac) :
+ (bp->subns_incr + diff_frac);
+
+ spin_lock(&bp->tsu_clk_lock);
+
+ gem_writel(bp, TISUBN, GEM_BF(SUBNSINCR, addend_frac));
+ gem_writel(bp, TI, GEM_BF(NSINCR, addend));
+
+ spin_unlock(&bp->tsu_clk_lock);
+ return 0;
+}
+
+static int macb_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
+{
+ struct macb *bp = container_of(ptp, struct macb, ptp_caps);
+ struct timespec64 now, then = ns_to_timespec64(delta);
+ u32 adj, sign = 0;
+
+ if (delta < 0) {
+ delta = -delta;
+ sign = 1;
+ }
+
+ if (delta > 0x3FFFFFFF) {
+ macb_tsu_get_time(bp, &now);
+
+ if (sign)
+ now = timespec64_sub(now, then);
+ else
+ now = timespec64_add(now, then);
+
+ macb_tsu_set_time(bp, (const struct timespec64 *)&now);
+ } else {
+ adj = delta;
+ if (sign)
+ adj |= GEM_BIT(ADDSUB);
+
+ gem_writel(bp, TA, adj);
+ }
+
+ return 0;
+}
+
+static int macb_ptp_gettime(struct ptp_clock_info *ptp,
+ struct timespec64 *ts)
+{
+ struct macb *bp = container_of(ptp, struct macb, ptp_caps);
+
+ macb_tsu_get_time(bp, ts);
+
+ return 0;
+}
+
+static int macb_ptp_settime(struct ptp_clock_info *ptp,
+ const struct timespec64 *ts)
+{
+ struct macb *bp = container_of(ptp, struct macb, ptp_caps);
+
+ macb_tsu_set_time(bp, ts);
+
+ return 0;
+}
+
+static int macb_ptp_enable(struct ptp_clock_info *ptp,
+ struct ptp_clock_request *rq, int on)
+{
+ return -EOPNOTSUPP;
+}
+
+static struct ptp_clock_info macb_ptp_caps = {
+ .owner = THIS_MODULE,
+ .name = GMAC_TIMER_NAME,
+ .max_adj = 250000000,
+ .n_alarm = 0,
+ .n_ext_ts = 0,
+ .n_per_out = 0,
+ .n_pins = 0,
+ .pps = 0,
+ .adjfreq = macb_ptp_adjfreq,
+ .adjtime = macb_ptp_adjtime,
+ .gettime64 = macb_ptp_gettime,
+ .settime64 = macb_ptp_settime,
+ .enable = macb_ptp_enable,
+};
+
+void macb_ptp_init(struct net_device *ndev)
+{
+ struct macb *bp = netdev_priv(ndev);
+ struct timespec64 now;
+ u32 rem = 0;
+
+ if (!(bp->caps | MACB_CAPS_GEM_HAS_PTP)){
+ netdev_vdbg(bp->dev, "Platform does not support PTP!\n");
+ return;
+ }
+
+ spin_lock_init(&bp->tsu_clk_lock);
+
+ bp->ptp_caps = macb_ptp_caps;
+ bp->tsu_rate = clk_get_rate(bp->pclk);
+
+ getnstimeofday64(&now);
+ macb_tsu_set_time(bp, (const struct timespec64 *)&now);
+
+ bp->ns_incr = div_u64_rem(NSEC_PER_SEC, bp->tsu_rate, &rem);
+ if (rem) {
+ u64 adj = rem;
+ /* Multiply by 2^16 as subns register is 16 bits */
+ adj <<= 16;
+ bp->subns_incr = div_u64(adj, bp->tsu_rate);
+ } else {
+ bp->subns_incr = 0;
+ }
+
+ gem_writel(bp, TISUBN, GEM_BF(SUBNSINCR, bp->subns_incr));
+ gem_writel(bp, TI, GEM_BF(NSINCR, bp->ns_incr));
+ gem_writel(bp, TA, 0);
+
+ bp->ptp_clock = ptp_clock_register(&bp->ptp_caps, NULL);
+ if (IS_ERR(&bp->ptp_clock)) {
+ bp->ptp_clock = NULL;
+ pr_err("ptp clock register failed\n");
+ return;
+ }
+
+ dev_info(&bp->pdev->dev, "%s ptp clock registered.\n", GMAC_TIMER_NAME);
+}
+
--
1.9.1
^ permalink raw reply related
* [RFC PATCH v2 2/2] macb: Enable 1588 support in SAMA5D2 platform.
From: Andrei Pistirica @ 2016-11-18 14:21 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1479478912-14067-1-git-send-email-andrei.pistirica@microchip.com>
Hardware time stamp on the PTP Ethernet packets are received using the
SO_TIMESTAMPING API. Where timers are obtained from the PTP event/peer
registers.
Signed-off-by: Andrei Pistirica <andrei.pistirica@microchip.com>
---
Version 2 patch for: https://patchwork.kernel.org/patch/9310991/
Modificaions:
- add PTP caps for SAMA5D2/3/4 platforms
- and cosmetic changes
drivers/net/ethernet/cadence/macb.c | 24 +++-
drivers/net/ethernet/cadence/macb.h | 13 ++
drivers/net/ethernet/cadence/macb_ptp.c | 222 ++++++++++++++++++++++++++++++++
3 files changed, 254 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c
index d975882..eb66b76 100644
--- a/drivers/net/ethernet/cadence/macb.c
+++ b/drivers/net/ethernet/cadence/macb.c
@@ -697,6 +697,8 @@ static void macb_tx_interrupt(struct macb_queue *queue)
/* First, update TX stats if needed */
if (skb) {
+ macb_ptp_do_txstamp(bp, skb);
+
netdev_vdbg(bp->dev, "skb %u (data %p) TX complete\n",
macb_tx_ring_wrap(tail), skb->data);
bp->stats.tx_packets++;
@@ -853,6 +855,8 @@ static int gem_rx(struct macb *bp, int budget)
GEM_BFEXT(RX_CSUM, ctrl) & GEM_RX_CSUM_CHECKED_MASK)
skb->ip_summed = CHECKSUM_UNNECESSARY;
+ macb_ptp_do_rxstamp(bp, skb);
+
bp->stats.rx_packets++;
bp->stats.rx_bytes += skb->len;
@@ -1946,6 +1950,8 @@ static int macb_open(struct net_device *dev)
netif_tx_start_all_queues(dev);
+ macb_ptp_init(dev);
+
return 0;
}
@@ -2204,7 +2210,7 @@ static const struct ethtool_ops gem_ethtool_ops = {
.get_regs_len = macb_get_regs_len,
.get_regs = macb_get_regs,
.get_link = ethtool_op_get_link,
- .get_ts_info = ethtool_op_get_ts_info,
+ .get_ts_info = macb_get_ts_info,
.get_ethtool_stats = gem_get_ethtool_stats,
.get_strings = gem_get_ethtool_strings,
.get_sset_count = gem_get_sset_count,
@@ -2221,7 +2227,14 @@ static int macb_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
if (!phydev)
return -ENODEV;
- return phy_mii_ioctl(phydev, rq, cmd);
+ switch (cmd) {
+ case SIOCSHWTSTAMP:
+ return macb_hwtst_set(dev, rq, cmd);
+ case SIOCGHWTSTAMP:
+ return macb_hwtst_get(dev, rq);
+ default:
+ return phy_mii_ioctl(phydev, rq, cmd);
+ }
}
static int macb_set_features(struct net_device *netdev,
@@ -2812,7 +2825,7 @@ static const struct macb_config pc302gem_config = {
};
static const struct macb_config sama5d2_config = {
- .caps = MACB_CAPS_USRIO_DEFAULT_IS_MII_GMII,
+ .caps = MACB_CAPS_USRIO_DEFAULT_IS_MII_GMII | MACB_CAPS_GEM_HAS_PTP,
.dma_burst_length = 16,
.clk_init = macb_clk_init,
.init = macb_init,
@@ -2820,14 +2833,15 @@ static const struct macb_config sama5d2_config = {
static const struct macb_config sama5d3_config = {
.caps = MACB_CAPS_SG_DISABLED | MACB_CAPS_GIGABIT_MODE_AVAILABLE
- | MACB_CAPS_USRIO_DEFAULT_IS_MII_GMII,
+ | MACB_CAPS_USRIO_DEFAULT_IS_MII_GMII
+ | MACB_CAPS_GEM_HAS_PTP,
.dma_burst_length = 16,
.clk_init = macb_clk_init,
.init = macb_init,
};
static const struct macb_config sama5d4_config = {
- .caps = MACB_CAPS_USRIO_DEFAULT_IS_MII_GMII,
+ .caps = MACB_CAPS_USRIO_DEFAULT_IS_MII_GMII | MACB_CAPS_GEM_HAS_PTP,
.dma_burst_length = 4,
.clk_init = macb_clk_init,
.init = macb_init,
diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h
index 2ee9af8..3ac824a 100644
--- a/drivers/net/ethernet/cadence/macb.h
+++ b/drivers/net/ethernet/cadence/macb.h
@@ -918,8 +918,21 @@ struct macb {
#ifdef CONFIG_MACB_USE_HWSTAMP
void macb_ptp_init(struct net_device *ndev);
+void macb_ptp_do_rxstamp(struct macb *bp, struct sk_buff *skb);
+void macb_ptp_do_txstamp(struct macb *bp, struct sk_buff *skb);
+int macb_ptp_get_ts_info(struct net_device *dev, struct ethtool_ts_info *info);
+#define macb_get_ts_info macb_ptp_get_ts_info
+int macb_hwtst_set(struct net_device *netdev, struct ifreq *ifr, int cmd);
+int macb_hwtst_get(struct net_device *netdev, struct ifreq *ifr);
#else
void macb_ptp_init(struct net_device *ndev) { }
+void macb_ptp_do_rxstamp(struct macb *bp, struct sk_buff *skb) { }
+void macb_ptp_do_txstamp(struct macb *bp, struct sk_buff *skb) { }
+#define macb_get_ts_info ethtool_op_get_ts_info
+int macb_hwtst_set(struct net_device *netdev, struct ifreq *ifr, int cmd)
+ { return -EOPNOTSUPP; }
+int macb_hwtst_get(struct net_device *netdev, struct ifreq *ifr)
+ { return -EOPNOTSUPP; }
#endif
static inline bool macb_is_gem(struct macb *bp)
diff --git a/drivers/net/ethernet/cadence/macb_ptp.c b/drivers/net/ethernet/cadence/macb_ptp.c
index 81ce3a9..f476b55 100644
--- a/drivers/net/ethernet/cadence/macb_ptp.c
+++ b/drivers/net/ethernet/cadence/macb_ptp.c
@@ -227,3 +227,225 @@ void macb_ptp_init(struct net_device *ndev)
dev_info(&bp->pdev->dev, "%s ptp clock registered.\n", GMAC_TIMER_NAME);
}
+/* While the GEM can timestamp PTP packets, it does not mark the RX descriptor
+ * to identify them. UDP packets must be parsed to identify PTP packets.
+ *
+ * Note: Inspired from drivers/net/ethernet/ti/cpts.c
+ */
+static int macb_get_ptp_peer(struct sk_buff *skb, int ptp_class)
+{
+ unsigned int offset = 0;
+ u8 *msgtype, *data = skb->data;
+
+ /* PTP frames are rare! */
+ if (likely(ptp_class == PTP_CLASS_NONE))
+ return -1;
+
+ if (ptp_class & PTP_CLASS_VLAN)
+ offset += VLAN_HLEN;
+
+ switch (ptp_class & PTP_CLASS_PMASK) {
+ case PTP_CLASS_IPV4:
+ offset += ETH_HLEN + IPV4_HLEN(data + offset) + UDP_HLEN;
+ break;
+ case PTP_CLASS_IPV6:
+ offset += ETH_HLEN + IP6_HLEN + UDP_HLEN;
+ break;
+ case PTP_CLASS_L2:
+ offset += ETH_HLEN;
+ break;
+
+ /* something went wrong! */
+ default:
+ return -1;
+ }
+
+ if (skb->len + ETH_HLEN < offset + OFF_PTP_SEQUENCE_ID)
+ return -1;
+
+ if (unlikely(ptp_class & PTP_CLASS_V1))
+ msgtype = data + offset + OFF_PTP_CONTROL;
+ else
+ msgtype = data + offset;
+
+ return (*msgtype) & 0x2;
+}
+
+static void macb_ptp_tx_hwtstamp(struct macb *bp, struct sk_buff *skb,
+ int peer_ev)
+{
+ struct skb_shared_hwtstamps *shhwtstamps = skb_hwtstamps(skb);
+ struct timespec64 ts;
+ u64 ns;
+
+ /* PTP Peer Event Frame packets */
+ if (peer_ev) {
+ ts.tv_sec = gem_readl(bp, PEFTSL);
+ ts.tv_nsec = gem_readl(bp, PEFTN);
+
+ /* PTP Event Frame packets */
+ } else {
+ ts.tv_sec = gem_readl(bp, EFTSL);
+ ts.tv_nsec = gem_readl(bp, EFTN);
+ }
+ ns = timespec64_to_ns(&ts);
+
+ memset(shhwtstamps, 0, sizeof(struct skb_shared_hwtstamps));
+ shhwtstamps->hwtstamp = ns_to_ktime(ns);
+ skb_tstamp_tx(skb, skb_hwtstamps(skb));
+}
+
+/* no static since it is called from macb driver! */
+void macb_ptp_do_txstamp(struct macb *bp, struct sk_buff *skb)
+{
+ if (!bp->hwts_tx_en)
+ return;
+
+ if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) {
+ int class = ptp_classify_raw(skb);
+ int peer;
+
+ peer = macb_get_ptp_peer(skb, class);
+ if (peer < 0)
+ return;
+
+ /* Timestamp this packet */
+ macb_ptp_tx_hwtstamp(bp, skb, peer);
+ }
+}
+
+static void macb_ptp_rx_hwtstamp(struct macb *bp, struct sk_buff *skb,
+ int peer_ev)
+{
+ struct skb_shared_hwtstamps *shhwtstamps = skb_hwtstamps(skb);
+ struct timespec64 ts;
+ u64 ns;
+
+ if (peer_ev) {
+ /* PTP Peer Event Frame packets */
+ ts.tv_sec = gem_readl(bp, PEFRSL);
+ ts.tv_nsec = gem_readl(bp, PEFRN);
+ } else {
+ /* PTP Event Frame packets */
+ ts.tv_sec = gem_readl(bp, EFRSL);
+ ts.tv_nsec = gem_readl(bp, EFRN);
+ }
+ ns = timespec64_to_ns(&ts);
+
+ memset(shhwtstamps, 0, sizeof(struct skb_shared_hwtstamps));
+ shhwtstamps->hwtstamp = ns_to_ktime(ns);
+}
+
+/* no static since it is called from macb driver! */
+void macb_ptp_do_rxstamp(struct macb *bp, struct sk_buff *skb)
+{
+ int class;
+ int peer;
+
+ if (!bp->hwts_rx_en)
+ return;
+
+ __skb_push(skb, ETH_HLEN);
+ class = ptp_classify_raw(skb);
+ __skb_pull(skb, ETH_HLEN);
+
+ peer = macb_get_ptp_peer(skb, class);
+ if (peer < 0)
+ return;
+
+ macb_ptp_rx_hwtstamp(bp, skb, peer);
+}
+
+int macb_ptp_get_ts_info(struct net_device *dev, struct ethtool_ts_info *info)
+{
+ struct macb *bp = netdev_priv(dev);
+
+ ethtool_op_get_ts_info(dev, info);
+ info->so_timestamping =
+ SOF_TIMESTAMPING_TX_SOFTWARE |
+ SOF_TIMESTAMPING_RX_SOFTWARE |
+ SOF_TIMESTAMPING_SOFTWARE |
+ SOF_TIMESTAMPING_TX_HARDWARE |
+ SOF_TIMESTAMPING_RX_HARDWARE |
+ SOF_TIMESTAMPING_RAW_HARDWARE;
+ info->phc_index = -1;
+
+ if (bp->ptp_clock)
+ info->phc_index = ptp_clock_index(bp->ptp_clock);
+
+ return 0;
+}
+
+int macb_hwtst_set(struct net_device *netdev, struct ifreq *ifr, int cmd)
+{
+ struct hwtstamp_config config;
+ struct macb *priv = netdev_priv(netdev);
+ u32 regval;
+
+ netdev_vdbg(netdev, "macb_hwtstamp_ioctl\n");
+
+ if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
+ return -EFAULT;
+
+ /* reserved for future extensions */
+ if (config.flags)
+ return -EINVAL;
+
+ switch (config.tx_type) {
+ case HWTSTAMP_TX_OFF:
+ priv->hwts_tx_en = 0;
+ break;
+ case HWTSTAMP_TX_ON:
+ priv->hwts_tx_en = 1;
+ break;
+ default:
+ return -ERANGE;
+ }
+
+ switch (config.rx_filter) {
+ case HWTSTAMP_FILTER_NONE:
+ if (priv->hwts_rx_en)
+ priv->hwts_rx_en = 0;
+ break;
+ case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
+ case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
+ case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
+ case HWTSTAMP_FILTER_ALL:
+ case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
+ case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
+ case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
+ case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
+ case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
+ case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
+ case HWTSTAMP_FILTER_PTP_V2_EVENT:
+ case HWTSTAMP_FILTER_PTP_V2_SYNC:
+ case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
+ config.rx_filter = HWTSTAMP_FILTER_ALL;
+ regval = macb_readl(priv, NCR);
+ macb_writel(priv, NCR, (regval | MACB_BIT(SRTSM)));
+
+ if (!priv->hwts_rx_en)
+ priv->hwts_rx_en = 1;
+ break;
+ default:
+ return -ERANGE;
+ }
+
+ return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ?
+ -EFAULT : 0;
+}
+
+int macb_hwtst_get(struct net_device *netdev, struct ifreq *ifr)
+{
+ struct hwtstamp_config config;
+ struct macb *priv = netdev_priv(netdev);
+
+ config.flags = 0;
+ config.tx_type = priv->hwts_tx_en ? HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF;
+ config.rx_filter = (priv->hwts_rx_en ?
+ HWTSTAMP_FILTER_ALL : HWTSTAMP_FILTER_NONE);
+
+ return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ?
+ -EFAULT : 0;
+}
+
--
1.9.1
^ permalink raw reply related
* [PATCH v16 13/15] acpi/arm64: Add memory-mapped timer support in GTDT driver
From: Lorenzo Pieralisi @ 2016-11-18 14:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1479304148-2965-14-git-send-email-fu.wei@linaro.org>
On Wed, Nov 16, 2016 at 09:49:06PM +0800, fu.wei at linaro.org wrote:
> From: Fu Wei <fu.wei@linaro.org>
>
> On platforms booting with ACPI, architected memory-mapped timers'
> configuration data is provided by firmware through the ACPI GTDT
> static table.
>
> The clocksource architected timer kernel driver requires a firmware
> interface to collect timer configuration and configure its driver.
> this infrastructure is present for device tree systems, but it is
> missing on systems booting with ACPI.
>
> Implement the kernel infrastructure required to parse the static
> ACPI GTDT table so that the architected timer clocksource driver can
> make use of it on systems booting with ACPI, therefore enabling
> the corresponding timers configuration.
>
> Signed-off-by: Fu Wei <fu.wei@linaro.org>
> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
> ---
> drivers/acpi/arm64/gtdt.c | 95 +++++++++++++++++++++++++++++++++++++++++++++++
> include/linux/acpi.h | 1 +
> 2 files changed, 96 insertions(+)
>
> diff --git a/drivers/acpi/arm64/gtdt.c b/drivers/acpi/arm64/gtdt.c
> index 2de79aa..08d9506 100644
> --- a/drivers/acpi/arm64/gtdt.c
> +++ b/drivers/acpi/arm64/gtdt.c
> @@ -51,6 +51,14 @@ static inline bool is_timer_block(void *platform_timer)
> return gh->type == ACPI_GTDT_TYPE_TIMER_BLOCK;
> }
>
> +static inline struct acpi_gtdt_timer_block *get_timer_block(unsigned int index)
> +{
> + if (index >= acpi_gtdt_desc.timer_block_count || !timer_block)
> + return NULL;
> +
> + return timer_block[index];
> +}
> +
> static inline bool is_watchdog(void *platform_timer)
> {
> struct acpi_gtdt_header *gh = platform_timer;
> @@ -214,3 +222,90 @@ int __init acpi_gtdt_init(struct acpi_table_header *table)
> acpi_gtdt_release();
> return -EINVAL;
> }
> +
> +/*
> + * Get ONE GT block info for memory-mapped timer from GTDT table.
> + * @data: the GT block data (parsing result)
> + * @index: the index number of GT block
> + * Note: we already verify @data in caller, it can't be NULL here.
> + * Returns 0 if success, -EINVAL/-ENODEV if error.
> + */
Documentation/kernel-doc-nano-HOWTO.txt
> +int __init gtdt_arch_timer_mem_init(struct arch_timer_mem *data,
> + unsigned int index)
Nit: acpi_arch_timer_mem_init() to make it consistent with other ACPI
calls ?
> +{
> + struct acpi_gtdt_timer_block *block;
> + struct acpi_gtdt_timer_entry *frame;
> + int i;
> +
> + block = get_timer_block(index);
> + if (!block)
> + return -ENODEV;
> +
> + if (!block->timer_count) {
> + pr_err(FW_BUG "GT block present, but frame count is zero.");
> + return -ENODEV;
> + }
> +
> + if (block->timer_count > ARCH_TIMER_MEM_MAX_FRAMES) {
> + pr_err(FW_BUG "GT block lists %d frames, ACPI spec only allows 8\n",
> + block->timer_count);
> + return -EINVAL;
> + }
Nit: these two checks can be carried out at GTDT init where the GTDT
is parsed first. Actually you could have two functions one to init
timers (say acpi_gtdt_timers_init()) and one watchdogs, that would
eliminate the duplicated timer_block/watchdog arrays (both sized
Platform Timer Count) and acpi_gtdt_timers_init() can return
the number of entries found so that you can loop with a determined
upper bound in the arm arch timer driver.
Just thinking aloud, these are just improvements I can carry them
out later, the more important question here is the interface between the
parsing code and the arch timer probing code which depends on other
patches and that needs to be agreed, this patch is not really a problem.
> + data->cntctlbase = (phys_addr_t)block->block_address;
> + /*
> + * We can NOT get the size info from GTDT table,
> + * but according to "Table * CNTCTLBase memory map" of
> + * <ARM Architecture Reference Manual> for ARMv8,
> + * it should be 4KB(Offset 0x000 ? 0xFFC).
That's the reason why it is not explicit in the GTDT table :)
> + data->size = SZ_4K;
> + data->num_frames = block->timer_count;
> +
> + frame = (void *)block + block->timer_offset;
> + if (frame + block->timer_count != (void *)block + block->header.length)
> + return -EINVAL;
> +
> + /*
> + * Get the GT timer Frame data for every GT Block Timer
> + */
> + for (i = 0; i < block->timer_count; i++, frame++) {
> + if (!frame->base_address || !frame->timer_interrupt)
> + return -EINVAL;
> +
> + data->frame[i].phys_irq = map_gt_gsi(frame->timer_interrupt,
> + frame->timer_flags);
> + if (data->frame[i].phys_irq <= 0) {
> + pr_warn("failed to map physical timer irq in frame %d.\n",
> + i);
> + return -EINVAL;
> + }
> +
> + if (frame->virtual_timer_interrupt) {
> + data->frame[i].virt_irq =
> + map_gt_gsi(frame->virtual_timer_interrupt,
> + frame->virtual_timer_flags);
> + if (data->frame[i].virt_irq <= 0) {
> + pr_warn("failed to map virtual timer irq in frame %d.\n",
> + i);
> + return -EINVAL;
You should unregister phys_irq here for correctness, right ?
> + }
> + }
> +
> + data->frame[i].frame_nr = frame->frame_number;
> + data->frame[i].cntbase = frame->base_address;
> + /*
> + * We can NOT get the size info from GTDT table,
> + * but according to "Table * CNTBaseN memory map" of
> + * <ARM Architecture Reference Manual> for ARMv8,
> + * it should be 4KB(Offset 0x000 ? 0xFFC).
See above.
> + */
> + data->frame[i].size = SZ_4K;
> + }
> +
> + if (acpi_gtdt_desc.timer_block_count)
> + pr_info("parsed No.%d of %d memory-mapped timer block(s).\n",
> + index, acpi_gtdt_desc.timer_block_count);
I am not sure how helpful this message can be honestly.
> +
> + return 0;
> +}
> diff --git a/include/linux/acpi.h b/include/linux/acpi.h
> index a1611d1..44b8c1b 100644
> --- a/include/linux/acpi.h
> +++ b/include/linux/acpi.h
> @@ -582,6 +582,7 @@ int acpi_gtdt_init(struct acpi_table_header *table);
> int acpi_gtdt_map_ppi(int type);
> bool acpi_gtdt_c3stop(int type);
> void acpi_gtdt_release(void);
> +int gtdt_arch_timer_mem_init(struct arch_timer_mem *data, unsigned int index);
See above.
Overall it looks fine as long as the interface with clocksource is
settled, which is what really needs to be agreed upon in this series.
Lorenzo
> #endif
>
> #else /* !CONFIG_ACPI */
> --
> 2.7.4
>
^ permalink raw reply
* [PATCH V8 1/3] tracing: add a possibility of exporting function trace to other places instead of ring buffer only
From: Steven Rostedt @ 2016-11-18 14:29 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1479438454-28650-2-git-send-email-zhang.chunyan@linaro.org>
On Fri, 18 Nov 2016 11:07:32 +0800
Chunyan Zhang <zhang.chunyan@linaro.org> wrote:
> Currently Function traces can be only exported to ring buffer, this
> patch added trace_export concept which can process traces and export
> them to a registered destination as an addition to the current only
> one output of Ftrace - i.e. ring buffer.
>
> In this way, if we want Function traces to be sent to other destination
> rather than ring buffer only, we just need to register a new trace_export
> and implement its own .write() function for writing traces to storage.
>
> With this patch, only Function trace (trace type is TRACE_FN)
> is supported.
>
> Signed-off-by: Chunyan Zhang <zhang.chunyan@linaro.org>
This looks good to me, although I would like this to go through my tree
(to make sure it gets all my testing). I understand the next two
patches depend on this, how would you want to go about that?
One is that I can pull it in the next merge window, and the rest go in
after that. Or I can take the other two patches with the proper acks as
well.
-- Steve
^ permalink raw reply
* [PATCHv3 5/6] arm64: Use __pa_symbol for kernel symbols
From: Mark Rutland @ 2016-11-18 14:35 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1479431816-5028-6-git-send-email-labbott@redhat.com>
Hi Laura,
On Thu, Nov 17, 2016 at 05:16:55PM -0800, Laura Abbott wrote:
>
> __pa_symbol is technically the marco that should be used for kernel
> symbols. Switch to this as a pre-requisite for DEBUG_VIRTUAL which
> will do bounds checking.
>
> Signed-off-by: Laura Abbott <labbott@redhat.com>
> ---
> v3: Conversion of more sites besides just _end. Addition of __lm_sym_addr
> macro to take care of the _va(__pa_symbol(..)) idiom.
>
> Note that a copy of __pa_symbol was added to avoid a mess of headers
> since the #ifndef __pa_symbol case is defined in linux/mm.h
I think we also need to fix up virt_to_phys(__cpu_soft_restart) in
arch/arm64/kernel/cpu-reset.h. Otherwise, this looks complete for uses
falling under arch/arm64/.
I also think it's worth mentioning in the commit message that this patch
adds and __lm_sym_addr() and uses it in some places so that low-level
helpers can use virt_to_phys() or __pa() consistently.
The PSCI change doesn't conflict with patches [1] that'll go via
arm-soc, so I'm happy for that PSCI change to go via the arm64 tree,
though it may be worth splitting into its own patch just in case
something unexpected crops up.
With those fixed up:
Reviewed-by: Mark Rutland <mark.rutland@arm.com>
[1] http://lists.infradead.org/pipermail/linux-arm-kernel/2016-November/466522.html
Otherwise, I just have a few nits below.
> @@ -271,7 +271,7 @@ static inline void __kvm_flush_dcache_pud(pud_t pud)
> kvm_flush_dcache_to_poc(page_address(page), PUD_SIZE);
> }
>
> -#define kvm_virt_to_phys(x) __virt_to_phys((unsigned long)(x))
> +#define kvm_virt_to_phys(x) __pa_symbol((unsigned long)(x))
Nit: we can drop the unsigned long cast given __pa_symbol() contains
one.
> diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
> index ffbb9a5..c2041a3 100644
> --- a/arch/arm64/include/asm/pgtable.h
> +++ b/arch/arm64/include/asm/pgtable.h
> @@ -52,7 +52,7 @@ extern void __pgd_error(const char *file, int line, unsigned long val);
> * for zero-mapped memory areas etc..
> */
> extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)];
> -#define ZERO_PAGE(vaddr) pfn_to_page(PHYS_PFN(__pa(empty_zero_page)))
> +#define ZERO_PAGE(vaddr) pfn_to_page(PHYS_PFN(__pa_symbol(empty_zero_page)))
Nit: I think we can also simplify this to:
phys_to_page(__pa_symbol(empty_zero_page))
... since phys_to_page(p) is (pfn_to_page(__phys_to_pfn(p)))
... and __phys_to_pfn(p) is PHYS_PFN(p)
> diff --git a/arch/arm64/kernel/insn.c b/arch/arm64/kernel/insn.c
> index 6f2ac4f..af8967a 100644
> --- a/arch/arm64/kernel/insn.c
> +++ b/arch/arm64/kernel/insn.c
> @@ -97,7 +97,7 @@ static void __kprobes *patch_map(void *addr, int fixmap)
> if (module && IS_ENABLED(CONFIG_DEBUG_SET_MODULE_RONX))
> page = vmalloc_to_page(addr);
> else if (!module)
> - page = pfn_to_page(PHYS_PFN(__pa(addr)));
> + page = pfn_to_page(PHYS_PFN(__pa_symbol(addr)));
Nit: likewise, we can use phys_to_page() here.
> diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c
> index a2c2478..791e87a 100644
> --- a/arch/arm64/kernel/vdso.c
> +++ b/arch/arm64/kernel/vdso.c
> @@ -140,11 +140,11 @@ static int __init vdso_init(void)
> return -ENOMEM;
>
> /* Grab the vDSO data page. */
> - vdso_pagelist[0] = pfn_to_page(PHYS_PFN(__pa(vdso_data)));
> + vdso_pagelist[0] = pfn_to_page(PHYS_PFN(__pa_symbol(vdso_data)));
Nit: phys_to_page() again.
>
> /* Grab the vDSO code pages. */
> for (i = 0; i < vdso_pages; i++)
> - vdso_pagelist[i + 1] = pfn_to_page(PHYS_PFN(__pa(&vdso_start)) + i);
> + vdso_pagelist[i + 1] = pfn_to_page(PHYS_PFN(__pa_symbol(&vdso_start)) + i);
Nit: phys_to_page() again.
Thanks,
Mark.
^ permalink raw reply
* [PATCH] arm: spin one more cycle in timer-based delays
From: Peter Zijlstra @ 2016-11-18 14:42 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <582F0DD2.3030805@free.fr>
On Fri, Nov 18, 2016 at 03:18:58PM +0100, Mason wrote:
> If I understand correctly, udelay is, in fact, a wrapper around
> several possible implementations. (Run-time decision on arch/arm)
>
> 1) The "historical" software loop-based method, which is calibrated
> during init.
>
> 2) A hardware solution, based on an actual timer, ticking away
> at a constant frequency.
I'd say clock, a timer would imply interrupts or somesuch, which is of
course not useful for udelay.
x86 with TSC uses this, although recent chips have grown an timed-mwait
instruction and that too can be used.
The TSC based ones (including the mwait) try very hard to not return
early.
> 3) others?
On x86 there's a variant that times itself based on io port accesses
which have a 'known' slowness.
^ permalink raw reply
* [PATCH V8 3/3] stm: Mark the functions of writing buffer with notrace
From: Alexander Shishkin @ 2016-11-18 14:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1479438454-28650-4-git-send-email-zhang.chunyan@linaro.org>
Chunyan Zhang <zhang.chunyan@linaro.org> writes:
> If CONFIG_STM_SOURCE_FTRACE is selected, Function trace data can be writen
> to sink via STM, all functions that related to writing data packets to
> STM should be marked 'notrace' to avoid being traced by Ftrace, otherwise
> the program would stall into an endless loop.
>
> Signed-off-by: Chunyan Zhang <zhang.chunyan@linaro.org>
> Acked-by: Steven Rostedt <rostedt@goodmis.org>
> ---
> drivers/hwtracing/coresight/coresight-stm.c | 2 +-
> drivers/hwtracing/intel_th/sth.c | 11 +++++++----
> drivers/hwtracing/stm/core.c | 7 ++++---
> drivers/hwtracing/stm/dummy_stm.c | 2 +-
> include/linux/stm.h | 4 ++--
> 5 files changed, 15 insertions(+), 11 deletions(-)
Quick nit: can you please split this one in 4: one for Coresight, one
for Intel TH, one for stm/dummy and one for stm/core?
I'd like to keep the bisectability. Otherwise, this is fine by me:
Acked-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Regards,
--
Alex
^ permalink raw reply
* [PATCH V8 2/3] stm class: ftrace: Add ftrace-export-over-stm driver
From: Alexander Shishkin @ 2016-11-18 14:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1479438454-28650-3-git-send-email-zhang.chunyan@linaro.org>
Chunyan Zhang <zhang.chunyan@linaro.org> writes:
> This patch adds a driver that models itself as an stm_source called
> stm_ftrace. Once the stm device and stm_ftrace have been linked via
> sysfs, the driver registers itself as a trace_export and everything
> passed to the interface from Ftrace subsystem will end up in the STM
> trace engine.
>
> Signed-off-by: Chunyan Zhang <zhang.chunyan@linaro.org>
Acked-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Regards,
--
Alex
^ permalink raw reply
* [PATCH v8 04/16] drivers: iommu: make of_iommu_set/get_ops() DT agnostic
From: Will Deacon @ 2016-11-18 14:49 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161116152936.22955-5-lorenzo.pieralisi@arm.com>
On Wed, Nov 16, 2016 at 03:29:24PM +0000, Lorenzo Pieralisi wrote:
> The of_iommu_{set/get}_ops() API is used to associate a device
> tree node with a specific set of IOMMU operations. The same
> kernel interface is required on systems booting with ACPI, where
> devices are not associated with a device tree node, therefore
> the interface requires generalization.
>
> The struct device fwnode member represents the fwnode token associated
> with the device and the struct it points at is firmware specific;
> regardless, it is initialized on both ACPI and DT systems and makes an
> ideal candidate to use it to associate a set of IOMMU operations to a
> given device, through its struct device.fwnode member pointer, paving
> the way for representing per-device iommu_ops (ie an iommu instance
> associated with a device).
>
> Convert the DT specific of_iommu_{set/get}_ops() interface to
> use struct device.fwnode as a look-up token, making the interface
> usable on ACPI systems and rename the data structures and the
> registration API so that they are made to represent their usage
> more clearly.
>
> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> Reviewed-by: Robin Murphy <robin.murphy@arm.com>
> Reviewed-by: Tomasz Nowicki <tn@semihalf.com>
> Tested-by: Hanjun Guo <hanjun.guo@linaro.org>
> Tested-by: Tomasz Nowicki <tn@semihalf.com>
> Cc: Will Deacon <will.deacon@arm.com>
> Cc: Hanjun Guo <hanjun.guo@linaro.org>
> Cc: Robin Murphy <robin.murphy@arm.com>
> Cc: Joerg Roedel <joro@8bytes.org>
> ---
> drivers/iommu/iommu.c | 40 ++++++++++++++++++++++++++++++++++++++++
> drivers/iommu/of_iommu.c | 39 ---------------------------------------
> include/linux/iommu.h | 14 ++++++++++++++
> include/linux/of_iommu.h | 12 ++++++++++--
> 4 files changed, 64 insertions(+), 41 deletions(-)
Acked-by: Will Deacon <will.deacon@arm.com>
Will
^ permalink raw reply
* [PATCH v8 05/16] drivers: iommu: arm-smmu: convert struct device of_node to fwnode usage
From: Will Deacon @ 2016-11-18 14:49 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161116152936.22955-6-lorenzo.pieralisi@arm.com>
On Wed, Nov 16, 2016 at 03:29:25PM +0000, Lorenzo Pieralisi wrote:
> Current ARM SMMU driver rely on the struct device.of_node pointer for
> device look-up and iommu_ops retrieval.
>
> In preparation for ACPI probing enablement, convert the driver to use
> the struct device.fwnode member for device and iommu_ops look-up so that
> the driver infrastructure can be used also on systems that do not
> associate an of_node pointer to a struct device (eg ACPI), making the
> device look-up and iommu_ops retrieval firmware agnostic.
>
> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> Reviewed-by: Robin Murphy <robin.murphy@arm.com>
> Reviewed-by: Tomasz Nowicki <tn@semihalf.com>
> Tested-by: Hanjun Guo <hanjun.guo@linaro.org>
> Tested-by: Tomasz Nowicki <tn@semihalf.com>
> Cc: Will Deacon <will.deacon@arm.com>
> Cc: Hanjun Guo <hanjun.guo@linaro.org>
> Cc: Robin Murphy <robin.murphy@arm.com>
> ---
> drivers/iommu/arm-smmu.c | 11 ++++++-----
> 1 file changed, 6 insertions(+), 5 deletions(-)
Acked-by: Will Deacon <will.deacon@arm.com>
Will
^ permalink raw reply
* [PATCH v8 06/16] drivers: iommu: arm-smmu-v3: convert struct device of_node to fwnode usage
From: Will Deacon @ 2016-11-18 14:50 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161116152936.22955-7-lorenzo.pieralisi@arm.com>
On Wed, Nov 16, 2016 at 03:29:26PM +0000, Lorenzo Pieralisi wrote:
> Current ARM SMMU v3 driver rely on the struct device.of_node pointer for
> device look-up and iommu_ops retrieval.
>
> In preparation for ACPI probing enablement, convert the driver to use
> the struct device.fwnode member for device and iommu_ops look-up so that
> the driver infrastructure can be used also on systems that do not
> associate an of_node pointer to a struct device (eg ACPI), making the
> device look-up and iommu_ops retrieval firmware agnostic.
>
> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> Reviewed-by: Robin Murphy <robin.murphy@arm.com>
> Reviewed-by: Tomasz Nowicki <tn@semihalf.com>
> Tested-by: Hanjun Guo <hanjun.guo@linaro.org>
> Tested-by: Tomasz Nowicki <tn@semihalf.com>
> Cc: Will Deacon <will.deacon@arm.com>
> Cc: Hanjun Guo <hanjun.guo@linaro.org>
> Cc: Robin Murphy <robin.murphy@arm.com>
> ---
> drivers/iommu/arm-smmu-v3.c | 12 +++++++-----
> 1 file changed, 7 insertions(+), 5 deletions(-)
Acked-by: Will Deacon <will.deacon@arm.com>
Will
^ permalink raw reply
* [PATCH v13 0/5] generic TEE subsystem
From: Jens Wiklander @ 2016-11-18 14:51 UTC (permalink / raw)
To: linux-arm-kernel
Hi,
This patch set introduces a generic TEE subsystem. These patches are used
on HiKey in AOSP. It's currently supported by roughly 20 platforms
(https://github.com/OP-TEE/optee_os#3-platforms-supported), to name a few,
Renesas RCAR H3, Sequitur Labs CoreTEE, Wind River VxWorks etc.
I?m not sure how to progress this. I?ve had only positive feedback on the
previous v12 version. In the previous versions I?ve addressed all feedback
(which has been getting more and more minor) and I haven?t had any response
from Greg since February. Is there anything else we can be doing here to
help progress this?
The TEE subsystem will contain drivers for various TEE implementations. A
TEE (Trusted Execution Environment) is a trusted OS running in some secure
environment, for example, TrustZone on ARM CPUs, or a separate secure
co-processor etc.
Regarding use cases, TrustZone has traditionally been used for
offloading secure tasks to the secure world. Examples include:
- Secure key handling where the OS may or may not have direct access to key
material.
- E-commerce and payment technologies. Credentials, credit card numbers etc
could be stored in a more secure environment.
- Trusted User Interface (TUI) to ensure that no-one can snoop PIN-codes
etc.
- Secure boot to ensure that loaded binaries haven?t been tampered with.
It?s not strictly needed for secure boot, but you could enhance security
by leveraging a TEE during boot.
- Digital Rights Management (DRM), the studios provides content with
different resolution depending on the security of the device. Higher
security means higher resolution.
A TEE could also be used in existing and new technologies. For example IMA
(Integrity Measurement Architecture) which has been in the kernel for quite
a while. Today you can enhance security by using a TPM-chip to sign the IMA
measurement list. This is something that also has been done in practical
systems by leveraging a TEE.
Another example could be in 2-factor authentication which is becoming
increasingly more important. FIDO (https://fidoalliance.org) for example
are using public key cryptography in their 2-factor authentication standard
(U2F). With FIDO, a private and public key pair will be generated for every
site you visit and the private key should never leave the local device.
This is an example where you could use secure storage in a TEE for the
private key.
Today you will find a quite a few different out of tree implementations of
TEE drivers which tends to fragment the TEE ecosystem and development. We
think it would be a good idea to have a generic TEE driver integrated in
the kernel which would serve as a base for several different TEE solutions,
no matter if they are on-chip like TrustZone or if they are on a separate
crypto co-processor.
To develop this TEE subsystem we have been using the open source TEE called
OP-TEE (https://www.op-tee.org/) and therefore this would be the first TEE
solution supported by this new subsystem. OP-TEE is a GlobalPlatform
compliant TEE, however this TEE subsystem is not limited to only
GlobalPlatform TEEs, instead we have tried to design it so that it should
work with other TEE solutions also. Since the first version (2015 April) of
this patchset we?ve talked about it at Linaro Connect, GlobalPlatform
annual TEE conference and last time at Linux Plumbers, so we think there
has been both exposure and plenty of time to be able to get involved in
this work.
"tee: generic TEE subsystem" brings in the generic TEE subsystem which
helps when writing a driver for a specific TEE, for example, OP-TEE.
"tee: add OP-TEE driver" is an OP-TEE driver which uses the subsystem to do
its work.
This patch set has been prepared in cooperation with Javier Gonz?lez who
proposed "Generic TrustZone Driver in Linux Kernel" patches 28 Nov 2014,
https://lwn.net/Articles/623380/ . We've since then changed the scope to
TEE instead of TrustZone.
We have discussed the design on tee-dev at lists.linaro.org (archive at
https://lists.linaro.org/pipermail/tee-dev/) with people from other
companies, including Valentin Manea <valentin.manea@huawei.com>,
Emmanuel MICHEL <emmanuel.michel@st.com>,
Jean-michel DELORME <jean-michel.delorme@st.com>,
and Joakim Bech <joakim.bech@linaro.org>. Our main concern has been to
agree on something that is generic enough to support many different
TEEs while still keeping the interface together.
v13:
* Rebased on v4.9-rc5
* Added Hikey DT patch
* Tested-by: Jerome Forissier <jerome.forissier@linaro.org> (HiKey)
* Tested-by: Volodymyr Babchuk <vlad.babchuk@gmail.com> (RCAR H3)
* Tested-by: Andrew F. Davis <afd@ti.com>
v12-resend:
* Rebased on v4.9-rc2
v12:
* Rebased on v4.8-rc5
* Addressed review comments from Andrew F. Davis
* Removed Acked-by: Andreas Dannenberg <dannenberg@ti.com> as the
mail bounces
* Bugfix possible null dereference in error cleanup path of
optee_probe().
* Bugfix optee_from_msg_param() when calculating offset of memref
into a shared memory object
v11:
* Rebased on v4.8-rc3
* Addressed review comments from Nishanth Menon
* Made the TEE framework available as a loadable module.
* Reviewed-by: Javier Gonz?lez <javier@javigon.com>
* Zeroes shared memory on allocation to avoid information leakage
* Links shared memory objects to context to avoid stealing of shared memory
object from an unrelated process
* Allow RPC interruption if supplicant is unavailable
v10:
* Rebased on v4.7-rc1
* Addressed private review comments from Nishanth Menon
* Optee driver only accepts one supplicant process on the privileged device
* Optee driver avoids long delayed releases of shm objects
* Added more comments on functions and structs
v9:
* Rebased on v4.6-rc1
* Acked-by: Andreas Dannenberg <dannenberg@ti.com>
* Addressed comments from Al Viro how file descriptors are passed to
user space
* Addressed comments from Randy Dunlap on documentation
* Changed license for include/uapi/linux/tee.h
v8:
* Rebased on v4.5-rc3
* dt/bindings: add bindings for optee
Acked-by: Rob Herring <robh@kernel.org>
* Fixes build error for X86
* Fixes spell error in "dt/bindings: add bindings for optee"
v7:
* Rebased on v4.5-rc2
* Moved the ARM SMC Calling Convention support into a separate patch
set, which is now merged
v6:
* Rebased on v4.3-rc7
* Changed smccc interface to let the compiler marshal most of the
parameters
* Added ARCH64 capability for smccc interface
* Changed the PSCI firmware calls (both arm and arm64) to use the new
generic smccc interface instead instead of own assembly functions.
* Move optee DT bindings to below arm/firmware
* Defines method for OP-TEE driver to call secure world in DT, smc or hvc
* Exposes implementation id of a TEE driver in sysfs
to easily spawn corresponding tee-supplicant when device is ready
* Update OP-TEE Message Protocol to better cope with fragmented physical
memory
* Read time directly from OP-TEE driver instead of forwarding the RPC
request to tee-supplicant
v5:
* Replaced kref reference counting for the device with a size_t instead as
the counter is always protected by a mutex
v4:
* Rebased on 4.1
* Redesigned the synchronization around entry exit of normal SMC
* Replaced rwsem on the driver instance with kref and completion since
rwsem wasn't intended to be used in this way
* Expanded the TEE_IOCTL_PARAM_ATTR_TYPE_MASK to make room for
future additional parameter types
* Documents TEE subsystem and OP-TEE driver
* Replaced TEE_IOC_CMD with TEE_IOC_OPEN_SESSION, TEE_IOC_INVOKE,
TEE_IOC_CANCEL and TEE_IOC_CLOSE_SESSION
* DT bindings in a separate patch
* Assembly parts moved to arch/arm and arch/arm64 respectively, in a
separate patch
* Redefined/clarified the meaning of OPTEE_SMC_SHM_CACHED
* Removed CMA usage to limit the scope of the patch set
v3:
* Rebased on 4.1-rc3 (dma_buf_export() API change)
* A couple of small sparse fixes
* Documents bindings for OP-TEE driver
* Updated MAINTAINERS
v2:
* Replaced the stubbed OP-TEE driver with a real OP-TEE driver
* Removed most APIs not needed by OP-TEE in current state
* Update Documentation/ioctl/ioctl-number.txt with correct path to tee.h
* Rename tee_shm_pool_alloc_cma() to tee_shm_pool_alloc()
* Moved tee.h into include/uapi/linux/
* Redefined tee.h IOCTL macros to be directly based on _IOR and friends
* Removed version info on the API to user space, a data blob which
can contain an UUID is left for user space to be able to tell which
protocol to use in TEE_IOC_CMD
* Changed user space exposed structures to only have types with __ prefix
* Dropped THIS_MODULE from tee_fops
* Reworked how the driver is registered and ref counted:
- moved from using an embedded struct miscdevice to an embedded struct
device.
- uses an struct rw_semaphore as synchronization for driver detachment
- uses alloc/register pattern from TPM
Thanks,
Jens
Jens Wiklander (4):
dt/bindings: add bindings for optee
tee: generic TEE subsystem
tee: add OP-TEE driver
Documentation: tee subsystem and op-tee driver
Jerome Forissier (1):
arm64: dt: hikey: Add optee node
Documentation/00-INDEX | 2 +
.../bindings/arm/firmware/linaro,optee-tz.txt | 31 +
.../devicetree/bindings/vendor-prefixes.txt | 1 +
Documentation/ioctl/ioctl-number.txt | 1 +
Documentation/tee.txt | 118 +++
MAINTAINERS | 13 +
arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts | 7 +
drivers/Kconfig | 2 +
drivers/Makefile | 1 +
drivers/tee/Kconfig | 18 +
drivers/tee/Makefile | 5 +
drivers/tee/optee/Kconfig | 7 +
drivers/tee/optee/Makefile | 5 +
drivers/tee/optee/call.c | 435 ++++++++++
drivers/tee/optee/core.c | 598 ++++++++++++++
drivers/tee/optee/optee_msg.h | 435 ++++++++++
drivers/tee/optee/optee_private.h | 185 +++++
drivers/tee/optee/optee_smc.h | 446 ++++++++++
drivers/tee/optee/rpc.c | 404 +++++++++
drivers/tee/optee/supp.c | 273 +++++++
drivers/tee/tee_core.c | 901 +++++++++++++++++++++
drivers/tee/tee_private.h | 129 +++
drivers/tee/tee_shm.c | 357 ++++++++
drivers/tee/tee_shm_pool.c | 158 ++++
include/linux/tee_drv.h | 278 +++++++
include/uapi/linux/tee.h | 401 +++++++++
26 files changed, 5211 insertions(+)
create mode 100644 Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt
create mode 100644 Documentation/tee.txt
create mode 100644 drivers/tee/Kconfig
create mode 100644 drivers/tee/Makefile
create mode 100644 drivers/tee/optee/Kconfig
create mode 100644 drivers/tee/optee/Makefile
create mode 100644 drivers/tee/optee/call.c
create mode 100644 drivers/tee/optee/core.c
create mode 100644 drivers/tee/optee/optee_msg.h
create mode 100644 drivers/tee/optee/optee_private.h
create mode 100644 drivers/tee/optee/optee_smc.h
create mode 100644 drivers/tee/optee/rpc.c
create mode 100644 drivers/tee/optee/supp.c
create mode 100644 drivers/tee/tee_core.c
create mode 100644 drivers/tee/tee_private.h
create mode 100644 drivers/tee/tee_shm.c
create mode 100644 drivers/tee/tee_shm_pool.c
create mode 100644 include/linux/tee_drv.h
create mode 100644 include/uapi/linux/tee.h
--
1.9.1
^ permalink raw reply
* [PATCH v13 1/5] dt/bindings: add bindings for optee
From: Jens Wiklander @ 2016-11-18 14:51 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1479480700-554-1-git-send-email-jens.wiklander@linaro.org>
Introduces linaro prefix and adds bindings for ARM TrustZone based OP-TEE
implementation.
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
---
.../bindings/arm/firmware/linaro,optee-tz.txt | 31 ++++++++++++++++++++++
.../devicetree/bindings/vendor-prefixes.txt | 1 +
2 files changed, 32 insertions(+)
create mode 100644 Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt
diff --git a/Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt b/Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt
new file mode 100644
index 0000000..d38834c
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt
@@ -0,0 +1,31 @@
+OP-TEE Device Tree Bindings
+
+OP-TEE is a piece of software using hardware features to provide a Trusted
+Execution Environment. The security can be provided with ARM TrustZone, but
+also by virtualization or a separate chip.
+
+We're using "linaro" as the first part of the compatible property for
+the reference implementation maintained by Linaro.
+
+* OP-TEE based on ARM TrustZone required properties:
+
+- compatible : should contain "linaro,optee-tz"
+
+- method : The method of calling the OP-TEE Trusted OS. Permitted
+ values are:
+
+ "smc" : SMC #0, with the register assignments specified
+ in drivers/tee/optee/optee_smc.h
+
+ "hvc" : HVC #0, with the register assignments specified
+ in drivers/tee/optee/optee_smc.h
+
+
+
+Example:
+ firmware {
+ optee {
+ compatible = "linaro,optee-tz";
+ method = "smc";
+ };
+ };
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index f0a48ea..6ab5d04 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -155,6 +155,7 @@ lacie LaCie
lantiq Lantiq Semiconductor
lenovo Lenovo Group Ltd.
lg LG Corporation
+linaro Linaro Limited
linux Linux-specific binding
lltc Linear Technology Corporation
lsi LSI Corp. (LSI Logic)
--
1.9.1
^ 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