* [PATCH 1/9] ARM: dts: pxa2xx fix compatible strings
[not found] ` <1386543229-1542-1-git-send-email-ynvich@gmail.com>
@ 2013-12-08 22:53 ` Sergei Ianovich
2013-12-08 22:53 ` [PATCH 2/9] ARM: dts: fix pxa27x-gpio interrupts Sergei Ianovich
` (3 subsequent siblings)
4 siblings, 0 replies; 148+ messages in thread
From: Sergei Ianovich @ 2013-12-08 22:53 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel
Cc: Sergei Ianovich, Daniel Mack, Arnd Bergmann, Rob Herring,
Pawel Moll, Mark Rutland, Stephen Warren, Ian Campbell,
Russell King, open list:OPEN FIRMWARE AND...
Signed-off-by: Sergei Ianovich <ynvich@gmail.com>
CC: Daniel Mack <zonque@gmail.com>
CC: Arnd Bergmann <arnd@arndb.de>
---
arch/arm/boot/dts/pxa2xx.dtsi | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/arch/arm/boot/dts/pxa2xx.dtsi b/arch/arm/boot/dts/pxa2xx.dtsi
index a5e90f0..3419f87 100644
--- a/arch/arm/boot/dts/pxa2xx.dtsi
+++ b/arch/arm/boot/dts/pxa2xx.dtsi
@@ -18,7 +18,6 @@
serial1 = &btuart;
serial2 = &stuart;
serial3 = &hwuart;
- i2c0 = &pwri2c;
i2c1 = &pxai2c1;
};
@@ -113,14 +112,14 @@
};
usb0: ohci@4c000000 {
- compatible = "mrvl,pxa-ohci";
+ compatible = "marvell,pxa-ohci";
reg = <0x4c000000 0x10000>;
interrupts = <3>;
status = "disabled";
};
mmc0: mmc@41100000 {
- compatible = "mrvl,pxa-mmc";
+ compatible = "marvell,pxa-mmc";
reg = <0x41100000 0x1000>;
interrupts = <23>;
status = "disabled";
--
1.8.4.3
^ permalink raw reply related [flat|nested] 148+ messages in thread
* [PATCH 2/9] ARM: dts: fix pxa27x-gpio interrupts
[not found] ` <1386543229-1542-1-git-send-email-ynvich@gmail.com>
2013-12-08 22:53 ` [PATCH 1/9] ARM: dts: pxa2xx fix compatible strings Sergei Ianovich
@ 2013-12-08 22:53 ` Sergei Ianovich
2013-12-08 22:53 ` [PATCH 5/9] ARM: dts: provide DMA config to pxamci Sergei Ianovich
` (2 subsequent siblings)
4 siblings, 0 replies; 148+ messages in thread
From: Sergei Ianovich @ 2013-12-08 22:53 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel
Cc: Sergei Ianovich, Daniel Mack, Arnd Bergmann, Rob Herring,
Pawel Moll, Mark Rutland, Stephen Warren, Ian Campbell,
Russell King, open list:OPEN FIRMWARE AND...
Signed-off-by: Sergei Ianovich <ynvich@gmail.com>
CC: Daniel Mack <zonque@gmail.com>
CC: Arnd Bergmann <arnd@arndb.de>
---
arch/arm/boot/dts/pxa27x.dtsi | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/arch/arm/boot/dts/pxa27x.dtsi b/arch/arm/boot/dts/pxa27x.dtsi
index d7c5d72..44df554 100644
--- a/arch/arm/boot/dts/pxa27x.dtsi
+++ b/arch/arm/boot/dts/pxa27x.dtsi
@@ -10,5 +10,11 @@
marvell,intc-priority;
marvell,intc-nr-irqs = <34>;
};
+
+ gpio: gpio@40e00000 {
+ compatible = "intel,pxa27x-gpio";
+ interrupts = <8>, <9>, <10>;
+ interrupt-names = "gpio0", "gpio1", "gpio_mux";
+ };
};
};
--
1.8.4.3
^ permalink raw reply related [flat|nested] 148+ messages in thread
* [PATCH 5/9] ARM: dts: provide DMA config to pxamci
[not found] ` <1386543229-1542-1-git-send-email-ynvich@gmail.com>
2013-12-08 22:53 ` [PATCH 1/9] ARM: dts: pxa2xx fix compatible strings Sergei Ianovich
2013-12-08 22:53 ` [PATCH 2/9] ARM: dts: fix pxa27x-gpio interrupts Sergei Ianovich
@ 2013-12-08 22:53 ` Sergei Ianovich
2013-12-09 1:33 ` Arnd Bergmann
2013-12-08 22:53 ` [PATCH 9/9] ARM: pxa27x: device tree support ICP DAS LP-8x4x Sergei Ianovich
[not found] ` <1386901645-28895-1-git-send-email-ynvich@gmail.com>
4 siblings, 1 reply; 148+ messages in thread
From: Sergei Ianovich @ 2013-12-08 22:53 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel
Cc: Sergei Ianovich, Daniel Mack, Arnd Bergmann, Rob Herring,
Pawel Moll, Mark Rutland, Stephen Warren, Ian Campbell,
Rob Landley, Russell King, Chris Ball, Ulf Hansson, Jaehoon Chung,
Seungwon Jeon, open list:OPEN FIRMWARE AND...,
open list:DOCUMENTATION
Non-dts implementation supply required DMA channel numbers as
IORESOURCE_DMA. However, there is was no way to get them from
device tree.
Signed-off-by: Sergei Ianovich <ynvich@gmail.com>
CC: Daniel Mack <zonque@gmail.com>
CC: Arnd Bergmann <arnd@arndb.de>
---
Documentation/devicetree/bindings/mmc/pxa-mmc.txt | 2 +
arch/arm/boot/dts/pxa27x.dtsi | 4 ++
drivers/mmc/host/pxamci.c | 50 ++++++++++++++++++-----
3 files changed, 45 insertions(+), 11 deletions(-)
diff --git a/Documentation/devicetree/bindings/mmc/pxa-mmc.txt b/Documentation/devicetree/bindings/mmc/pxa-mmc.txt
index b7025de..27447ec 100644
--- a/Documentation/devicetree/bindings/mmc/pxa-mmc.txt
+++ b/Documentation/devicetree/bindings/mmc/pxa-mmc.txt
@@ -5,6 +5,7 @@ Driver bindings for the PXA MCI (MMC/SDIO) interfaces
Required properties:
- compatible: Should be "marvell,pxa-mmc".
- vmmc-supply: A regulator for VMMC
+- marvell,dma-channels: 2 PXA DMA channels [0] for RX, [1] for TX
Optional properties:
- marvell,detect-delay-ms: sets the detection delay timeout in ms.
@@ -19,6 +20,7 @@ mmc0: mmc@41100000 {
compatible = "marvell,pxa-mmc";
reg = <0x41100000 0x1000>;
interrupts = <23>;
+ marvell,dma-channels = <21 22>;
cd-gpios = <&gpio 23 0>;
wp-gpios = <&gpio 24 0>;
};
diff --git a/arch/arm/boot/dts/pxa27x.dtsi b/arch/arm/boot/dts/pxa27x.dtsi
index 44df554..3f97520 100644
--- a/arch/arm/boot/dts/pxa27x.dtsi
+++ b/arch/arm/boot/dts/pxa27x.dtsi
@@ -16,5 +16,9 @@
interrupts = <8>, <9>, <10>;
interrupt-names = "gpio0", "gpio1", "gpio_mux";
};
+
+ mmc@41100000 {
+ marvell,dma-channels = <21 22>;
+ };
};
};
diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c
index 32fe113..8c7a110 100644
--- a/drivers/mmc/host/pxamci.c
+++ b/drivers/mmc/host/pxamci.c
@@ -613,11 +613,37 @@ static int pxamci_of_init(struct platform_device *pdev)
return 0;
}
+
+static int pxamci_of_init_dma(struct platform_device *pdev,
+ struct pxamci_host *host)
+{
+ struct device_node *np = pdev->dev.of_node;
+ u32 tmp;
+ int ret;
+
+ ret = of_property_read_u32_index(np, "marvell,dma-channels", 0, &tmp);
+ if (ret < 0)
+ return ret;
+ host->dma_drcmrrx = tmp;
+
+ ret = of_property_read_u32_index(np, "marvell,dma-channels", 1, &tmp);
+ if (ret < 0)
+ return ret;
+ host->dma_drcmrtx = tmp;
+
+ return 0;
+}
#else
static int pxamci_of_init(struct platform_device *pdev)
{
return 0;
}
+
+static int pxamci_of_init_dma(struct platform_device *pdev,
+ struct pxamci_host *host)
+{
+ return -ENODATA;
+}
#endif
static int pxamci_probe(struct platform_device *pdev)
@@ -741,19 +767,21 @@ static int pxamci_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, mmc);
- dmarx = platform_get_resource(pdev, IORESOURCE_DMA, 0);
- if (!dmarx) {
- ret = -ENXIO;
- goto out;
- }
- host->dma_drcmrrx = dmarx->start;
+ if (pxamci_of_init_dma(pdev, host) < 0) {
+ dmarx = platform_get_resource(pdev, IORESOURCE_DMA, 0);
+ if (!dmarx) {
+ ret = -ENXIO;
+ goto out;
+ }
+ host->dma_drcmrrx = dmarx->start;
- dmatx = platform_get_resource(pdev, IORESOURCE_DMA, 1);
- if (!dmatx) {
- ret = -ENXIO;
- goto out;
+ dmatx = platform_get_resource(pdev, IORESOURCE_DMA, 1);
+ if (!dmatx) {
+ ret = -ENXIO;
+ goto out;
+ }
+ host->dma_drcmrtx = dmatx->start;
}
- host->dma_drcmrtx = dmatx->start;
if (host->pdata) {
gpio_cd = host->pdata->gpio_card_detect;
--
1.8.4.3
^ permalink raw reply related [flat|nested] 148+ messages in thread
* [PATCH 9/9] ARM: pxa27x: device tree support ICP DAS LP-8x4x
[not found] ` <1386543229-1542-1-git-send-email-ynvich@gmail.com>
` (2 preceding siblings ...)
2013-12-08 22:53 ` [PATCH 5/9] ARM: dts: provide DMA config to pxamci Sergei Ianovich
@ 2013-12-08 22:53 ` Sergei Ianovich
2013-12-09 1:47 ` Arnd Bergmann
[not found] ` <1386901645-28895-1-git-send-email-ynvich@gmail.com>
4 siblings, 1 reply; 148+ messages in thread
From: Sergei Ianovich @ 2013-12-08 22:53 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel
Cc: Sergei Ianovich, Daniel Mack, Arnd Bergmann, Olof Johansson,
Linus Walleij, Rob Herring, Pawel Moll, Mark Rutland,
Stephen Warren, Ian Campbell, Russell King, Eric Miao,
Haojian Zhuang, open list:OPEN FIRMWARE AND...
ICP DAS calls LP-8x4x 'programmable automation controller'. It is
an industrial computer based on PXA270 SoC. They ship it with a 2.6.19
kernel and proprietary kernel module and userspace library to access
its industrial IO.
This patch allows to boot the device with a modern kernel with device
tree. It adds support for:
* MMC card interface on PXA270
* USB 1.1 port on PXA270
* 2 NOR flash devices
* 2 onboard ethernet Davicom DM9000 devices
* 3 serial UART ports on PXA270
Support for these devices will be added in separate patches, since
they are not currently supported by the kernel:
* DS1302 RTC
* 512kiB SRAM
* FPGA irq chip
* 3 built-in and up to 32 pluggable 8250 serial UART ports
* industrial IO parallel bus
* digital and analog industrial IO modules for parallel bus
* serial interface for digital and analog industrial IO modules on
parallel bus
Not supported for now:
* VGA interface on PXA270 for lack of dts binding
Signed-off-by: Sergei Ianovich <ynvich@gmail.com>
CC: Daniel Mack <zonque@gmail.com>
CC: Arnd Bergmann <arnd@arndb.de>
CC: Olof Johansson <olof@lixom.net>
CC: Linus Walleij <linus.walleij@linaro.org>
---
Changes v2..v3:
* further clean up defconfig (minus 100 lines more) as suggested
by Arnd Bergmann
* rewrite machine support code to use device tree
changes v1..v2
* clean up defconfig (reduces size by 10) as suggested
by Arnd Bergmann
* the rest is now irrelevant
arch/arm/boot/dts/Makefile | 1 +
arch/arm/boot/dts/pxa27x-lp8x4x.dts | 111 ++++++++++++++++++++++++
arch/arm/configs/lp8x4x_defconfig | 162 ++++++++++++++++++++++++++++++++++++
arch/arm/mach-pxa/Kconfig | 31 +++++++
arch/arm/mach-pxa/Makefile | 1 +
arch/arm/mach-pxa/pxa27x-dt.c | 97 +++++++++++++++++++++
6 files changed, 403 insertions(+)
create mode 100644 arch/arm/boot/dts/pxa27x-lp8x4x.dts
create mode 100644 arch/arm/configs/lp8x4x_defconfig
create mode 100644 arch/arm/mach-pxa/pxa27x-dt.c
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index d57c1a6..c4752ff 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -206,6 +206,7 @@ dtb-$(CONFIG_ARCH_OMAP2PLUS) += omap2420-h4.dtb \
dra7-evm.dtb
dtb-$(CONFIG_ARCH_ORION5X) += orion5x-lacie-ethernet-disk-mini-v2.dtb
dtb-$(CONFIG_ARCH_PRIMA2) += prima2-evb.dtb
+dtb-$(CONFIG_MACH_PXA27X_DT) += pxa27x-lp8x4x.dtb
dtb-$(CONFIG_ARCH_U8500) += ste-snowball.dtb \
ste-hrefprev60-stuib.dtb \
ste-hrefprev60-tvk.dtb \
diff --git a/arch/arm/boot/dts/pxa27x-lp8x4x.dts b/arch/arm/boot/dts/pxa27x-lp8x4x.dts
new file mode 100644
index 0000000..b288c98
--- /dev/null
+++ b/arch/arm/boot/dts/pxa27x-lp8x4x.dts
@@ -0,0 +1,111 @@
+/* Device tree for ICP DAS LP-8x4x */
+/dts-v1/;
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include "pxa27x.dtsi"
+
+/ {
+ model = "ICP DAS LP-8x4x programmable automation controller";
+ compatible = "marvell,lp8x4x", "marvell,pxa27x";
+
+ memory {
+ reg = <0xa0000000 0x08000000>;
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ vmmc: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "vmmc";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ };
+
+ flash@00000000 {
+ compatible = "cfi-flash";
+ reg = <0x0 0x02000000>;
+ bank-width = <4>;
+ device-width = <2>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ fs@0 {
+ label = "u-boot";
+ reg = <0 0x40000>;
+ };
+ fs@40000 {
+ label = "settings";
+ reg = <0x40000 0x40000>;
+ };
+ fs@80000 {
+ label = "kernel";
+ reg = <0x80000 0x280000>;
+ };
+ fs@300000 {
+ label = "root_fs";
+ reg = <0x300000 0x1d00000>;
+ };
+ };
+
+ flash@04000000 {
+ compatible = "cfi-flash";
+ reg = <0x04000000 0x02000000>;
+ bank-width = <2>;
+ device-width = <1>;
+ };
+
+ pxabus {
+ pxairq: interrupt-controller@40d00000 {
+ marvell,intc-priority;
+ marvell,intc-nr-irqs = <34>;
+ };
+
+ uart@40100000 {
+ status = "okay";
+ };
+
+ uart@40200000 {
+ status = "okay";
+ };
+
+ uart@40700000 {
+ status = "okay";
+ };
+
+ mmc@41100000 {
+ status = "okay";
+ vmmc-supply = <&vmmc>;
+ marvell,dma-channels = <21 22>;
+ };
+
+ ohci@4c000000 {
+ status = "okay";
+ marvell,port-mode = <3>;
+ marvell,oc-mode-perport;
+ marvell,enable-port1;
+ };
+
+ eth0: eth@0c000000 {
+ compatible = "davicom,dm9000";
+ reg = <0x0c000000 0x2
+ 0x0c004000 0x2>;
+ interrupt-parent = <&gpio>;
+ interrupts = <9 IRQ_TYPE_EDGE_RISING>;
+ status = "okay";
+ };
+
+ eth1: eth@0d000000 {
+ compatible = "davicom,dm9000";
+ reg = <0x0d000000 0x2
+ 0x0d004000 0x2>;
+ interrupt-parent = <&gpio>;
+ interrupts = <82 IRQ_TYPE_EDGE_RISING>;
+ status = "okay";
+ };
+ };
+};
diff --git a/arch/arm/configs/lp8x4x_defconfig b/arch/arm/configs/lp8x4x_defconfig
new file mode 100644
index 0000000..faaa604
--- /dev/null
+++ b/arch/arm/configs/lp8x4x_defconfig
@@ -0,0 +1,162 @@
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_RCU_BOOST=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+# CONFIG_UID16 is not set
+# CONFIG_SHMEM is not set
+CONFIG_EMBEDDED=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLOB=y
+CONFIG_JUMP_LABEL=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+# CONFIG_LBDAF is not set
+CONFIG_BLK_CMDLINE_PARSER=y
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+CONFIG_ARCH_PXA=y
+CONFIG_MACH_PXA27X_DT=y
+CONFIG_MACH_LP8X4X=y
+# CONFIG_ARM_THUMB is not set
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+# CONFIG_COMPACTION is not set
+# CONFIG_CROSS_MEMORY_ATTACH is not set
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="init=/sbin/init root=/dev/mmcblk0p1 rw rootfstype=ext4 console=ttyS0,115200 mem=128M rootwait"
+# CONFIG_SUSPEND is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_BRIDGE=m
+CONFIG_BRIDGE_VLAN_FILTERING=y
+CONFIG_VLAN_8021Q=m
+CONFIG_VLAN_8021Q_GVRP=y
+CONFIG_VLAN_8021Q_MVRP=y
+# CONFIG_WIRELESS is not set
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_FW_LOADER is not set
+CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_GEOMETRY=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_PHYSMAP_OF=y
+CONFIG_PROC_DEVICETREE=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_LOOP_MIN_COUNT=2
+CONFIG_SCSI=y
+# CONFIG_SCSI_PROC_FS is not set
+CONFIG_BLK_DEV_SD=y
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_NETDEVICES=y
+CONFIG_BONDING=m
+CONFIG_MACVLAN=m
+CONFIG_MACVTAP=m
+CONFIG_TUN=m
+# CONFIG_NET_VENDOR_ARC is not set
+# CONFIG_NET_CADENCE is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CIRRUS is not set
+CONFIG_DM9000=y
+CONFIG_DM9000_FORCE_SIMPLE_PHY_POLL=y
+# CONFIG_NET_VENDOR_FARADAY 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_SEEQ is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_VIA is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
+CONFIG_PPP=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPPOE=m
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+# CONFIG_WLAN is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=800
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=600
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_8250=y
+# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=40
+CONFIG_SERIAL_8250_RUNTIME_UARTS=40
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_MANY_PORTS=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_PXA=y
+CONFIG_HW_RANDOM=y
+CONFIG_I2C=m
+# CONFIG_I2C_COMPAT is not set
+CONFIG_I2C_PXA=m
+CONFIG_I2C_PXA_SLAVE=y
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_SA1100_WATCHDOG=m
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_FB=y
+CONFIG_FB_PXA=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_LOGO=y
+CONFIG_USB=m
+CONFIG_USB_OHCI_HCD=m
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+CONFIG_USB_STORAGE=m
+CONFIG_USB_SERIAL=m
+CONFIG_MMC=y
+CONFIG_MMC_PXA=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_PXA=m
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_EXT2_FS=m
+CONFIG_EXT3_FS=y
+CONFIG_EXT4_FS=y
+CONFIG_REISERFS_FS=m
+CONFIG_ISO9660_FS=m
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_NTFS_FS=m
+CONFIG_NTFS_RW=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+CONFIG_CIFS=m
+CONFIG_CIFS_STATS=y
+CONFIG_CODA_FS=m
+CONFIG_NLS_DEFAULT="cp855"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_855=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_UTF8=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_INFO=y
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
index 96100db..f0c8f01 100644
--- a/arch/arm/mach-pxa/Kconfig
+++ b/arch/arm/mach-pxa/Kconfig
@@ -4,6 +4,20 @@ menu "Intel PXA2xx/PXA3xx Implementations"
comment "Intel/Marvell Dev Platforms (sorted by hardware release time)"
+config MACH_PXA27X_DT
+ bool "Support PXA27x platforms from device tree"
+ select USE_OF
+ help
+ Include support for Marvell PXA27x based platforms using
+ the device tree.
+
+ While MACH_PXA27X_DT when enabled should boot any PXA27x
+ compatible machine, it still makes sense to select specific
+ machines. Those options will select required features and
+ provide per-machine errata workarounds.
+
+ If unsure, say Y.
+
config MACH_PXA3XX_DT
bool "Support PXA3xx platforms from device tree"
select CPU_PXA300
@@ -273,6 +287,23 @@ config MACH_VPAC270
comment "End-user Products (sorted by vendor name)"
+config MACH_LP8X4X
+ bool "ICP DAS LP-8X4X (device tree)"
+ depends on MACH_PXA27X_DT
+ select IWMMXT
+ select PXA27x
+ help
+ Say Y here if you intend to run this kernel on an ICP DAS
+ LP-8x4x programmable automation controller.
+
+ LP-8x4x is ARM-based and built around PXA270 SoC. The device
+ has 128 MiB SDRAM, 48 or 96 MiB NOR flash, VGA port with
+ 800x600 resolution, MMC card slot, 2 Ethernet ports, 1 USB
+ port, 5 serial ports (1 on them is wired internally to
+ expansion slots). The device has a range of digital and
+ analog expansion IO modules which can be installed in 1, 4 or
+ 8 slots depending on the model.
+
config MACH_H4700
bool "HP iPAQ hx4700"
select HAVE_PWM
diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile
index 648867a..adaa72a 100644
--- a/arch/arm/mach-pxa/Makefile
+++ b/arch/arm/mach-pxa/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_CPU_PXA930) += pxa930.o
# NOTE: keep the order of boards in accordance to their order in Kconfig
# Device Tree support
+obj-$(CONFIG_MACH_PXA27X_DT) += pxa27x-dt.o
obj-$(CONFIG_MACH_PXA3XX_DT) += pxa-dt.o
# Intel/Marvell Dev Platforms
diff --git a/arch/arm/mach-pxa/pxa27x-dt.c b/arch/arm/mach-pxa/pxa27x-dt.c
new file mode 100644
index 0000000..95c6ef4
--- /dev/null
+++ b/arch/arm/mach-pxa/pxa27x-dt.c
@@ -0,0 +1,97 @@
+/*
+ * linux/arch/arm/mach-pxa/pxa27x-dt.c
+ *
+ * Copyright (C) 2013 Sergei Ianovich
+ *
+ * based mostly on linux/arch/arm/mach-pxa/pxa-dt.c by Daniel Mack
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <asm/io.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <mach/irqs.h>
+#include <mach/pxa27x.h>
+
+#include "generic.h"
+
+#ifdef CONFIG_PXA27x
+extern void __init pxa27x_dt_init_irq(void);
+
+static const struct of_dev_auxdata pxa27x_auxdata_lookup[] __initconst = {
+ OF_DEV_AUXDATA("mrvl,pxa-uart", 0x40100000, "pxa2xx-uart.0", NULL),
+ OF_DEV_AUXDATA("mrvl,pxa-uart", 0x40200000, "pxa2xx-uart.1", NULL),
+ OF_DEV_AUXDATA("mrvl,pxa-uart", 0x40700000, "pxa2xx-uart.2", NULL),
+ OF_DEV_AUXDATA("mrvl,pxa-uart", 0x41600000, "pxa2xx-uart.3", NULL),
+ OF_DEV_AUXDATA("marvell,pxa-mmc", 0x41100000, "pxa2xx-mci.0", NULL),
+ OF_DEV_AUXDATA("intel,pxa27x-gpio", 0x40e00000, "pxa27x-gpio", NULL),
+ OF_DEV_AUXDATA("marvell,pxa-ohci", 0x4c000000, "pxa27x-ohci", NULL),
+ OF_DEV_AUXDATA("mrvl,pxa-i2c", 0x40301680, "pxa2xx-i2c.0", NULL),
+ {}
+};
+
+static void __init pxa27x_init_early(void)
+{
+ pxa27x_skip_init();
+}
+
+static void __init pxa27x_dt_init(void)
+{
+ of_platform_populate(NULL, of_default_bus_match_table,
+ pxa27x_auxdata_lookup, NULL);
+}
+
+static const char *pxa27x_dt_board_compat[] __initdata = {
+ "marvell,pxa27x",
+ NULL,
+};
+
+#ifdef CONFIG_MACH_LP8X4X
+static const char *lp8x4x_dt_board_compat[] __initdata = {
+ "marvell,lp8x4x",
+ NULL,
+};
+
+static void lp8x4x_restart(enum reboot_mode mode, const char *cmd)
+{
+ /* Switch off fast-bus and turbo mode */
+ asm volatile("mcr p14, 0, %0, c6, c0, 0" : :
+ "r"(2));
+ /* SDRAM hangs on watchdog reset on Marvell PXA270 (erratum 71) */
+ pxa_restart(REBOOT_SOFT, cmd);
+}
+#endif
+#endif
+
+#ifdef CONFIG_PXA27x
+DT_MACHINE_START(PXA27X_DT, "Marvell PXA27x (Device Tree Support)")
+ .map_io = pxa27x_map_io,
+ .init_irq = pxa27x_dt_init_irq,
+ .handle_irq = pxa27x_handle_irq,
+ .init_time = pxa_timer_init,
+ .restart = pxa_restart,
+ .init_early = pxa27x_init_early,
+ .init_machine = pxa27x_dt_init,
+ .dt_compat = pxa27x_dt_board_compat,
+MACHINE_END
+
+#ifdef CONFIG_MACH_LP8X4X
+DT_MACHINE_START(LP8X4X_DT, "ICP DAS LP-8X4X (Device Tree Support)")
+ .map_io = pxa27x_map_io,
+ .init_irq = pxa27x_dt_init_irq,
+ .handle_irq = pxa27x_handle_irq,
+ .init_time = pxa_timer_init,
+ .restart = lp8x4x_restart,
+ .init_early = pxa27x_init_early,
+ .init_machine = pxa27x_dt_init,
+ .dt_compat = lp8x4x_dt_board_compat,
+MACHINE_END
+#endif
+#endif
--
1.8.4.3
^ permalink raw reply related [flat|nested] 148+ messages in thread
* Re: [PATCH 5/9] ARM: dts: provide DMA config to pxamci
2013-12-08 22:53 ` [PATCH 5/9] ARM: dts: provide DMA config to pxamci Sergei Ianovich
@ 2013-12-09 1:33 ` Arnd Bergmann
2013-12-09 9:04 ` Daniel Mack
0 siblings, 1 reply; 148+ messages in thread
From: Arnd Bergmann @ 2013-12-09 1:33 UTC (permalink / raw)
To: Sergei Ianovich
Cc: linux-kernel, linux-arm-kernel, Daniel Mack, Rob Herring,
Pawel Moll, Mark Rutland, Stephen Warren, Ian Campbell,
Rob Landley, Russell King, Chris Ball, Ulf Hansson, Jaehoon Chung,
Seungwon Jeon, open list:OPEN FIRMWARE AND...,
open list:DOCUMENTATION
On Sunday 08 December 2013, Sergei Ianovich wrote:
> Non-dts implementation supply required DMA channel numbers as
> IORESOURCE_DMA. However, there is was no way to get them from
> device tree.
I just wrote a lengthy reply to this email to explain in what ways
you got it wrong, but then I saw that Daniel has already done all
the work in the right way in August, so nevermind that.
It hasn't made it upstream yet, but see http://list-archives.org/2013/08/07/linux-mtd-lists-infradead-org/patch-00-20-arm-pxa-move-core-and-drivers-to-dmaengine/f/3444199144
for how it's done. Maybe Daniel can comment on the status of his
patches.
Arnd
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH 9/9] ARM: pxa27x: device tree support ICP DAS LP-8x4x
2013-12-08 22:53 ` [PATCH 9/9] ARM: pxa27x: device tree support ICP DAS LP-8x4x Sergei Ianovich
@ 2013-12-09 1:47 ` Arnd Bergmann
2013-12-09 15:16 ` Sergei Ianovich
0 siblings, 1 reply; 148+ messages in thread
From: Arnd Bergmann @ 2013-12-09 1:47 UTC (permalink / raw)
To: Sergei Ianovich
Cc: linux-kernel, linux-arm-kernel, Daniel Mack, Olof Johansson,
Linus Walleij, Rob Herring, Pawel Moll, Mark Rutland,
Stephen Warren, Ian Campbell, Russell King, Eric Miao,
Haojian Zhuang, open list:OPEN FIRMWARE AND...
On Sunday 08 December 2013, Sergei Ianovich wrote:
> +
> +#ifdef CONFIG_PXA27x
> +extern void __init pxa27x_dt_init_irq(void);
This is not the right place to put an 'extern' declaration, it should go into
a header file if it's really needed. Ideally you would not need it at all
and just add an IRQCHIP_DECLARE() line into the driver to automatically
probe it.
> +static const struct of_dev_auxdata pxa27x_auxdata_lookup[] __initconst = {
> + OF_DEV_AUXDATA("mrvl,pxa-uart", 0x40100000, "pxa2xx-uart.0", NULL),
> + OF_DEV_AUXDATA("mrvl,pxa-uart", 0x40200000, "pxa2xx-uart.1", NULL),
> + OF_DEV_AUXDATA("mrvl,pxa-uart", 0x40700000, "pxa2xx-uart.2", NULL),
> + OF_DEV_AUXDATA("mrvl,pxa-uart", 0x41600000, "pxa2xx-uart.3", NULL),
> + OF_DEV_AUXDATA("marvell,pxa-mmc", 0x41100000, "pxa2xx-mci.0", NULL),
> + OF_DEV_AUXDATA("intel,pxa27x-gpio", 0x40e00000, "pxa27x-gpio", NULL),
> + OF_DEV_AUXDATA("marvell,pxa-ohci", 0x4c000000, "pxa27x-ohci", NULL),
> + OF_DEV_AUXDATA("mrvl,pxa-i2c", 0x40301680, "pxa2xx-i2c.0", NULL),
> + {}
> +};
I guess these are needed only for clock management purposes at the moment?
> +static void __init pxa27x_init_early(void)
> +{
> + pxa27x_skip_init();
> +}
I would prefer not to have an init_early function at all, and instead
check "if (of_have_populated_dt())" in pxa27x_init, or to split
that function into two.
> +static const char *pxa27x_dt_board_compat[] __initdata = {
> + "marvell,pxa27x",
> + NULL,
> +};
> +
> +#ifdef CONFIG_MACH_LP8X4X
> +static const char *lp8x4x_dt_board_compat[] __initdata = {
> + "marvell,lp8x4x",
> + NULL,
> +};
Note that you should not have wildcards in any "compatible" strings.
Just list all the combinations here (pxa270, pxa271, pxa272, and whatever
you need for lp8x4x).
> +static void lp8x4x_restart(enum reboot_mode mode, const char *cmd)
> +{
> + /* Switch off fast-bus and turbo mode */
> + asm volatile("mcr p14, 0, %0, c6, c0, 0" : :
> + "r"(2));
> + /* SDRAM hangs on watchdog reset on Marvell PXA270 (erratum 71) */
> + pxa_restart(REBOOT_SOFT, cmd);
> +}
> +#endif
> +#endif
Since the only difference here is the restart logic, I would prefer here to
have only a single DT_MACHINE_START() and do
static void pxa27x_restart(enum reboot_mode mode, const char *cmd)
{
/* Switch off fast-bus and turbo mode */
if (of_machine_is_compatible("marvell,lp8x4x"))
asm volatile("mcr p14, 0, %0, c6, c0, 0" : : "r"(2));
/* SDRAM hangs on watchdog reset on Marvell PXA270 (erratum 71) */
if (of_machine_is_compatible("marvell,pxa270"))
pxa_restart(REBOOT_SOFT, cmd);
}
Arnd
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH 5/9] ARM: dts: provide DMA config to pxamci
2013-12-09 1:33 ` Arnd Bergmann
@ 2013-12-09 9:04 ` Daniel Mack
2013-12-09 9:34 ` Sergei Ianovich
2013-12-11 8:19 ` Robert Jarzmik
0 siblings, 2 replies; 148+ messages in thread
From: Daniel Mack @ 2013-12-09 9:04 UTC (permalink / raw)
To: Arnd Bergmann, Sergei Ianovich
Cc: Mark Rutland, open list:OPEN FIRMWARE AND..., Ulf Hansson,
Russell King, Pawel Moll, Stephen Warren, Seungwon Jeon,
Ian Campbell, DOCUMENTATION, linux-kernel, Rob Herring,
Jaehoon Chung, Rob Landley, Chris Ball, Robert Jarzmik,
linux-arm-kernel
On 12/09/2013 02:33 AM, Arnd Bergmann wrote:
> On Sunday 08 December 2013, Sergei Ianovich wrote:
>> Non-dts implementation supply required DMA channel numbers as
>> IORESOURCE_DMA. However, there is was no way to get them from
>> device tree.
>
> I just wrote a lengthy reply to this email to explain in what ways
> you got it wrong, but then I saw that Daniel has already done all
> the work in the right way in August, so nevermind that.
>
> It hasn't made it upstream yet, but see http://list-archives.org/2013/08/07/linux-mtd-lists-infradead-org/patch-00-20-arm-pxa-move-core-and-drivers-to-dmaengine/f/3444199144
> for how it's done. Maybe Daniel can comment on the status of his
> patches.
I recently rebased all my patches on top of 3.13-rc3, and will resend in
couple of days.
The real problem here is that by reworking the DMA related PXA bits, all
drivers have to be changed at once, and a gradual transition seems
impossible. For that, I was asking for help in areas where I don't have
any hardware to test my patches on, but unfortunately, nobody got back
to me yet.
In particular, the pxa camera driver is something Robert (cc) wanted to
have a look at. Robert, any updates on this?
Anyway, I'll have to clean up some details and will resend my patches
very soon.
Thanks,
Daniel
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH 5/9] ARM: dts: provide DMA config to pxamci
2013-12-09 9:04 ` Daniel Mack
@ 2013-12-09 9:34 ` Sergei Ianovich
2013-12-09 9:53 ` Sergei Ianovich
2013-12-09 10:21 ` Daniel Mack
2013-12-11 8:19 ` Robert Jarzmik
1 sibling, 2 replies; 148+ messages in thread
From: Sergei Ianovich @ 2013-12-09 9:34 UTC (permalink / raw)
To: Daniel Mack
Cc: Arnd Bergmann, linux-kernel, linux-arm-kernel, Rob Herring,
Pawel Moll, Mark Rutland, Stephen Warren, Ian Campbell,
Rob Landley, Russell King, Chris Ball, Ulf Hansson, Jaehoon Chung,
Seungwon Jeon, open list:OPEN FIRMWARE AND..., DOCUMENTATION,
Robert Jarzmik
On Mon, 2013-12-09 at 10:04 +0100, Daniel Mack wrote:
> On 12/09/2013 02:33 AM, Arnd Bergmann wrote:
> > On Sunday 08 December 2013, Sergei Ianovich wrote:
> >> Non-dts implementation supply required DMA channel numbers as
> >> IORESOURCE_DMA. However, there is was no way to get them from
> >> device tree.
> >
> > I just wrote a lengthy reply to this email to explain in what ways
> > you got it wrong, but then I saw that Daniel has already done all
> > the work in the right way in August, so nevermind that.
> >
> > It hasn't made it upstream yet, but see http://list-archives.org/2013/08/07/linux-mtd-lists-infradead-org/patch-00-20-arm-pxa-move-core-and-drivers-to-dmaengine/f/3444199144
> > for how it's done. Maybe Daniel can comment on the status of his
> > patches.
>
> I recently rebased all my patches on top of 3.13-rc3, and will resend in
> couple of days.
>
> The real problem here is that by reworking the DMA related PXA bits, all
> drivers have to be changed at once, and a gradual transition seems
> impossible. For that, I was asking for help in areas where I don't have
> any hardware to test my patches on, but unfortunately, nobody got back
> to me yet.
Nice to have Daniel in this conversation. Your patch series is a big and
important work. However, I am not sure I will ever land as is exactly
for this reason.
DMA is a per-physical-device concept, not per-platform. Only the DMA
controller is per-platform. This means we need to rewrite all platform
drivers at once. This is roughly equivalent to adding a new platform
support in one patch, which is not going to work.
In patch 08/20 in the series above, you change 10% lines of the pxa mmc
driver. If we don't count boilerplate lines, this will amount to over
50%. In other word, the output is a new driver.
My proposal in to actually add new drivers for each platform device with
DMA and mark new ones EXPERIMENTAL. When they receive adequate testing
we remove the tag and mark the old one OBSOLETE. When we have a new
driver for every device presently supported, we will drop the whole old
series.
This should be very close to a gradual transition.
While we are in transition, I propose that we allow 'hackish' support
for device tree in the existing drivers. Platform devices are declared
in dtsi files, so when we move to a new driver we just change the
compatible string there. Actual devices with their one dts file won't
need any change. They will need a dtb recompile, though. This way we can
begin a migration to device tree in pxa immediately.
The patch series does just that.
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH 5/9] ARM: dts: provide DMA config to pxamci
2013-12-09 9:34 ` Sergei Ianovich
@ 2013-12-09 9:53 ` Sergei Ianovich
2013-12-09 10:21 ` Daniel Mack
1 sibling, 0 replies; 148+ messages in thread
From: Sergei Ianovich @ 2013-12-09 9:53 UTC (permalink / raw)
To: Daniel Mack
Cc: Arnd Bergmann, linux-kernel, linux-arm-kernel, Rob Herring,
Pawel Moll, Mark Rutland, Stephen Warren, Ian Campbell,
Rob Landley, Russell King, Chris Ball, Ulf Hansson, Jaehoon Chung,
Seungwon Jeon, open list:OPEN FIRMWARE AND..., DOCUMENTATION,
Robert Jarzmik
On Mon, 2013-12-09 at 13:34 +0400, Sergei Ianovich wrote:
> On Mon, 2013-12-09 at 10:04 +0100, Daniel Mack wrote:
> > On 12/09/2013 02:33 AM, Arnd Bergmann wrote:
> > > On Sunday 08 December 2013, Sergei Ianovich wrote:
> > >> Non-dts implementation supply required DMA channel numbers as
> > >> IORESOURCE_DMA. However, there is was no way to get them from
> > >> device tree.
> > >
> > > I just wrote a lengthy reply to this email to explain in what ways
> > > you got it wrong, but then I saw that Daniel has already done all
> > > the work in the right way in August, so nevermind that.
> > >
> > > It hasn't made it upstream yet, but see http://list-archives.org/2013/08/07/linux-mtd-lists-infradead-org/patch-00-20-arm-pxa-move-core-and-drivers-to-dmaengine/f/3444199144
> > > for how it's done. Maybe Daniel can comment on the status of his
> > > patches.
> >
> > I recently rebased all my patches on top of 3.13-rc3, and will resend in
> > couple of days.
> >
> > The real problem here is that by reworking the DMA related PXA bits, all
> > drivers have to be changed at once, and a gradual transition seems
> > impossible. For that, I was asking for help in areas where I don't have
> > any hardware to test my patches on, but unfortunately, nobody got back
> > to me yet.
>
> Nice to have Daniel in this conversation. Your patch series is a big and
> important work. However, I am not sure I will ever land as is exactly
> for this reason.
s/I will/it will/
> DMA is a per-physical-device concept, not per-platform. Only the DMA
> controller is per-platform. This means we need to rewrite all platform
> drivers at once. This is roughly equivalent to adding a new platform
> support in one patch, which is not going to work.
>
> In patch 08/20 in the series above, you change 10% lines of the pxa mmc
> driver. If we don't count boilerplate lines, this will amount to over
> 50%. In other word, the output is a new driver.
s/other word/other words/
> My proposal in to actually add new drivers for each platform device with
> DMA and mark new ones EXPERIMENTAL. When they receive adequate testing
> we remove the tag and mark the old one OBSOLETE. When we have a new
> driver for every device presently supported, we will drop the whole old
> series.
s/proposal in/proposal is/
> This should be very close to a gradual transition.
>
> While we are in transition, I propose that we allow 'hackish' support
> for device tree in the existing drivers. Platform devices are declared
> in dtsi files, so when we move to a new driver we just change the
> compatible string there. Actual devices with their one dts file won't
> need any change. They will need a dtb recompile, though. This way we can
> begin a migration to device tree in pxa immediately.
s/their one/their own/
> The patch series does just that.
Sorry for noise.
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH 5/9] ARM: dts: provide DMA config to pxamci
2013-12-09 9:34 ` Sergei Ianovich
2013-12-09 9:53 ` Sergei Ianovich
@ 2013-12-09 10:21 ` Daniel Mack
[not found] ` <52A59991.1060305-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2013-12-09 13:16 ` Sergei Ianovich
1 sibling, 2 replies; 148+ messages in thread
From: Daniel Mack @ 2013-12-09 10:21 UTC (permalink / raw)
To: Sergei Ianovich
Cc: Arnd Bergmann, linux-kernel, linux-arm-kernel, Rob Herring,
Pawel Moll, Mark Rutland, Stephen Warren, Ian Campbell,
Rob Landley, Russell King, Chris Ball, Ulf Hansson, Jaehoon Chung,
Seungwon Jeon, open list:OPEN FIRMWARE AND..., DOCUMENTATION,
Robert Jarzmik
On 12/09/2013 10:34 AM, Sergei Ianovich wrote:
> On Mon, 2013-12-09 at 10:04 +0100, Daniel Mack wrote:
>> On 12/09/2013 02:33 AM, Arnd Bergmann wrote:
>>> On Sunday 08 December 2013, Sergei Ianovich wrote:
>>>> Non-dts implementation supply required DMA channel numbers as
>>>> IORESOURCE_DMA. However, there is was no way to get them from
>>>> device tree.
>>>
>>> I just wrote a lengthy reply to this email to explain in what ways
>>> you got it wrong, but then I saw that Daniel has already done all
>>> the work in the right way in August, so nevermind that.
>>>
>>> It hasn't made it upstream yet, but see http://list-archives.org/2013/08/07/linux-mtd-lists-infradead-org/patch-00-20-arm-pxa-move-core-and-drivers-to-dmaengine/f/3444199144
>>> for how it's done. Maybe Daniel can comment on the status of his
>>> patches.
>>
>> I recently rebased all my patches on top of 3.13-rc3, and will resend in
>> couple of days.
>>
>> The real problem here is that by reworking the DMA related PXA bits, all
>> drivers have to be changed at once, and a gradual transition seems
>> impossible. For that, I was asking for help in areas where I don't have
>> any hardware to test my patches on, but unfortunately, nobody got back
>> to me yet.
>
> Nice to have Daniel in this conversation. Your patch series is a big and
> important work. However, I am not sure I will ever land as is exactly
> for this reason.
Well, I wouldn't be so certain about that statement. As I wrote in the
cover letter, most of the work is actually done, and I successfully
tested the new DMA support with a some of the drivers I ported. Others
were ported blindly, and in case of no reaction, I'd dare to merge them
and wait for people to report back in case of trouble.
The only real problem is the PXA camera driver, which does tricky things
like hot re-queuing of DMA descriptors. That one needs fixing before the
series can land.
> My proposal in to actually add new drivers for each platform device with
> DMA and mark new ones EXPERIMENTAL.
That would cause tree-wide cross-dependencies between drivers, because
the two DMA controllers can't be used at the same time, and the PXA
specific API will be unavailable when the mmp-dma driver is selected. My
patch series (and the DMA controller framework for that matter) aims for
the opposite - the unification of APIs and drivers.
> When they receive adequate testing
> we remove the tag and mark the old one OBSOLETE. When we have a new
> driver for every device presently supported, we will drop the whole old
> series.
Well, given the feedback I got for the series so far, I fear we'll be
off to maintain two drivers for each peripheral for a very long time.
I'd rather propose cracking the last nut that's left, and then get the
thing merged.
Arnd, Haojian? Any opinion here?
Daniel
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH 5/9] ARM: dts: provide DMA config to pxamci
[not found] ` <52A59991.1060305-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2013-12-09 12:09 ` Sergei Ianovich
2013-12-10 0:25 ` Arnd Bergmann
0 siblings, 1 reply; 148+ messages in thread
From: Sergei Ianovich @ 2013-12-09 12:09 UTC (permalink / raw)
To: Daniel Mack
Cc: Arnd Bergmann, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Rob Herring,
Pawel Moll, Mark Rutland, Stephen Warren, Ian Campbell,
Rob Landley, Russell King, Chris Ball, Ulf Hansson, Jaehoon Chung,
Seungwon Jeon, open list:OPEN FIRMWARE AND..., DOCUMENTATION,
Robert Jarzmik
On Mon, 2013-12-09 at 11:21 +0100, Daniel Mack wrote:
> On 12/09/2013 10:34 AM, Sergei Ianovich wrote:
> > Nice to have Daniel in this conversation. Your patch series is a big and
> > important work. However, I am not sure I will ever land as is exactly
> > for this reason.
>
> Well, I wouldn't be so certain about that statement. As I wrote in the
> cover letter, most of the work is actually done, and I successfully
> tested the new DMA support with a some of the drivers I ported. Others
> were ported blindly, and in case of no reaction, I'd dare to merge them
> and wait for people to report back in case of trouble.
If breaking things is an option, I am definitely wrong. I assumed the
opposite.
> > My proposal in to actually add new drivers for each platform device with
> > DMA and mark new ones EXPERIMENTAL.
>
> That would cause tree-wide cross-dependencies between drivers, because
> the two DMA controllers can't be used at the same time, and the PXA
> specific API will be unavailable when the mmp-dma driver is selected. My
> patch series (and the DMA controller framework for that matter) aims for
> the opposite - the unification of APIs and drivers.
Not sure I got this point. My proposal is to keep the existing DMA
intact until we are ready to remove it. I understand this approach
requires considerably more work inside DMA to allow both driver to
coexist than wholesale replacement. I still think big change is risky.
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH 5/9] ARM: dts: provide DMA config to pxamci
2013-12-09 10:21 ` Daniel Mack
[not found] ` <52A59991.1060305-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2013-12-09 13:16 ` Sergei Ianovich
1 sibling, 0 replies; 148+ messages in thread
From: Sergei Ianovich @ 2013-12-09 13:16 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Daniel Mack, linux-kernel, linux-arm-kernel, Rob Herring,
Pawel Moll, Mark Rutland, Stephen Warren, Ian Campbell,
Rob Landley, Russell King, Chris Ball, Ulf Hansson, Jaehoon Chung,
Seungwon Jeon, open list:OPEN FIRMWARE AND..., DOCUMENTATION,
Robert Jarzmik
On Mon, 2013-12-09 at 11:21 +0100, Daniel Mack wrote:
> On 12/09/2013 10:34 AM, Sergei Ianovich wrote:
> > On Mon, 2013-12-09 at 10:04 +0100, Daniel Mack wrote:
> >> On 12/09/2013 02:33 AM, Arnd Bergmann wrote:
> >>> It hasn't made it upstream yet, but see http://list-archives.org/2013/08/07/linux-mtd-lists-infradead-org/patch-00-20-arm-pxa-move-core-and-drivers-to-dmaengine/f/3444199144
> >>> for how it's done. Maybe Daniel can comment on the status of his
> >>> patches.
> >>
...
> The only real problem is the PXA camera driver, which does tricky things
> like hot re-queuing of DMA descriptors. That one needs fixing before the
> series can land.
My impression is that his series is hard to land. I've expressed my
concerns about big changes in a separate mail.
PXA device tree support issue is practically orthogonal. As of August
2013, Daniel's dma series doesn't add any dt support. After new DMA is
working, we will need to add dt support in the same drivers.
Basically we have three options:
A. Wait for Daniel DMA, than for PXA clock, than do dt support
pros:
* correct order
cons:
* need to wait, possibly a long time
* dt boot not possible, while we wait
B. Provide 'hackish' support to dt, than correct hacks when DMA is
merged.
pros:
* parallel development
* healthier kernel code (current PXA usb driver won't compile with dt
enabled)
cons:
* wrong concept (like my patch 5/9) until DMA is working
* need to recompile dtb files when kernel changes
C. Use 'fake' DMA provider dt binding to emulate existing DMA until new
DMA is merged, than
pros:
* parallel development
* healthier kernel code
* correct device trees from the beginning
cons:
* more work
* still need to recompile dtbs when clock support is merged
Any ideas?
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH 9/9] ARM: pxa27x: device tree support ICP DAS LP-8x4x
2013-12-09 1:47 ` Arnd Bergmann
@ 2013-12-09 15:16 ` Sergei Ianovich
2013-12-09 15:55 ` Sergei Ianovich
2013-12-09 16:25 ` Arnd Bergmann
0 siblings, 2 replies; 148+ messages in thread
From: Sergei Ianovich @ 2013-12-09 15:16 UTC (permalink / raw)
To: Arnd Bergmann
Cc: linux-kernel, linux-arm-kernel, Daniel Mack, Olof Johansson,
Linus Walleij, Rob Herring, Pawel Moll, Mark Rutland,
Stephen Warren, Ian Campbell, Russell King, Eric Miao,
Haojian Zhuang, open list:OPEN FIRMWARE AND...
On Mon, 2013-12-09 at 02:47 +0100, Arnd Bergmann wrote:
> On Sunday 08 December 2013, Sergei Ianovich wrote:
> > +
> > +#ifdef CONFIG_PXA27x
> > +extern void __init pxa27x_dt_init_irq(void);
> This is not the right place to put an 'extern' declaration, it should go into
> a header file if it's really needed. Ideally you would not need it at all
> and just add an IRQCHIP_DECLARE() line into the driver to automatically
> probe it.
I thought I moved it to the header in patch 6/9. I'll just drop the
line.
IRQCHIP_DECLARE isn't used on pxa_internal_irq_chip in
arch/arm/mach-pxa/irq.c, probably for a reason.
> > +static const struct of_dev_auxdata pxa27x_auxdata_lookup[] __initconst = {
> > + OF_DEV_AUXDATA("mrvl,pxa-uart", 0x40100000, "pxa2xx-uart.0", NULL),
> > + OF_DEV_AUXDATA("mrvl,pxa-uart", 0x40200000, "pxa2xx-uart.1", NULL),
> > + OF_DEV_AUXDATA("mrvl,pxa-uart", 0x40700000, "pxa2xx-uart.2", NULL),
> > + OF_DEV_AUXDATA("mrvl,pxa-uart", 0x41600000, "pxa2xx-uart.3", NULL),
> > + OF_DEV_AUXDATA("marvell,pxa-mmc", 0x41100000, "pxa2xx-mci.0", NULL),
> > + OF_DEV_AUXDATA("intel,pxa27x-gpio", 0x40e00000, "pxa27x-gpio", NULL),
> > + OF_DEV_AUXDATA("marvell,pxa-ohci", 0x4c000000, "pxa27x-ohci", NULL),
> > + OF_DEV_AUXDATA("mrvl,pxa-i2c", 0x40301680, "pxa2xx-i2c.0", NULL),
> > + {}
> > +};
>
> I guess these are needed only for clock management purposes at the moment?
Absolutely.
> > +static void __init pxa27x_init_early(void)
> > +{
> > + pxa27x_skip_init();
> > +}
>
> I would prefer not to have an init_early function at all, and instead
> check "if (of_have_populated_dt())" in pxa27x_init, or to split
> that function into two.
Device tree is populated in init_machine. However, pxa27x_init is
executed before via postcore_initcall. The only chance to run before is
to use init_early. What's wrong with this function?
> > +static const char *pxa27x_dt_board_compat[] __initdata = {
> > + "marvell,pxa27x",
> > + NULL,
> > +};
> > +
> > +#ifdef CONFIG_MACH_LP8X4X
> > +static const char *lp8x4x_dt_board_compat[] __initdata = {
> > + "marvell,lp8x4x",
> > + NULL,
> > +};
>
> Note that you should not have wildcards in any "compatible" strings.
> Just list all the combinations here (pxa270, pxa271, pxa272, and whatever
> you need for lp8x4x).
Will do.
> > +static void lp8x4x_restart(enum reboot_mode mode, const char *cmd)
> > +{
> > + /* Switch off fast-bus and turbo mode */
> > + asm volatile("mcr p14, 0, %0, c6, c0, 0" : :
> > + "r"(2));
> > + /* SDRAM hangs on watchdog reset on Marvell PXA270 (erratum 71) */
> > + pxa_restart(REBOOT_SOFT, cmd);
> > +}
> > +#endif
> > +#endif
>
> Since the only difference here is the restart logic, I would prefer here to
> have only a single DT_MACHINE_START() and do
>
> static void pxa27x_restart(enum reboot_mode mode, const char *cmd)
> {
> /* Switch off fast-bus and turbo mode */
> if (of_machine_is_compatible("marvell,lp8x4x"))
> asm volatile("mcr p14, 0, %0, c6, c0, 0" : : "r"(2));
>
> /* SDRAM hangs on watchdog reset on Marvell PXA270 (erratum 71) */
> if (of_machine_is_compatible("marvell,pxa270"))
> pxa_restart(REBOOT_SOFT, cmd);
> }
Nice tip, thanks. I've spent 30 minutes to find something like that.
If the device has fast SDRAM, which can reset itself in up to 8ms, the
device is not affected by E71. So both checks are per-device.
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH 9/9] ARM: pxa27x: device tree support ICP DAS LP-8x4x
2013-12-09 15:16 ` Sergei Ianovich
@ 2013-12-09 15:55 ` Sergei Ianovich
[not found] ` <1386604530.7152.184.camel-7ZSkjCHmnyFmet/iJI8ZvA@public.gmane.org>
2013-12-09 16:25 ` Arnd Bergmann
1 sibling, 1 reply; 148+ messages in thread
From: Sergei Ianovich @ 2013-12-09 15:55 UTC (permalink / raw)
To: Arnd Bergmann
Cc: linux-kernel, linux-arm-kernel, Daniel Mack, Olof Johansson,
Linus Walleij, Rob Herring, Pawel Moll, Mark Rutland,
Stephen Warren, Ian Campbell, Russell King, Eric Miao,
Haojian Zhuang, open list:OPEN FIRMWARE AND...,
Dmitry Eremin-Solenikov
On Mon, 2013-12-09 at 19:16 +0400, Sergei Ianovich wrote:
> On Mon, 2013-12-09 at 02:47 +0100, Arnd Bergmann wrote:
> > On Sunday 08 December 2013, Sergei Ianovich wrote:
> > > +
> > > +#ifdef CONFIG_PXA27x
> > > +extern void __init pxa27x_dt_init_irq(void);
>
> > > +static void __init pxa27x_init_early(void)
> > > +{
> > > + pxa27x_skip_init();
> > > +}
> >
> > I would prefer not to have an init_early function at all, and instead
> > check "if (of_have_populated_dt())" in pxa27x_init, or to split
> > that function into two.
Although this is counterintuitive, it works. Since of_populate_dt() is
not required for of_have_populated_dt() to return true, should we rename
of_have_populated_dt() to of_have_dt()?
> Device tree is populated in init_machine. However, pxa27x_init is
> executed before via postcore_initcall. The only chance to run before is
> to use init_early. What's wrong with this function?
I was wrong.
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH 9/9] ARM: pxa27x: device tree support ICP DAS LP-8x4x
2013-12-09 15:16 ` Sergei Ianovich
2013-12-09 15:55 ` Sergei Ianovich
@ 2013-12-09 16:25 ` Arnd Bergmann
1 sibling, 0 replies; 148+ messages in thread
From: Arnd Bergmann @ 2013-12-09 16:25 UTC (permalink / raw)
To: Sergei Ianovich
Cc: linux-kernel, linux-arm-kernel, Daniel Mack, Olof Johansson,
Linus Walleij, Rob Herring, Pawel Moll, Mark Rutland,
Stephen Warren, Ian Campbell, Russell King, Eric Miao,
Haojian Zhuang, open list:OPEN FIRMWARE AND...
On Monday 09 December 2013, Sergei Ianovich wrote:
> On Mon, 2013-12-09 at 02:47 +0100, Arnd Bergmann wrote:
> > On Sunday 08 December 2013, Sergei Ianovich wrote:
> > > +
> > > +#ifdef CONFIG_PXA27x
> > > +extern void __init pxa27x_dt_init_irq(void);
>
> > This is not the right place to put an 'extern' declaration, it should go into
> > a header file if it's really needed. Ideally you would not need it at all
> > and just add an IRQCHIP_DECLARE() line into the driver to automatically
> > probe it.
>
> I thought I moved it to the header in patch 6/9. I'll just drop the
> line.
Ok.
> IRQCHIP_DECLARE isn't used on pxa_internal_irq_chip in
> arch/arm/mach-pxa/irq.c, probably for a reason.
Yes, you can only use it from drivers in drivers/irqchip/.
> > > +static void __init pxa27x_init_early(void)
> > > +{
> > > + pxa27x_skip_init();
> > > +}
> >
> > I would prefer not to have an init_early function at all, and instead
> > check "if (of_have_populated_dt())" in pxa27x_init, or to split
> > that function into two.
>
> Device tree is populated in init_machine. However, pxa27x_init is
> executed before via postcore_initcall.
The device tree is populated in unflatten_device_tree(), which gets
called before init_early.
> The only chance to run before is
> to use init_early. What's wrong with this function?
I generally dislike adding any platform specific hooks to "early"
functions, i.e. stuff that runs before init_machine, and I'm pretty
sure it's not necessary here.
> > static void pxa27x_restart(enum reboot_mode mode, const char *cmd)
> > {
> > /* Switch off fast-bus and turbo mode */
> > if (of_machine_is_compatible("marvell,lp8x4x"))
> > asm volatile("mcr p14, 0, %0, c6, c0, 0" : : "r"(2));
> >
> > /* SDRAM hangs on watchdog reset on Marvell PXA270 (erratum 71) */
> > if (of_machine_is_compatible("marvell,pxa270"))
> > pxa_restart(REBOOT_SOFT, cmd);
> > }
>
> Nice tip, thanks. I've spent 30 minutes to find something like that.
>
> If the device has fast SDRAM, which can reset itself in up to 8ms, the
> device is not affected by E71. So both checks are per-device.
Ok.
Arnd
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH 9/9] ARM: pxa27x: device tree support ICP DAS LP-8x4x
[not found] ` <1386604530.7152.184.camel-7ZSkjCHmnyFmet/iJI8ZvA@public.gmane.org>
@ 2013-12-09 16:39 ` Arnd Bergmann
0 siblings, 0 replies; 148+ messages in thread
From: Arnd Bergmann @ 2013-12-09 16:39 UTC (permalink / raw)
To: Sergei Ianovich
Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Daniel Mack,
Olof Johansson, Linus Walleij, Rob Herring, Pawel Moll,
Mark Rutland, Stephen Warren, Ian Campbell, Russell King,
Eric Miao, Haojian Zhuang, open list:OPEN FIRMWARE AND...,
Dmitry Eremin-Solenikov
On Monday 09 December 2013, Sergei Ianovich wrote:
> anovich wrote:
> > On Mon, 2013-12-09 at 02:47 +0100, Arnd Bergmann wrote:
> > > On Sunday 08 December 2013, Sergei Ianovich wrote:
> > > > +
> > > > +#ifdef CONFIG_PXA27x
> > > > +extern void __init pxa27x_dt_init_irq(void);
> >
> > > > +static void __init pxa27x_init_early(void)
> > > > +{
> > > > + pxa27x_skip_init();
> > > > +}
> > >
> > > I would prefer not to have an init_early function at all, and instead
> > > check "if (of_have_populated_dt())" in pxa27x_init, or to split
> > > that function into two.
>
> Although this is counterintuitive, it works. Since of_populate_dt() is
> not required for of_have_populated_dt() to return true, should we rename
> of_have_populated_dt() to of_have_dt()?
I don't think it's worth the change. The explanation for the current
terminoligy is that of_unflatten() populates the DT device_node structures
in the kernel from the FTD blob, while of_platform_populate populates the
platform_device infrastructure from the device nodes.
Arnd
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH 5/9] ARM: dts: provide DMA config to pxamci
2013-12-09 12:09 ` Sergei Ianovich
@ 2013-12-10 0:25 ` Arnd Bergmann
2013-12-10 4:25 ` Sergei Ianovich
0 siblings, 1 reply; 148+ messages in thread
From: Arnd Bergmann @ 2013-12-10 0:25 UTC (permalink / raw)
To: Sergei Ianovich
Cc: Daniel Mack, linux-kernel, linux-arm-kernel, Rob Herring,
Pawel Moll, Mark Rutland, Stephen Warren, Ian Campbell,
Rob Landley, Russell King, Chris Ball, Ulf Hansson, Jaehoon Chung,
Seungwon Jeon, open list:OPEN FIRMWARE AND..., DOCUMENTATION,
Robert Jarzmik
On Monday 09 December 2013, Sergei Ianovich wrote:
> On Mon, 2013-12-09 at 11:21 +0100, Daniel Mack wrote:
> > On 12/09/2013 10:34 AM, Sergei Ianovich wrote:
> > > Nice to have Daniel in this conversation. Your patch series is a big and
> > > important work. However, I am not sure I will ever land as is exactly
> > > for this reason.
> >
> > Well, I wouldn't be so certain about that statement. As I wrote in the
> > cover letter, most of the work is actually done, and I successfully
> > tested the new DMA support with a some of the drivers I ported. Others
> > were ported blindly, and in case of no reaction, I'd dare to merge them
> > and wait for people to report back in case of trouble.
>
> If breaking things is an option, I am definitely wrong. I assumed the
> opposite.
We never intentionally break things that people are using, but there are
cases where doing blind changes is the best way forward. We should
always try to find people to test patches on real hardware if possible,
which is only possible if there are people around that have the hardware
and that are going to run new kernels on them.
In case of PXA dmaengine support, I think the benefits of applying the
series far outweigh the breakage potential. A lot of the drivers are
shared with MMP, which is going to be DT-only eventually and will require
the new dmaengine code. Some PXA drivers may be shared with SA1100,
which has also converted to dmaengine although there are no plans to
ever support DT on sa1100.
> > > My proposal in to actually add new drivers for each platform device with
> > > DMA and mark new ones EXPERIMENTAL.
> >
> > That would cause tree-wide cross-dependencies between drivers, because
> > the two DMA controllers can't be used at the same time, and the PXA
> > specific API will be unavailable when the mmp-dma driver is selected. My
> > patch series (and the DMA controller framework for that matter) aims for
> > the opposite - the unification of APIs and drivers.
>
> Not sure I got this point. My proposal is to keep the existing DMA
> intact until we are ready to remove it. I understand this approach
> requires considerably more work inside DMA to allow both driver to
> coexist than wholesale replacement. I still think big change is risky.
We certainly need to be extra careful if we want to move things over
at once and cannot test all the drivers. I'd be happier if it could
be done gradually by having some drivers use the new interface and
other drivers use the old one, but I don't see how that can be done
here.
Arnd
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH 5/9] ARM: dts: provide DMA config to pxamci
2013-12-10 0:25 ` Arnd Bergmann
@ 2013-12-10 4:25 ` Sergei Ianovich
0 siblings, 0 replies; 148+ messages in thread
From: Sergei Ianovich @ 2013-12-10 4:25 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Daniel Mack, linux-kernel, linux-arm-kernel, Rob Herring,
Pawel Moll, Mark Rutland, Stephen Warren, Ian Campbell,
Rob Landley, Russell King, Chris Ball, Ulf Hansson, Jaehoon Chung,
Seungwon Jeon, open list:OPEN FIRMWARE AND..., DOCUMENTATION,
Robert Jarzmik
On Tue, 2013-12-10 at 01:25 +0100, Arnd Bergmann wrote:
> We never intentionally break things that people are using, but there are
> cases where doing blind changes is the best way forward. We should
> always try to find people to test patches on real hardware if possible,
> which is only possible if there are people around that have the hardware
> and that are going to run new kernels on them.
>
> In case of PXA dmaengine support, I think the benefits of applying the
> series far outweigh the breakage potential. A lot of the drivers are
> shared with MMP, which is going to be DT-only eventually and will require
> the new dmaengine code. Some PXA drivers may be shared with SA1100,
> which has also converted to dmaengine although there are no plans to
> ever support DT on sa1100.
>
> We certainly need to be extra careful if we want to move things over
> at once and cannot test all the drivers. I'd be happier if it could
> be done gradually by having some drivers use the new interface and
> other drivers use the old one, but I don't see how that can be done
> here.
Thanks for detailed explanation. I see there is strong support for the
big change. Lets hope it'll be smooth. I'll strest test Daniel's changes
and report the results.
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH 5/9] ARM: dts: provide DMA config to pxamci
2013-12-09 9:04 ` Daniel Mack
2013-12-09 9:34 ` Sergei Ianovich
@ 2013-12-11 8:19 ` Robert Jarzmik
1 sibling, 0 replies; 148+ messages in thread
From: Robert Jarzmik @ 2013-12-11 8:19 UTC (permalink / raw)
To: Daniel Mack
Cc: Arnd Bergmann, Sergei Ianovich, linux-kernel, linux-arm-kernel,
Rob Herring, Pawel Moll, Mark Rutland, Stephen Warren,
Ian Campbell, Rob Landley, Russell King, Chris Ball, Ulf Hansson,
Jaehoon Chung, Seungwon Jeon, devicetree, linux-doc
Daniel Mack <zonque@gmail.com> writes:
> In particular, the pxa camera driver is something Robert (cc) wanted to
> have a look at. Robert, any updates on this?
Oh yes, sorry, it's been monthes, I've been very busy.
This is my last status :
- my current patch is in (1)
- this patch doesn't work yet
- if my memory serves me well, I have reached the conclusion that dmaengine
pxa-mpp driver doesn't allow pxa_camera to work properly in the current
state. This is a long time since I checked, so take the following with
caution until I have checked again.
This assertion is based on this required behaviour :
- video buffers are queued, let's say 5
=> 5 dma are "prepared"
- video buffers are submitted
=> 5 dma xfers are submitted
- the userspace polls for each finished frame (ie. dma xfer termination), and
on the third one, resubmits the 2 finished frames
=> scatter-gathers should mot be recomputed, just xfer should be
resubmitted, with cache sync operations and first/last descriptors chaining
- the pxa_camera driver needs a way to know if a dma channel is still running,
for missed chaining transfers, because if a channel stopped, the dma xfers
should not be submitted until IRQ "begin of frame" is encoutered. I didn't
find a way for that.
Now, I will retry this weekend, but if I remember correctly the issues I had
were :
- a transfer cannot be resubmitted, it has to be freed and recreated
- if it is resubmitted, the completion is not signaled by the tasklet
Cheers.
--
Robert
(1)
commit 4741ba6 (pxa_camera_dmaengine, backup/pxa_camera_dmaengine)
Author: Robert Jarzmik <robert.jarzmik@free.fr>
Date: Sat Aug 24 21:13:38 2013 +0200
WIP: pxa_camera dmaengine conversion
Only slightly tested, without much success.
Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
diff --git a/drivers/media/platform/soc_camera/pxa_camera.c b/drivers/media/platform/soc_camera/pxa_camera.c
index d4df305..903ea03 100644
--- a/drivers/media/platform/soc_camera/pxa_camera.c
+++ b/drivers/media/platform/soc_camera/pxa_camera.c
@@ -9,7 +9,7 @@
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
-
+#define DEBUG 1
#include <linux/init.h>
#include <linux/module.h>
#include <linux/io.h>
@@ -28,6 +28,9 @@
#include <linux/clk.h>
#include <linux/sched.h>
#include <linux/slab.h>
+#include <linux/dmaengine.h>
+#include <linux/dma-mapping.h>
+#include <linux/dma/mmp-pdma.h>
#include <media/v4l2-common.h>
#include <media/v4l2-dev.h>
@@ -37,7 +40,6 @@
#include <linux/videodev2.h>
-#include <mach/dma.h>
#include <linux/platform_data/camera-pxa.h>
#define PXA_CAM_VERSION "0.0.6"
@@ -174,21 +176,13 @@ enum pxa_camera_active_dma {
DMA_V = 0x4,
};
-/* descriptor needed for the PXA DMA engine */
-struct pxa_cam_dma {
- dma_addr_t sg_dma;
- struct pxa_dma_desc *sg_cpu;
- size_t sg_size;
- int sglen;
-};
-
/* buffer for one video frame */
struct pxa_buffer {
/* common v4l buffer stuff -- must be first */
struct videobuf_buffer vb;
enum v4l2_mbus_pixelcode code;
/* our descriptor lists for Y, U and V channels */
- struct pxa_cam_dma dmas[3];
+ struct dma_async_tx_descriptor *descs[3];
int inwork;
enum pxa_camera_active_dma active_dma;
};
@@ -206,7 +200,7 @@ struct pxa_camera_dev {
void __iomem *base;
int channels;
- unsigned int dma_chans[3];
+ struct dma_chan *dma_chans[3];
struct pxacamera_platform_data *pdata;
struct resource *res;
@@ -221,7 +215,6 @@ struct pxa_camera_dev {
spinlock_t lock;
struct pxa_buffer *active;
- struct pxa_dma_desc *sg_tail[3];
u32 save_cicr[5];
};
@@ -273,40 +266,70 @@ static void free_buffer(struct videobuf_queue *vq, struct pxa_buffer *buf)
videobuf_waiton(vq, &buf->vb, 0, 0);
videobuf_dma_unmap(vq->dev, dma);
videobuf_dma_free(dma);
-
- for (i = 0; i < ARRAY_SIZE(buf->dmas); i++) {
- if (buf->dmas[i].sg_cpu)
- dma_free_coherent(ici->v4l2_dev.dev,
- buf->dmas[i].sg_size,
- buf->dmas[i].sg_cpu,
- buf->dmas[i].sg_dma);
- buf->dmas[i].sg_cpu = NULL;
- }
+ /* FIXME: free buf->descs[0..2] */
buf->vb.state = VIDEOBUF_NEEDS_INIT;
+
+ dev_dbg(icd->parent, "%s end (vb=0x%p) 0x%08lx %d\n", __func__,
+ &buf->vb, buf->vb.baddr, buf->vb.bsize);
}
-static int calculate_dma_sglen(struct scatterlist *sglist, int sglen,
- int sg_first_ofs, int size)
+static struct scatterlist *videobuf_sg_splice(struct scatterlist *sglist,
+ int sglen, int offset, int size,
+ int *new_sg_len)
{
- int i, offset, dma_len, xfer_len;
- struct scatterlist *sg;
+ struct scatterlist *sg0, *sg;
+ int nfirst, i, dma_len, xfer_len;
- offset = sg_first_ofs;
- for_each_sg(sglist, sg, sglen, i) {
+ sg0 = kmalloc(sizeof(struct scatterlist) * sglen, GFP_KERNEL);
+ if (!sg0)
+ return NULL;
+ for_each_sg(sglist, sg, sglen, nfirst) {
dma_len = sg_dma_len(sg);
-
+ if (offset < dma_len)
+ break;
/* PXA27x Developer's Manual 27.4.4.1: round up to 8 bytes */
- xfer_len = roundup(min(dma_len - offset, size), 8);
-
- size = max(0, size - xfer_len);
- offset = 0;
- if (size == 0)
+ xfer_len = roundup(min(dma_len - offset, offset), 8);
+ offset = max(0, offset - xfer_len);
+ }
+ BUG_ON(sg_is_last(&sglist[nfirst]));
+ for_each_sg(&sglist[nfirst], sg, sglen - nfirst, i) {
+ sg0[i] = sglist[nfirst];
+ sg0[i].offset = offset;
+ sg_dma_len(&sg0[i]) -= offset;
+ if (size <= sg_dma_len(sg))
break;
+ offset = 0;
+ size -= roundup(sg_dma_len(sg), 8);
+ }
+ if (size) {
+ sg_dma_len(&sg0[i]) = size;
+ *new_sg_len = i + 1;
+ } else {
+ *new_sg_len = i;
}
- BUG_ON(size != 0);
- return i + 1;
+ return sg0;
+}
+static void pxa_camera_dma_irq(struct pxa_camera_dev *pcdev,
+ enum pxa_camera_active_dma act_dma);
+
+static void pxa_camera_dma_irq_y(void *data)
+{
+ struct pxa_camera_dev *pcdev = data;
+ pxa_camera_dma_irq(pcdev, DMA_Y);
+}
+
+static void pxa_camera_dma_irq_u(void *data)
+{
+ struct pxa_camera_dev *pcdev = data;
+ pxa_camera_dma_irq(pcdev, DMA_U);
+}
+
+static void pxa_camera_dma_irq_v(void *data)
+{
+ struct pxa_camera_dev *pcdev = data;
+ pxa_camera_dma_irq(pcdev, DMA_V);
}
/**
@@ -317,91 +340,68 @@ static int calculate_dma_sglen(struct scatterlist *sglist, int sglen,
* @channel: dma channel (0 => 'Y', 1 => 'U', 2 => 'V')
* @cibr: camera Receive Buffer Register
* @size: bytes to transfer
- * @sg_first: first element of sg_list
- * @sg_first_ofs: offset in first element of sg_list
+ * @offset: offset in videobuffer of the first byte to transfer
*
* Prepares the pxa dma descriptors to transfer one camera channel.
- * Beware sg_first and sg_first_ofs are both input and output parameters.
*
- * Returns 0 or -ENOMEM if no coherent memory is available
+ * Returns 0 if success or -ENOMEM if no memory is available
*/
static int pxa_init_dma_channel(struct pxa_camera_dev *pcdev,
struct pxa_buffer *buf,
struct videobuf_dmabuf *dma, int channel,
- int cibr, int size,
- struct scatterlist **sg_first, int *sg_first_ofs)
+ int cibr, int size, int offset)
{
- struct pxa_cam_dma *pxa_dma = &buf->dmas[channel];
- struct device *dev = pcdev->soc_host.v4l2_dev.dev;
- struct scatterlist *sg;
- int i, offset, sglen;
- int dma_len = 0, xfer_len = 0;
+ struct dma_chan *dma_chan = pcdev->dma_chans[channel];
+ struct scatterlist *sg = NULL;
+ int ret, sglen;
+ struct dma_slave_config config;
+ struct dma_async_tx_descriptor *tx;
- if (pxa_dma->sg_cpu)
- dma_free_coherent(dev, pxa_dma->sg_size,
- pxa_dma->sg_cpu, pxa_dma->sg_dma);
+ dmaengine_terminate_all(dma_chan);
- sglen = calculate_dma_sglen(*sg_first, dma->sglen,
- *sg_first_ofs, size);
-
- pxa_dma->sg_size = (sglen + 1) * sizeof(struct pxa_dma_desc);
- pxa_dma->sg_cpu = dma_alloc_coherent(dev, pxa_dma->sg_size,
- &pxa_dma->sg_dma, GFP_KERNEL);
- if (!pxa_dma->sg_cpu)
+ sg = videobuf_sg_splice(dma->sglist, dma->sglen, offset, size, &sglen);
+ if (!sg)
return -ENOMEM;
- pxa_dma->sglen = sglen;
- offset = *sg_first_ofs;
-
- dev_dbg(dev, "DMA: sg_first=%p, sglen=%d, ofs=%d, dma.desc=%x\n",
- *sg_first, sglen, *sg_first_ofs, pxa_dma->sg_dma);
-
+ memset(&config, 0, sizeof(config));
+ config.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; /* FIXME? */
+ config.src_maxburst = 8;
+ config.src_addr = pcdev->res->start + cibr;
+ config.direction = DMA_DEV_TO_MEM;
- for_each_sg(*sg_first, sg, sglen, i) {
- dma_len = sg_dma_len(sg);
-
- /* PXA27x Developer's Manual 27.4.4.1: round up to 8 bytes */
- xfer_len = roundup(min(dma_len - offset, size), 8);
-
- size = max(0, size - xfer_len);
-
- pxa_dma->sg_cpu[i].dsadr = pcdev->res->start + cibr;
- pxa_dma->sg_cpu[i].dtadr = sg_dma_address(sg) + offset;
- pxa_dma->sg_cpu[i].dcmd =
- DCMD_FLOWSRC | DCMD_BURST8 | DCMD_INCTRGADDR | xfer_len;
-#ifdef DEBUG
- if (!i)
- pxa_dma->sg_cpu[i].dcmd |= DCMD_STARTIRQEN;
-#endif
- pxa_dma->sg_cpu[i].ddadr =
- pxa_dma->sg_dma + (i + 1) * sizeof(struct pxa_dma_desc);
-
- dev_vdbg(dev, "DMA: desc.%08x->@phys=0x%08x, len=%d\n",
- pxa_dma->sg_dma + i * sizeof(struct pxa_dma_desc),
- sg_dma_address(sg) + offset, xfer_len);
- offset = 0;
-
- if (size == 0)
- break;
+ ret = dmaengine_slave_config(dma_chan, &config);
+ if (ret < 0) {
+ printk("%s(): dma slave config failed: %d\n", __func__, ret);
+ return ret;
}
- pxa_dma->sg_cpu[sglen].ddadr = DDADR_STOP;
- pxa_dma->sg_cpu[sglen].dcmd = DCMD_FLOWSRC | DCMD_BURST8 | DCMD_ENDIRQEN;
+ tx = dmaengine_prep_slave_sg(dma_chan, sg, sglen,
+ config.direction,
+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+ if (!tx) {
+ printk("%s(): prep_slave_sg() failed\n", __func__);
+ goto fail;
+ }
- /*
- * Handle 1 special case :
- * - in 3 planes (YUV422P format), we might finish with xfer_len equal
- * to dma_len (end on PAGE boundary). In this case, the sg element
- * for next plane should be the next after the last used to store the
- * last scatter gather RAM page
- */
- if (xfer_len >= dma_len) {
- *sg_first_ofs = xfer_len - dma_len;
- *sg_first = sg_next(sg);
- } else {
- *sg_first_ofs = xfer_len;
- *sg_first = sg;
+ tx->callback_param = pcdev;
+ switch (channel) {
+ case 0:
+ tx->callback = pxa_camera_dma_irq_y;
+ break;
+ case 1:
+ tx->callback = pxa_camera_dma_irq_u;
+ break;
+ case 2:
+ tx->callback = pxa_camera_dma_irq_v;
+ break;
}
+fail:
+ kfree(sg);
+ buf->descs[channel] = tx;
+
+ dev_dbg(pcdev->soc_host.v4l2_dev.dev,
+ "%s (vb=0x%p) dma_tx=%p\n",
+ __func__, &buf->vb, tx);
return 0;
}
@@ -470,11 +470,10 @@ static int pxa_videobuf_prepare(struct videobuf_queue *vq,
goto out;
}
- if (vb->state == VIDEOBUF_NEEDS_INIT) {
+ //if (vb->state == VIDEOBUF_NEEDS_INIT) {
+ if (vb->state != VIDEOBUF_PREPARED) {
int size = vb->size;
- int next_ofs = 0;
struct videobuf_dmabuf *dma = videobuf_to_dma(vb);
- struct scatterlist *sg;
ret = videobuf_iolock(vq, vb, NULL);
if (ret)
@@ -487,11 +486,8 @@ static int pxa_videobuf_prepare(struct videobuf_queue *vq,
size_y = size;
}
- sg = dma->sglist;
-
/* init DMA for Y channel */
- ret = pxa_init_dma_channel(pcdev, buf, dma, 0, CIBR0, size_y,
- &sg, &next_ofs);
+ ret = pxa_init_dma_channel(pcdev, buf, dma, 0, CIBR0, size_y, 0);
if (ret) {
dev_err(dev, "DMA initialization for Y/RGB failed\n");
goto fail;
@@ -500,7 +496,7 @@ static int pxa_videobuf_prepare(struct videobuf_queue *vq,
/* init DMA for U channel */
if (size_u)
ret = pxa_init_dma_channel(pcdev, buf, dma, 1, CIBR1,
- size_u, &sg, &next_ofs);
+ size_u, size_y);
if (ret) {
dev_err(dev, "DMA initialization for U failed\n");
goto fail_u;
@@ -509,7 +505,7 @@ static int pxa_videobuf_prepare(struct videobuf_queue *vq,
/* init DMA for V channel */
if (size_v)
ret = pxa_init_dma_channel(pcdev, buf, dma, 2, CIBR2,
- size_v, &sg, &next_ofs);
+ size_v, size_y + size_u);
if (ret) {
dev_err(dev, "DMA initialization for V failed\n");
goto fail_v;
@@ -524,11 +520,7 @@ static int pxa_videobuf_prepare(struct videobuf_queue *vq,
return 0;
fail_v:
- dma_free_coherent(dev, buf->dmas[1].sg_size,
- buf->dmas[1].sg_cpu, buf->dmas[1].sg_dma);
fail_u:
- dma_free_coherent(dev, buf->dmas[0].sg_size,
- buf->dmas[0].sg_cpu, buf->dmas[0].sg_dma);
fail:
free_buffer(vq, buf);
out:
@@ -552,10 +544,8 @@ static void pxa_dma_start_channels(struct pxa_camera_dev *pcdev)
for (i = 0; i < pcdev->channels; i++) {
dev_dbg(pcdev->soc_host.v4l2_dev.dev,
- "%s (channel=%d) ddadr=%08x\n", __func__,
- i, active->dmas[i].sg_dma);
- DDADR(pcdev->dma_chans[i]) = active->dmas[i].sg_dma;
- DCSR(pcdev->dma_chans[i]) = DCSR_RUN;
+ "%s (channel=%d)\n", __func__, i);
+ dma_async_issue_pending(pcdev->dma_chans[i]);
}
}
@@ -566,7 +556,7 @@ static void pxa_dma_stop_channels(struct pxa_camera_dev *pcdev)
for (i = 0; i < pcdev->channels; i++) {
dev_dbg(pcdev->soc_host.v4l2_dev.dev,
"%s (channel=%d)\n", __func__, i);
- DCSR(pcdev->dma_chans[i]) = 0;
+ dmaengine_terminate_all(pcdev->dma_chans[i]);
}
}
@@ -574,18 +564,12 @@ static void pxa_dma_add_tail_buf(struct pxa_camera_dev *pcdev,
struct pxa_buffer *buf)
{
int i;
- struct pxa_dma_desc *buf_last_desc;
for (i = 0; i < pcdev->channels; i++) {
- buf_last_desc = buf->dmas[i].sg_cpu + buf->dmas[i].sglen;
- buf_last_desc->ddadr = DDADR_STOP;
-
- if (pcdev->sg_tail[i])
- /* Link the new buffer to the old tail */
- pcdev->sg_tail[i]->ddadr = buf->dmas[i].sg_dma;
-
- /* Update the channel tail */
- pcdev->sg_tail[i] = buf_last_desc;
+ dmaengine_submit(buf->descs[i]);
+ dev_dbg(pcdev->soc_host.v4l2_dev.dev,
+ "%s (channel=%d) : submit vb=%p cookie=%d\n",
+ __func__, i, buf, buf->descs[i]->cookie);
}
}
@@ -676,8 +660,6 @@ static void pxa_camera_wakeup(struct pxa_camera_dev *pcdev,
struct videobuf_buffer *vb,
struct pxa_buffer *buf)
{
- int i;
-
/* _init is used to debug races, see comment in pxa_camera_reqbufs() */
list_del_init(&vb->queue);
vb->state = VIDEOBUF_DONE;
@@ -689,8 +671,6 @@ static void pxa_camera_wakeup(struct pxa_camera_dev *pcdev,
if (list_empty(&pcdev->capture)) {
pxa_camera_stop_capture(pcdev);
- for (i = 0; i < pcdev->channels; i++)
- pcdev->sg_tail[i] = NULL;
return;
}
@@ -716,48 +696,33 @@ static void pxa_camera_wakeup(struct pxa_camera_dev *pcdev,
*/
static void pxa_camera_check_link_miss(struct pxa_camera_dev *pcdev)
{
- int i, is_dma_stopped = 1;
+ /* FIXME: ask dmaengine if channel is still running */
+ int is_dma_stopped = 1;
- for (i = 0; i < pcdev->channels; i++)
- if (DDADR(pcdev->dma_chans[i]) != DDADR_STOP)
- is_dma_stopped = 0;
dev_dbg(pcdev->soc_host.v4l2_dev.dev,
- "%s : top queued buffer=%p, dma_stopped=%d\n",
- __func__, pcdev->active, is_dma_stopped);
+ "%s : top queued buffer=%p\n", __func__, pcdev->active);
+ if (pcdev->active)
+ pxa_dma_start_channels(pcdev);
if (pcdev->active && is_dma_stopped)
pxa_camera_start_capture(pcdev);
}
-static void pxa_camera_dma_irq(int channel, struct pxa_camera_dev *pcdev,
+static void pxa_camera_dma_irq(struct pxa_camera_dev *pcdev,
enum pxa_camera_active_dma act_dma)
{
struct device *dev = pcdev->soc_host.v4l2_dev.dev;
struct pxa_buffer *buf;
unsigned long flags;
- u32 status, camera_status, overrun;
+ u32 camera_status, overrun;
struct videobuf_buffer *vb;
spin_lock_irqsave(&pcdev->lock, flags);
- status = DCSR(channel);
- DCSR(channel) = status;
-
camera_status = __raw_readl(pcdev->base + CISR);
overrun = CISR_IFO_0;
if (pcdev->channels == 3)
overrun |= CISR_IFO_1 | CISR_IFO_2;
- if (status & DCSR_BUSERR) {
- dev_err(dev, "DMA Bus Error IRQ!\n");
- goto out;
- }
-
- if (!(status & (DCSR_ENDINTR | DCSR_STARTINTR))) {
- dev_err(dev, "Unknown DMA IRQ source, status: 0x%08x\n",
- status);
- goto out;
- }
-
/*
* pcdev->active should not be NULL in DMA irq handler.
*
@@ -777,52 +742,28 @@ static void pxa_camera_dma_irq(int channel, struct pxa_camera_dev *pcdev,
buf = container_of(vb, struct pxa_buffer, vb);
WARN_ON(buf->inwork || list_empty(&vb->queue));
- dev_dbg(dev, "%s channel=%d %s%s(vb=0x%p) dma.desc=%x\n",
- __func__, channel, status & DCSR_STARTINTR ? "SOF " : "",
- status & DCSR_ENDINTR ? "EOF " : "", vb, DDADR(channel));
-
- if (status & DCSR_ENDINTR) {
- /*
- * It's normal if the last frame creates an overrun, as there
- * are no more DMA descriptors to fetch from QCI fifos
- */
- if (camera_status & overrun &&
- !list_is_last(pcdev->capture.next, &pcdev->capture)) {
- dev_dbg(dev, "FIFO overrun! CISR: %x\n",
- camera_status);
- pxa_camera_stop_capture(pcdev);
- pxa_camera_start_capture(pcdev);
- goto out;
- }
- buf->active_dma &= ~act_dma;
- if (!buf->active_dma) {
- pxa_camera_wakeup(pcdev, vb, buf);
- pxa_camera_check_link_miss(pcdev);
- }
+ /*
+ * It's normal if the last frame creates an overrun, as there
+ * are no more DMA descriptors to fetch from QCI fifos
+ */
+ if (camera_status & overrun &&
+ !list_is_last(pcdev->capture.next, &pcdev->capture)) {
+ dev_dbg(dev, "FIFO overrun! CISR: %x\n",
+ camera_status);
+ pxa_camera_stop_capture(pcdev);
+ pxa_camera_start_capture(pcdev);
+ goto out;
+ }
+ buf->active_dma &= ~act_dma;
+ if (!buf->active_dma) {
+ pxa_camera_wakeup(pcdev, vb, buf);
+ pxa_camera_check_link_miss(pcdev);
}
out:
spin_unlock_irqrestore(&pcdev->lock, flags);
}
-static void pxa_camera_dma_irq_y(int channel, void *data)
-{
- struct pxa_camera_dev *pcdev = data;
- pxa_camera_dma_irq(channel, pcdev, DMA_Y);
-}
-
-static void pxa_camera_dma_irq_u(int channel, void *data)
-{
- struct pxa_camera_dev *pcdev = data;
- pxa_camera_dma_irq(channel, pcdev, DMA_U);
-}
-
-static void pxa_camera_dma_irq_v(int channel, void *data)
-{
- struct pxa_camera_dev *pcdev = data;
- pxa_camera_dma_irq(channel, pcdev, DMA_V);
-}
-
static struct videobuf_queue_ops pxa_videobuf_ops = {
.buf_setup = pxa_videobuf_setup,
.buf_prepare = pxa_videobuf_prepare,
@@ -992,10 +933,7 @@ static void pxa_camera_clock_stop(struct soc_camera_host *ici)
__raw_writel(0x3ff, pcdev->base + CICR0);
/* Stop DMA engine */
- DCSR(pcdev->dma_chans[0]) = 0;
- DCSR(pcdev->dma_chans[1]) = 0;
- DCSR(pcdev->dma_chans[2]) = 0;
-
+ pxa_dma_stop_channels(pcdev);
pxa_camera_deactivate(pcdev);
}
@@ -1608,10 +1546,6 @@ static int pxa_camera_resume(struct device *dev)
struct pxa_camera_dev *pcdev = ici->priv;
int i = 0, ret = 0;
- DRCMR(68) = pcdev->dma_chans[0] | DRCMR_MAPVLD;
- DRCMR(69) = pcdev->dma_chans[1] | DRCMR_MAPVLD;
- DRCMR(70) = pcdev->dma_chans[2] | DRCMR_MAPVLD;
-
__raw_writel(pcdev->save_cicr[i++] & ~CICR0_ENB, pcdev->base + CICR0);
__raw_writel(pcdev->save_cicr[i++], pcdev->base + CICR1);
__raw_writel(pcdev->save_cicr[i++], pcdev->base + CICR2);
@@ -1655,6 +1589,8 @@ static int pxa_camera_probe(struct platform_device *pdev)
struct pxa_camera_dev *pcdev;
struct resource *res;
void __iomem *base;
+ dma_cap_mask_t mask;
+ unsigned int drcmr;
int irq;
int err = 0;
@@ -1717,36 +1653,35 @@ static int pxa_camera_probe(struct platform_device *pdev)
pcdev->base = base;
/* request dma */
- err = pxa_request_dma("CI_Y", DMA_PRIO_HIGH,
- pxa_camera_dma_irq_y, pcdev);
- if (err < 0) {
+ dma_cap_zero(mask);
+ dma_cap_set(DMA_SLAVE, mask);
+
+ drcmr = 68;
+ pcdev->dma_chans[0] =
+ dma_request_slave_channel_compat(mask, mmp_pdma_filter_fn,
+ &drcmr, &pdev->dev, "CI_Y");
+ if (!pcdev->dma_chans[0]) {
dev_err(&pdev->dev, "Can't request DMA for Y\n");
- return err;
+ return -ENODEV;
}
- pcdev->dma_chans[0] = err;
- dev_dbg(&pdev->dev, "got DMA channel %d\n", pcdev->dma_chans[0]);
- err = pxa_request_dma("CI_U", DMA_PRIO_HIGH,
- pxa_camera_dma_irq_u, pcdev);
- if (err < 0) {
- dev_err(&pdev->dev, "Can't request DMA for U\n");
+ drcmr = 69;
+ pcdev->dma_chans[1] =
+ dma_request_slave_channel_compat(mask, mmp_pdma_filter_fn,
+ &drcmr, &pdev->dev, "CI_U");
+ if (!pcdev->dma_chans[1]) {
+ dev_err(&pdev->dev, "Can't request DMA for Y\n");
goto exit_free_dma_y;
}
- pcdev->dma_chans[1] = err;
- dev_dbg(&pdev->dev, "got DMA channel (U) %d\n", pcdev->dma_chans[1]);
- err = pxa_request_dma("CI_V", DMA_PRIO_HIGH,
- pxa_camera_dma_irq_v, pcdev);
- if (err < 0) {
+ drcmr = 70;
+ pcdev->dma_chans[2] =
+ dma_request_slave_channel_compat(mask, mmp_pdma_filter_fn,
+ &drcmr, &pdev->dev, "CI_V");
+ if (!pcdev->dma_chans[2]) {
dev_err(&pdev->dev, "Can't request DMA for V\n");
goto exit_free_dma_u;
}
- pcdev->dma_chans[2] = err;
- dev_dbg(&pdev->dev, "got DMA channel (V) %d\n", pcdev->dma_chans[2]);
-
- DRCMR(68) = pcdev->dma_chans[0] | DRCMR_MAPVLD;
- DRCMR(69) = pcdev->dma_chans[1] | DRCMR_MAPVLD;
- DRCMR(70) = pcdev->dma_chans[2] | DRCMR_MAPVLD;
/* request irq */
err = devm_request_irq(&pdev->dev, pcdev->irq, pxa_camera_irq, 0,
@@ -1769,11 +1704,11 @@ static int pxa_camera_probe(struct platform_device *pdev)
return 0;
exit_free_dma:
- pxa_free_dma(pcdev->dma_chans[2]);
+ dma_release_channel(pcdev->dma_chans[2]);
exit_free_dma_u:
- pxa_free_dma(pcdev->dma_chans[1]);
+ dma_release_channel(pcdev->dma_chans[1]);
exit_free_dma_y:
- pxa_free_dma(pcdev->dma_chans[0]);
+ dma_release_channel(pcdev->dma_chans[0]);
return err;
}
@@ -1783,9 +1718,9 @@ static int pxa_camera_remove(struct platform_device *pdev)
struct pxa_camera_dev *pcdev = container_of(soc_host,
struct pxa_camera_dev, soc_host);
- pxa_free_dma(pcdev->dma_chans[0]);
- pxa_free_dma(pcdev->dma_chans[1]);
- pxa_free_dma(pcdev->dma_chans[2]);
+ dma_release_channel(pcdev->dma_chans[0]);
+ dma_release_channel(pcdev->dma_chans[1]);
+ dma_release_channel(pcdev->dma_chans[2]);
soc_camera_host_unregister(soc_host);
----------
^ permalink raw reply related [flat|nested] 148+ messages in thread
* [PATCH v2 01/16] ARM: dts: pxa2xx fix compatible strings
[not found] ` <1386901645-28895-1-git-send-email-ynvich@gmail.com>
@ 2013-12-13 2:27 ` Sergei Ianovich
2013-12-13 2:27 ` [PATCH v2 02/16] ARM: dts: fix pxa27x-gpio interrupts Sergei Ianovich
` (9 subsequent siblings)
10 siblings, 0 replies; 148+ messages in thread
From: Sergei Ianovich @ 2013-12-13 2:27 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel
Cc: Sergei Ianovich, Daniel Mack, Arnd Bergmann, Rob Herring,
Pawel Moll, Mark Rutland, Stephen Warren, Ian Campbell,
Russell King, open list:OPEN FIRMWARE AND...
Signed-off-by: Sergei Ianovich <ynvich@gmail.com>
CC: Daniel Mack <zonque@gmail.com>
CC: Arnd Bergmann <arnd@arndb.de>
---
v1..v2
* no changes
arch/arm/boot/dts/pxa2xx.dtsi | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/arch/arm/boot/dts/pxa2xx.dtsi b/arch/arm/boot/dts/pxa2xx.dtsi
index a5e90f0..3419f87 100644
--- a/arch/arm/boot/dts/pxa2xx.dtsi
+++ b/arch/arm/boot/dts/pxa2xx.dtsi
@@ -18,7 +18,6 @@
serial1 = &btuart;
serial2 = &stuart;
serial3 = &hwuart;
- i2c0 = &pwri2c;
i2c1 = &pxai2c1;
};
@@ -113,14 +112,14 @@
};
usb0: ohci@4c000000 {
- compatible = "mrvl,pxa-ohci";
+ compatible = "marvell,pxa-ohci";
reg = <0x4c000000 0x10000>;
interrupts = <3>;
status = "disabled";
};
mmc0: mmc@41100000 {
- compatible = "mrvl,pxa-mmc";
+ compatible = "marvell,pxa-mmc";
reg = <0x41100000 0x1000>;
interrupts = <23>;
status = "disabled";
--
1.8.4.3
^ permalink raw reply related [flat|nested] 148+ messages in thread
* [PATCH v2 02/16] ARM: dts: fix pxa27x-gpio interrupts
[not found] ` <1386901645-28895-1-git-send-email-ynvich@gmail.com>
2013-12-13 2:27 ` [PATCH v2 01/16] ARM: dts: pxa2xx fix compatible strings Sergei Ianovich
@ 2013-12-13 2:27 ` Sergei Ianovich
2013-12-13 2:27 ` [PATCH v2 03/16] ARM: dts: provide DMA config to pxamci Sergei Ianovich
` (8 subsequent siblings)
10 siblings, 0 replies; 148+ messages in thread
From: Sergei Ianovich @ 2013-12-13 2:27 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel
Cc: Sergei Ianovich, Daniel Mack, Arnd Bergmann, Rob Herring,
Pawel Moll, Mark Rutland, Stephen Warren, Ian Campbell,
Russell King, open list:OPEN FIRMWARE AND...
Signed-off-by: Sergei Ianovich <ynvich@gmail.com>
CC: Daniel Mack <zonque@gmail.com>
CC: Arnd Bergmann <arnd@arndb.de>
---
v1..v2
* no changes
arch/arm/boot/dts/pxa27x.dtsi | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/arch/arm/boot/dts/pxa27x.dtsi b/arch/arm/boot/dts/pxa27x.dtsi
index d7c5d72..44df554 100644
--- a/arch/arm/boot/dts/pxa27x.dtsi
+++ b/arch/arm/boot/dts/pxa27x.dtsi
@@ -10,5 +10,11 @@
marvell,intc-priority;
marvell,intc-nr-irqs = <34>;
};
+
+ gpio: gpio@40e00000 {
+ compatible = "intel,pxa27x-gpio";
+ interrupts = <8>, <9>, <10>;
+ interrupt-names = "gpio0", "gpio1", "gpio_mux";
+ };
};
};
--
1.8.4.3
^ permalink raw reply related [flat|nested] 148+ messages in thread
* [PATCH v2 03/16] ARM: dts: provide DMA config to pxamci
[not found] ` <1386901645-28895-1-git-send-email-ynvich@gmail.com>
2013-12-13 2:27 ` [PATCH v2 01/16] ARM: dts: pxa2xx fix compatible strings Sergei Ianovich
2013-12-13 2:27 ` [PATCH v2 02/16] ARM: dts: fix pxa27x-gpio interrupts Sergei Ianovich
@ 2013-12-13 2:27 ` Sergei Ianovich
2013-12-14 19:06 ` Arnd Bergmann
2013-12-13 2:27 ` [PATCH v2 06/16] ARM: pxa27x: device tree support ICP DAS LP-8x4x Sergei Ianovich
` (7 subsequent siblings)
10 siblings, 1 reply; 148+ messages in thread
From: Sergei Ianovich @ 2013-12-13 2:27 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel
Cc: Sergei Ianovich, Daniel Mack, Arnd Bergmann, Rob Herring,
Pawel Moll, Mark Rutland, Stephen Warren, Ian Campbell,
Rob Landley, Russell King, Chris Ball, Viresh Kumar, Shawn Guo,
Haojian Zhuang, open list:OPEN FIRMWARE AND...,
open list:DOCUMENTATION, linux-mmc
Non-dts implementation supply required DMA channel numbers as
IORESOURCE_DMA. However, there is was no way to get them from
device tree.
Signed-off-by: Sergei Ianovich <ynvich@gmail.com>
CC: Daniel Mack <zonque@gmail.com>
CC: Arnd Bergmann <arnd@arndb.de>
---
v1..v2
* add binding for next-gen dma controller
* use correct dma declararion
* number changed from 5 to 3
Documentation/devicetree/bindings/mmc/pxa-mmc.txt | 5 ++
arch/arm/boot/dts/pxa27x.dtsi | 14 ++++++
drivers/mmc/host/pxamci.c | 59 ++++++++++++++++++-----
3 files changed, 67 insertions(+), 11 deletions(-)
diff --git a/Documentation/devicetree/bindings/mmc/pxa-mmc.txt b/Documentation/devicetree/bindings/mmc/pxa-mmc.txt
index b7025de..9f54c69 100644
--- a/Documentation/devicetree/bindings/mmc/pxa-mmc.txt
+++ b/Documentation/devicetree/bindings/mmc/pxa-mmc.txt
@@ -5,6 +5,8 @@ Driver bindings for the PXA MCI (MMC/SDIO) interfaces
Required properties:
- compatible: Should be "marvell,pxa-mmc".
- vmmc-supply: A regulator for VMMC
+- dmas: Should be DMA specifiers for RX and TX
+- dma-names: Should be "rx" and "tx"
Optional properties:
- marvell,detect-delay-ms: sets the detection delay timeout in ms.
@@ -21,5 +23,8 @@ mmc0: mmc@41100000 {
interrupts = <23>;
cd-gpios = <&gpio 23 0>;
wp-gpios = <&gpio 24 0>;
+ dmas = <&dma 21
+ &dma 22>;
+ dma-names = "rx", "tx";
};
diff --git a/arch/arm/boot/dts/pxa27x.dtsi b/arch/arm/boot/dts/pxa27x.dtsi
index 44df554..c2a90c5 100644
--- a/arch/arm/boot/dts/pxa27x.dtsi
+++ b/arch/arm/boot/dts/pxa27x.dtsi
@@ -11,10 +11,24 @@
marvell,intc-nr-irqs = <34>;
};
+ dma: dma-controller@40000000 {
+ compatible = "marvell,pdma-1.0";
+ reg = <0x40000000 0x10000>;
+ interrupts = <25>;
+ #dma-cells = <1>;
+ dma-channels = <32>;
+ };
+
gpio: gpio@40e00000 {
compatible = "intel,pxa27x-gpio";
interrupts = <8>, <9>, <10>;
interrupt-names = "gpio0", "gpio1", "gpio_mux";
};
+
+ mmc@41100000 {
+ dmas = <&dma 21
+ &dma 22>;
+ dma-names = "rx", "tx";
+ };
};
};
diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c
index 32fe113..6b67764 100644
--- a/drivers/mmc/host/pxamci.c
+++ b/drivers/mmc/host/pxamci.c
@@ -613,11 +613,46 @@ static int pxamci_of_init(struct platform_device *pdev)
return 0;
}
+
+static int pxamci_of_init_dma(struct platform_device *pdev,
+ struct pxamci_host *host)
+{
+ struct device_node *np = pdev->dev.of_node;
+ u32 tmp;
+ int i;
+ int ret;
+
+ i = of_property_match_string(np, "dma-names", "rx");
+ if (i < 0)
+ return i;
+
+ ret = of_property_read_u32_index(np, "dmas", 2 * i + 1, &tmp);
+ if (ret < 0)
+ return ret;
+ host->dma_drcmrrx = tmp;
+
+ i = of_property_match_string(np, "dma-names", "tx");
+ if (i < 0)
+ return i;
+
+ ret = of_property_read_u32_index(np, "dmas", 2 * i + 1, &tmp);
+ if (ret < 0)
+ return ret;
+ host->dma_drcmrtx = tmp;
+
+ return 0;
+}
#else
static int pxamci_of_init(struct platform_device *pdev)
{
return 0;
}
+
+static int pxamci_of_init_dma(struct platform_device *pdev,
+ struct pxamci_host *host)
+{
+ return -ENODATA;
+}
#endif
static int pxamci_probe(struct platform_device *pdev)
@@ -741,19 +776,21 @@ static int pxamci_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, mmc);
- dmarx = platform_get_resource(pdev, IORESOURCE_DMA, 0);
- if (!dmarx) {
- ret = -ENXIO;
- goto out;
- }
- host->dma_drcmrrx = dmarx->start;
+ if (pxamci_of_init_dma(pdev, host) < 0) {
+ dmarx = platform_get_resource(pdev, IORESOURCE_DMA, 0);
+ if (!dmarx) {
+ ret = -ENXIO;
+ goto out;
+ }
+ host->dma_drcmrrx = dmarx->start;
- dmatx = platform_get_resource(pdev, IORESOURCE_DMA, 1);
- if (!dmatx) {
- ret = -ENXIO;
- goto out;
+ dmatx = platform_get_resource(pdev, IORESOURCE_DMA, 1);
+ if (!dmatx) {
+ ret = -ENXIO;
+ goto out;
+ }
+ host->dma_drcmrtx = dmatx->start;
}
- host->dma_drcmrtx = dmatx->start;
if (host->pdata) {
gpio_cd = host->pdata->gpio_card_detect;
--
1.8.4.3
^ permalink raw reply related [flat|nested] 148+ messages in thread
* [PATCH v2 06/16] ARM: pxa27x: device tree support ICP DAS LP-8x4x
[not found] ` <1386901645-28895-1-git-send-email-ynvich@gmail.com>
` (2 preceding siblings ...)
2013-12-13 2:27 ` [PATCH v2 03/16] ARM: dts: provide DMA config to pxamci Sergei Ianovich
@ 2013-12-13 2:27 ` Sergei Ianovich
2013-12-13 2:27 ` [PATCH v2 07/16] rtc: support DS1302 RTC on " Sergei Ianovich
` (6 subsequent siblings)
10 siblings, 0 replies; 148+ messages in thread
From: Sergei Ianovich @ 2013-12-13 2:27 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel
Cc: Sergei Ianovich, Daniel Mack, Arnd Bergmann, Linus Walleij,
Rob Herring, Pawel Moll, Mark Rutland, Stephen Warren,
Ian Campbell, Russell King, Eric Miao, Haojian Zhuang,
open list:OPEN FIRMWARE AND...
ICP DAS calls LP-8x4x 'programmable automation controller'. It is
an industrial computer based on PXA270 SoC. They ship it with a 2.6.19
kernel and proprietary kernel module and userspace library to access
its industrial IO.
This patch allows to boot the device with a modern kernel with device
tree. It adds support for:
* MMC card interface on PXA270
* USB 1.1 port on PXA270
* 2 NOR flash devices
* 2 onboard ethernet Davicom DM9000 devices
* 3 serial UART ports on PXA270
Support for these devices will be added in separate patches, since
they are not currently supported by the kernel:
* DS1302 RTC
* 512kiB SRAM
* FPGA irq chip
* 3 built-in and up to 32 pluggable 8250 serial UART ports
* industrial IO parallel bus
* digital and analog industrial IO modules for parallel bus
* serial interface for digital and analog industrial IO modules on
parallel bus
Not supported for now:
* VGA interface on PXA270 for lack of dts binding
Signed-off-by: Sergei Ianovich <ynvich@gmail.com>
CC: Daniel Mack <zonque@gmail.com>
CC: Arnd Bergmann <arnd@arndb.de>
CC: Linus Walleij <linus.walleij@linaro.org>
---
v1..v2
* drop left-over extern declaration
* use of_have_populated_dt() instead of a static variable
* drop wildcards in compatible
* drop machine-special machine description
* number changed from 9 to 6 (dropped patches)
arch/arm/boot/dts/Makefile | 1 +
arch/arm/boot/dts/pxa27x-lp8x4x.dts | 111 +++++++++++++++++++++++++
arch/arm/configs/lp8x4x_defconfig | 160 ++++++++++++++++++++++++++++++++++++
arch/arm/mach-pxa/Kconfig | 15 ++++
arch/arm/mach-pxa/Makefile | 1 +
arch/arm/mach-pxa/pxa27x-dt.c | 64 +++++++++++++++
6 files changed, 352 insertions(+)
create mode 100644 arch/arm/boot/dts/pxa27x-lp8x4x.dts
create mode 100644 arch/arm/configs/lp8x4x_defconfig
create mode 100644 arch/arm/mach-pxa/pxa27x-dt.c
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index d57c1a6..c4752ff 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -206,6 +206,7 @@ dtb-$(CONFIG_ARCH_OMAP2PLUS) += omap2420-h4.dtb \
dra7-evm.dtb
dtb-$(CONFIG_ARCH_ORION5X) += orion5x-lacie-ethernet-disk-mini-v2.dtb
dtb-$(CONFIG_ARCH_PRIMA2) += prima2-evb.dtb
+dtb-$(CONFIG_MACH_PXA27X_DT) += pxa27x-lp8x4x.dtb
dtb-$(CONFIG_ARCH_U8500) += ste-snowball.dtb \
ste-hrefprev60-stuib.dtb \
ste-hrefprev60-tvk.dtb \
diff --git a/arch/arm/boot/dts/pxa27x-lp8x4x.dts b/arch/arm/boot/dts/pxa27x-lp8x4x.dts
new file mode 100644
index 0000000..a2a9183
--- /dev/null
+++ b/arch/arm/boot/dts/pxa27x-lp8x4x.dts
@@ -0,0 +1,111 @@
+/* Device tree for ICP DAS LP-8x4x */
+/dts-v1/;
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include "pxa27x.dtsi"
+
+/ {
+ model = "ICP DAS LP-8x4x programmable automation controller";
+ compatible = "marvell,lp8x4x", "marvell,pxa270";
+
+ memory {
+ reg = <0xa0000000 0x08000000>;
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ vmmc: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "vmmc";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ };
+
+ flash@00000000 {
+ compatible = "cfi-flash";
+ reg = <0x0 0x02000000>;
+ bank-width = <4>;
+ device-width = <2>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ fs@0 {
+ label = "u-boot";
+ reg = <0 0x40000>;
+ };
+ fs@40000 {
+ label = "settings";
+ reg = <0x40000 0x40000>;
+ };
+ fs@80000 {
+ label = "kernel";
+ reg = <0x80000 0x280000>;
+ };
+ fs@300000 {
+ label = "root_fs";
+ reg = <0x300000 0x1d00000>;
+ };
+ };
+
+ flash@04000000 {
+ compatible = "cfi-flash";
+ reg = <0x04000000 0x02000000>;
+ bank-width = <2>;
+ device-width = <1>;
+ };
+
+ pxabus {
+ pxairq: interrupt-controller@40d00000 {
+ marvell,intc-priority;
+ marvell,intc-nr-irqs = <34>;
+ };
+
+ uart@40100000 {
+ status = "okay";
+ };
+
+ uart@40200000 {
+ status = "okay";
+ };
+
+ uart@40700000 {
+ status = "okay";
+ };
+
+ mmc@41100000 {
+ status = "okay";
+ vmmc-supply = <&vmmc>;
+ marvell,dma-channels = <21 22>;
+ };
+
+ ohci@4c000000 {
+ status = "okay";
+ marvell,port-mode = <3>;
+ marvell,oc-mode-perport;
+ marvell,enable-port1;
+ };
+
+ eth0: eth@0c000000 {
+ compatible = "davicom,dm9000";
+ reg = <0x0c000000 0x2
+ 0x0c004000 0x2>;
+ interrupt-parent = <&gpio>;
+ interrupts = <9 IRQ_TYPE_EDGE_RISING>;
+ status = "okay";
+ };
+
+ eth1: eth@0d000000 {
+ compatible = "davicom,dm9000";
+ reg = <0x0d000000 0x2
+ 0x0d004000 0x2>;
+ interrupt-parent = <&gpio>;
+ interrupts = <82 IRQ_TYPE_EDGE_RISING>;
+ status = "okay";
+ };
+ };
+};
diff --git a/arch/arm/configs/lp8x4x_defconfig b/arch/arm/configs/lp8x4x_defconfig
new file mode 100644
index 0000000..4421c03
--- /dev/null
+++ b/arch/arm/configs/lp8x4x_defconfig
@@ -0,0 +1,160 @@
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_RCU_BOOST=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+# CONFIG_UID16 is not set
+# CONFIG_SHMEM is not set
+CONFIG_EMBEDDED=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLOB=y
+CONFIG_JUMP_LABEL=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+# CONFIG_LBDAF is not set
+CONFIG_BLK_CMDLINE_PARSER=y
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+CONFIG_ARCH_PXA=y
+CONFIG_MACH_PXA27X_DT=y
+# CONFIG_ARM_THUMB is not set
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+# CONFIG_COMPACTION is not set
+# CONFIG_CROSS_MEMORY_ATTACH is not set
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="init=/sbin/init root=/dev/mmcblk0p1 rw rootfstype=ext4 console=ttyS0,115200 mem=128M rootwait"
+# CONFIG_SUSPEND is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_BRIDGE=m
+CONFIG_BRIDGE_VLAN_FILTERING=y
+CONFIG_VLAN_8021Q=m
+CONFIG_VLAN_8021Q_GVRP=y
+CONFIG_VLAN_8021Q_MVRP=y
+# CONFIG_WIRELESS is not set
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_FW_LOADER is not set
+CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_GEOMETRY=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_PHYSMAP_OF=y
+CONFIG_PROC_DEVICETREE=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_LOOP_MIN_COUNT=2
+CONFIG_SCSI=y
+# CONFIG_SCSI_PROC_FS is not set
+CONFIG_BLK_DEV_SD=y
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_NETDEVICES=y
+CONFIG_BONDING=m
+CONFIG_MACVLAN=m
+CONFIG_MACVTAP=m
+CONFIG_TUN=m
+# CONFIG_NET_VENDOR_ARC is not set
+# CONFIG_NET_CADENCE is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CIRRUS is not set
+CONFIG_DM9000=y
+CONFIG_DM9000_FORCE_SIMPLE_PHY_POLL=y
+# CONFIG_NET_VENDOR_FARADAY 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_SEEQ is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_VIA is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
+CONFIG_PPP=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPPOE=m
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+# CONFIG_WLAN is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=800
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=600
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_8250=y
+# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=40
+CONFIG_SERIAL_8250_RUNTIME_UARTS=40
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_MANY_PORTS=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_PXA=y
+CONFIG_HW_RANDOM=y
+CONFIG_I2C=m
+# CONFIG_I2C_COMPAT is not set
+CONFIG_I2C_PXA=m
+CONFIG_I2C_PXA_SLAVE=y
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_SA1100_WATCHDOG=m
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_FB=y
+CONFIG_FB_PXA=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_LOGO=y
+CONFIG_USB=m
+CONFIG_USB_OHCI_HCD=m
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+CONFIG_USB_STORAGE=m
+CONFIG_USB_SERIAL=m
+CONFIG_MMC=y
+CONFIG_MMC_PXA=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_PXA=m
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_EXT2_FS=m
+CONFIG_EXT3_FS=y
+CONFIG_EXT4_FS=y
+CONFIG_REISERFS_FS=m
+CONFIG_ISO9660_FS=m
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_NTFS_FS=m
+CONFIG_NTFS_RW=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+CONFIG_CIFS=m
+CONFIG_CIFS_STATS=y
+CONFIG_CODA_FS=m
+CONFIG_NLS_DEFAULT="cp855"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_855=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_UTF8=y
+CONFIG_PRINTK_TIME=y
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
index 96100db..df3a79d 100644
--- a/arch/arm/mach-pxa/Kconfig
+++ b/arch/arm/mach-pxa/Kconfig
@@ -4,6 +4,21 @@ menu "Intel PXA2xx/PXA3xx Implementations"
comment "Intel/Marvell Dev Platforms (sorted by hardware release time)"
+config MACH_PXA27X_DT
+ bool "Support PXA27x platforms from device tree"
+ select PXA27x
+ select USE_OF
+ help
+ Include support for Marvell PXA27x based platforms using
+ the device tree.
+
+ While MACH_PXA27X_DT when enabled should boot any PXA27x
+ compatible machine, it still makes sense to select specific
+ machines. Those options will select required features and
+ provide per-machine errata workarounds.
+
+ If unsure, say Y.
+
config MACH_PXA3XX_DT
bool "Support PXA3xx platforms from device tree"
select CPU_PXA300
diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile
index 648867a..adaa72a 100644
--- a/arch/arm/mach-pxa/Makefile
+++ b/arch/arm/mach-pxa/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_CPU_PXA930) += pxa930.o
# NOTE: keep the order of boards in accordance to their order in Kconfig
# Device Tree support
+obj-$(CONFIG_MACH_PXA27X_DT) += pxa27x-dt.o
obj-$(CONFIG_MACH_PXA3XX_DT) += pxa-dt.o
# Intel/Marvell Dev Platforms
diff --git a/arch/arm/mach-pxa/pxa27x-dt.c b/arch/arm/mach-pxa/pxa27x-dt.c
new file mode 100644
index 0000000..865cf46
--- /dev/null
+++ b/arch/arm/mach-pxa/pxa27x-dt.c
@@ -0,0 +1,64 @@
+/*
+ * linux/arch/arm/mach-pxa/pxa27x-dt.c
+ *
+ * Copyright (C) 2013 Sergei Ianovich
+ *
+ * based mostly on linux/arch/arm/mach-pxa/pxa-dt.c by Daniel Mack
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <asm/io.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <mach/irqs.h>
+#include <mach/pxa27x.h>
+
+#include "generic.h"
+
+#ifdef CONFIG_PXA27x
+static const struct of_dev_auxdata pxa27x_auxdata_lookup[] __initconst = {
+ OF_DEV_AUXDATA("mrvl,pxa-uart", 0x40100000, "pxa2xx-uart.0", NULL),
+ OF_DEV_AUXDATA("mrvl,pxa-uart", 0x40200000, "pxa2xx-uart.1", NULL),
+ OF_DEV_AUXDATA("mrvl,pxa-uart", 0x40700000, "pxa2xx-uart.2", NULL),
+ OF_DEV_AUXDATA("mrvl,pxa-uart", 0x41600000, "pxa2xx-uart.3", NULL),
+ OF_DEV_AUXDATA("marvell,pxa-mmc", 0x41100000, "pxa2xx-mci.0", NULL),
+ OF_DEV_AUXDATA("intel,pxa27x-gpio", 0x40e00000, "pxa27x-gpio", NULL),
+ OF_DEV_AUXDATA("marvell,pxa-ohci", 0x4c000000, "pxa27x-ohci", NULL),
+ OF_DEV_AUXDATA("mrvl,pxa-i2c", 0x40301680, "pxa2xx-i2c.0", NULL),
+ {}
+};
+
+static void __init pxa27x_dt_init(void)
+{
+ of_platform_populate(NULL, of_default_bus_match_table,
+ pxa27x_auxdata_lookup, NULL);
+}
+
+static const char * const pxa27x_dt_board_compat[] __initconst = {
+ "marvell,pxa270",
+ "marvell,pxa271",
+ "marvell,pxa272",
+ NULL,
+};
+
+#endif
+
+#ifdef CONFIG_PXA27x
+DT_MACHINE_START(PXA27X_DT, "Marvell PXA27x (Device Tree Support)")
+ .map_io = pxa27x_map_io,
+ .init_irq = pxa27x_dt_init_irq,
+ .handle_irq = pxa27x_handle_irq,
+ .init_time = pxa_timer_init,
+ .restart = pxa_restart,
+ .init_machine = pxa27x_dt_init,
+ .dt_compat = pxa27x_dt_board_compat,
+MACHINE_END
+
+#endif
--
1.8.4.3
^ permalink raw reply related [flat|nested] 148+ messages in thread
* [PATCH v2 07/16] rtc: support DS1302 RTC on ICP DAS LP-8x4x
[not found] ` <1386901645-28895-1-git-send-email-ynvich@gmail.com>
` (3 preceding siblings ...)
2013-12-13 2:27 ` [PATCH v2 06/16] ARM: pxa27x: device tree support ICP DAS LP-8x4x Sergei Ianovich
@ 2013-12-13 2:27 ` Sergei Ianovich
2013-12-13 2:27 ` [PATCH v2 08/16] mtd: support BB SRAM " Sergei Ianovich
` (5 subsequent siblings)
10 siblings, 0 replies; 148+ messages in thread
From: Sergei Ianovich @ 2013-12-13 2:27 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel
Cc: Sergei Ianovich, Rob Herring, Pawel Moll, Mark Rutland,
Stephen Warren, Ian Campbell, Rob Landley, Russell King,
Alessandro Zummo, Grant Likely, open list:OPEN FIRMWARE AND...,
open list:DOCUMENTATION, rtc-linux
Signed-off-by: Sergei Ianovich <ynvich@gmail.com>
---
v0..v2
* use device tree
* use devm helpers where possible
.../devicetree/bindings/rtc/rtc-ds1302.txt | 14 +++
arch/arm/boot/dts/pxa27x-lp8x4x.dts | 6 ++
arch/arm/configs/lp8x4x_defconfig | 1 +
drivers/rtc/Kconfig | 2 +-
drivers/rtc/rtc-ds1302.c | 111 ++++++++++++++++++++-
5 files changed, 131 insertions(+), 3 deletions(-)
create mode 100644 Documentation/devicetree/bindings/rtc/rtc-ds1302.txt
diff --git a/Documentation/devicetree/bindings/rtc/rtc-ds1302.txt b/Documentation/devicetree/bindings/rtc/rtc-ds1302.txt
new file mode 100644
index 0000000..876297c
--- /dev/null
+++ b/Documentation/devicetree/bindings/rtc/rtc-ds1302.txt
@@ -0,0 +1,14 @@
+* Dallas Semiconductor DS-1302 RTC
+
+Simple device which could be used to store date/time between reboots.
+
+Required properties:
+- compatible : Should be "ds,rtc-ds1302"
+- reg : Should be address and size of IO memory region
+
+Examples:
+
+rtc@40900000 {
+ compatible = "ds,rtc-ds1302";
+ reg = <0x1700901c 0x1>;
+};
diff --git a/arch/arm/boot/dts/pxa27x-lp8x4x.dts b/arch/arm/boot/dts/pxa27x-lp8x4x.dts
index a2a9183..574e853 100644
--- a/arch/arm/boot/dts/pxa27x-lp8x4x.dts
+++ b/arch/arm/boot/dts/pxa27x-lp8x4x.dts
@@ -107,5 +107,11 @@
interrupts = <82 IRQ_TYPE_EDGE_RISING>;
status = "okay";
};
+
+ rtc@1700901c {
+ compatible = "ds,rtc-ds1302";
+ reg = <0x1700901c 0x1>;
+ status = "okay";
+ };
};
};
diff --git a/arch/arm/configs/lp8x4x_defconfig b/arch/arm/configs/lp8x4x_defconfig
index 4421c03..57f2830 100644
--- a/arch/arm/configs/lp8x4x_defconfig
+++ b/arch/arm/configs/lp8x4x_defconfig
@@ -133,6 +133,7 @@ CONFIG_USB_SERIAL=m
CONFIG_MMC=y
CONFIG_MMC_PXA=y
CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_DS1302=y
CONFIG_RTC_DRV_PXA=m
# CONFIG_IOMMU_SUPPORT is not set
CONFIG_EXT2_FS=m
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 0077302..501055f 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -676,7 +676,7 @@ config RTC_DRV_DS1286
config RTC_DRV_DS1302
tristate "Dallas DS1302"
- depends on SH_SECUREEDGE5410
+ depends on SH_SECUREEDGE5410 || (ARCH_PXA && HIGH_RES_TIMERS)
help
If you say yes here you get support for the Dallas DS1302 RTC chips.
diff --git a/drivers/rtc/rtc-ds1302.c b/drivers/rtc/rtc-ds1302.c
index 07e8d79..d88749c 100644
--- a/drivers/rtc/rtc-ds1302.c
+++ b/drivers/rtc/rtc-ds1302.c
@@ -50,7 +50,7 @@
#define ds1302_set_tx()
#define ds1302_set_rx()
-static inline int ds1302_hw_init(void)
+static inline int ds1302_hw_init(struct platform_device *pdev)
{
return 0;
}
@@ -86,6 +86,112 @@ static inline int ds1302_rxbit(void)
return !!(get_dp() & RTC_IODATA);
}
+#elif defined(CONFIG_ARCH_PXA) && defined(CONFIG_HIGH_RES_TIMERS)
+
+#include <linux/hrtimer.h>
+#include <linux/of.h>
+#include <linux/sched.h>
+
+#define RTC_CE 0x01
+#define RTC_CLK 0x02
+#define RTC_nWE 0x04
+#define RTC_IODATA 0x08
+
+static unsigned long ds1302_state;
+
+static void *mem;
+
+void nsleep(unsigned long nanosec)
+{
+ ktime_t t = ns_to_ktime(nanosec);
+ long state = current->state;
+
+ __set_current_state(TASK_UNINTERRUPTIBLE);
+ schedule_hrtimeout(&t, HRTIMER_MODE_REL);
+ __set_current_state(state);
+}
+
+static inline int ds1302_hw_init(struct platform_device *pdev)
+{
+ struct resource *r;
+
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!r)
+ return -ENODEV;
+
+ mem = devm_ioremap_resource(&pdev->dev, r);
+ if (!mem)
+ return -EFAULT;
+
+ return 0;
+}
+
+static inline void ds1302_reset(void)
+{
+ ds1302_state = 0;
+ iowrite8(ds1302_state, mem);
+ nsleep(4000);
+}
+
+static inline void ds1302_clock(void)
+{
+ nsleep(1000);
+ ds1302_state |= RTC_CLK;
+ iowrite8(ds1302_state, mem);
+ nsleep(1000);
+ ds1302_state &= ~RTC_CLK;
+ iowrite8(ds1302_state, mem);
+}
+
+static inline void ds1302_start(void)
+{
+ ds1302_state &= ~RTC_CLK;
+ ds1302_state |= RTC_CE;
+ iowrite8(ds1302_state, mem);
+ nsleep(3000);
+}
+
+static inline void ds1302_stop(void)
+{
+ ds1302_state &= ~RTC_CE;
+ iowrite8(ds1302_state, mem);
+}
+
+static inline void ds1302_set_tx(void)
+{
+ ds1302_state &= ~RTC_nWE;
+ iowrite8(ds1302_state, mem);
+}
+
+static inline void ds1302_set_rx(void)
+{
+ ds1302_state |= RTC_nWE;
+ iowrite8(ds1302_state, mem);
+}
+
+static inline void ds1302_txbit(int bit)
+{
+ if (bit)
+ ds1302_state |= RTC_IODATA;
+ else
+ ds1302_state &= ~RTC_IODATA;
+ iowrite8(ds1302_state, mem);
+}
+
+static inline int ds1302_rxbit(void)
+{
+ return ioread8(mem) & 0x1;
+}
+
+#ifdef CONFIG_OF
+static const struct of_device_id ds1302_dt_ids[] = {
+ { .compatible = "ds,rtc-ds1302" },
+ { }
+};
+
+MODULE_DEVICE_TABLE(of, ds1302_dt_ids);
+#endif
+
#else
#error "Add support for your platform"
#endif
@@ -216,7 +322,7 @@ static int __init ds1302_rtc_probe(struct platform_device *pdev)
{
struct rtc_device *rtc;
- if (ds1302_hw_init()) {
+ if (ds1302_hw_init(pdev)) {
dev_err(&pdev->dev, "Failed to init communication channel");
return -EINVAL;
}
@@ -245,6 +351,7 @@ static struct platform_driver ds1302_platform_driver = {
.driver = {
.name = DRV_NAME,
.owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(ds1302_dt_ids),
},
};
--
1.8.4.3
^ permalink raw reply related [flat|nested] 148+ messages in thread
* [PATCH v2 08/16] mtd: support BB SRAM on ICP DAS LP-8x4x
[not found] ` <1386901645-28895-1-git-send-email-ynvich@gmail.com>
` (4 preceding siblings ...)
2013-12-13 2:27 ` [PATCH v2 07/16] rtc: support DS1302 RTC on " Sergei Ianovich
@ 2013-12-13 2:27 ` Sergei Ianovich
[not found] ` <1386901645-28895-1-git-send-email-ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
` (4 subsequent siblings)
10 siblings, 0 replies; 148+ messages in thread
From: Sergei Ianovich @ 2013-12-13 2:27 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel
Cc: Sergei Ianovich, Rob Herring, Pawel Moll, Mark Rutland,
Stephen Warren, Ian Campbell, Russell King, David Woodhouse,
Grant Likely, Artem Bityutskiy, Robert Jarzmik, Randy Dunlap,
Kees Cook, Philip Avinash, open list:OPEN FIRMWARE AND...,
open list:MEMORY TECHNOLOGY...
This provides an MTD device driver for 512kB of battery backed up SRAM
on ICPDAS LP-8X4X programmable automation controllers.
SRAM chip is connected via FPGA and is not accessible without a driver,
unlike flash memory which is wired to CPU MMU.
This SRAM becomes an excellent persisent storage of volatile process
data like counter values and sensor statuses. Storing those data in
flash or mmc card is not a viable solution.
Signed-off-by: Sergei Ianovich <ynvich@gmail.com>
---
v0..v2
* use device tree
* use devm helpers where possible
arch/arm/boot/dts/pxa27x-lp8x4x.dts | 6 +
arch/arm/configs/lp8x4x_defconfig | 1 +
drivers/mtd/devices/Kconfig | 14 +++
drivers/mtd/devices/Makefile | 1 +
drivers/mtd/devices/sram_lp8x4x.c | 227 ++++++++++++++++++++++++++++++++++++
5 files changed, 249 insertions(+)
create mode 100644 drivers/mtd/devices/sram_lp8x4x.c
diff --git a/arch/arm/boot/dts/pxa27x-lp8x4x.dts b/arch/arm/boot/dts/pxa27x-lp8x4x.dts
index 574e853..b7f8cfc 100644
--- a/arch/arm/boot/dts/pxa27x-lp8x4x.dts
+++ b/arch/arm/boot/dts/pxa27x-lp8x4x.dts
@@ -59,6 +59,12 @@
device-width = <1>;
};
+ sram@1700a000 {
+ compatible = "icpdas,sram-lp8x4x";
+ reg = <0x1700a000 0x1000
+ 0x1700901e 0x1>;
+ };
+
pxabus {
pxairq: interrupt-controller@40d00000 {
marvell,intc-priority;
diff --git a/arch/arm/configs/lp8x4x_defconfig b/arch/arm/configs/lp8x4x_defconfig
index 57f2830..8fa871e 100644
--- a/arch/arm/configs/lp8x4x_defconfig
+++ b/arch/arm/configs/lp8x4x_defconfig
@@ -57,6 +57,7 @@ CONFIG_MTD_CFI_ADV_OPTIONS=y
CONFIG_MTD_CFI_GEOMETRY=y
CONFIG_MTD_CFI_INTELEXT=y
CONFIG_MTD_PHYSMAP_OF=y
+CONFIG_MTD_SRAM_LP8X4X=y
CONFIG_PROC_DEVICETREE=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_LOOP_MIN_COUNT=2
diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig
index 0128138..95f2075 100644
--- a/drivers/mtd/devices/Kconfig
+++ b/drivers/mtd/devices/Kconfig
@@ -217,4 +217,18 @@ config BCH_CONST_T
default 4
endif
+config MTD_SRAM_LP8X4X
+ tristate "SRAM on ICPDAS LP-8X4X"
+ depends on OF && ARCH_PXA
+ ---help---
+ This provides an MTD device driver for 512kiB of battery backed up SRAM
+ on ICPDAS LP-8X4X programmable automation controllers.
+
+ SRAM chip is connected via FPGA and is not accessible without a driver,
+ unlike flash memory which is wired to CPU MMU.
+
+ Say N, unless you plan to run this kernel on LP-8X4X.
+
+ If you say M, the module will be called sram_lp8x4x.
+
endmenu
diff --git a/drivers/mtd/devices/Makefile b/drivers/mtd/devices/Makefile
index d83bd73..56a74c9 100644
--- a/drivers/mtd/devices/Makefile
+++ b/drivers/mtd/devices/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_MTD_NAND_OMAP_BCH) += elm.o
obj-$(CONFIG_MTD_SPEAR_SMI) += spear_smi.o
obj-$(CONFIG_MTD_SST25L) += sst25l.o
obj-$(CONFIG_MTD_BCM47XXSFLASH) += bcm47xxsflash.o
+obj-$(CONFIG_MTD_SRAM_LP8X4X) += sram_lp8x4x.o
CFLAGS_docg3.o += -I$(src)
diff --git a/drivers/mtd/devices/sram_lp8x4x.c b/drivers/mtd/devices/sram_lp8x4x.c
new file mode 100644
index 0000000..9dc7149
--- /dev/null
+++ b/drivers/mtd/devices/sram_lp8x4x.c
@@ -0,0 +1,227 @@
+/*
+ * linux/drivers/mtd/devices/lp8x4x_sram.c
+ *
+ * MTD Driver for SRAM on ICPDAS LP-8x4x
+ * Copyright (C) 2013 Sergei Ianovich <ynvich@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation or any later version.
+ */
+
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/platform_device.h>
+#include <linux/of_device.h>
+#include <linux/slab.h>
+#include <linux/string_helpers.h>
+#include <linux/types.h>
+
+#include <asm/mach/flash.h>
+
+struct lp8x4x_sram_info {
+ void __iomem *bank;
+ void __iomem *virt;
+ struct mutex lock;
+ unsigned active_bank;
+ struct mtd_info mtd;
+};
+
+static int
+lp8x4x_sram_erase(struct mtd_info *mtd, struct erase_info *instr)
+{
+ struct lp8x4x_sram_info *info = mtd->priv;
+ unsigned bank = instr->addr >> 11;
+ unsigned offset = (instr->addr & 0x7ff) << 1;
+ loff_t i;
+
+ mutex_lock(&info->lock);
+ if (unlikely(bank != info->active_bank)) {
+ info->active_bank = bank;
+ iowrite8(bank, info->bank);
+ }
+ for (i = 0; i < instr->len; i++) {
+ iowrite8(0xff, info->virt + offset);
+ offset += 2;
+ if (unlikely(offset == 0)) {
+ info->active_bank++;
+ iowrite8(info->active_bank, info->bank);
+ }
+ }
+ mutex_unlock(&info->lock);
+ instr->state = MTD_ERASE_DONE;
+ mtd_erase_callback(instr);
+
+ return 0;
+}
+
+static int
+lp8x4x_sram_write(struct mtd_info *mtd, loff_t to, size_t len,
+ size_t *retlen, const u_char *b)
+{
+ struct lp8x4x_sram_info *info = mtd->priv;
+ unsigned bank = to >> 11;
+ unsigned offset = (to & 0x7ff) << 1;
+ loff_t i;
+
+ mutex_lock(&info->lock);
+ if (unlikely(bank != info->active_bank)) {
+ info->active_bank = bank;
+ iowrite8(bank, info->bank);
+ }
+ for (i = 0; i < len; i++) {
+ iowrite8(b[i], info->virt + offset);
+ offset += 2;
+ if (unlikely(offset == 0)) {
+ info->active_bank++;
+ iowrite8(info->active_bank, info->bank);
+ }
+ }
+ mutex_unlock(&info->lock);
+ *retlen = len;
+ return 0;
+}
+
+static int
+lp8x4x_sram_read(struct mtd_info *mtd, loff_t from, size_t len,
+ size_t *retlen, u_char *b)
+{
+ struct lp8x4x_sram_info *info = mtd->priv;
+ unsigned bank = from >> 11;
+ unsigned offset = (from & 0x7ff) << 1;
+ loff_t i;
+
+ mutex_lock(&info->lock);
+ if (unlikely(bank != info->active_bank)) {
+ info->active_bank = bank;
+ iowrite8(bank, info->bank);
+ }
+ for (i = 0; i < len; i++) {
+ b[i] = ioread8(info->virt + offset);
+ offset += 2;
+ if (unlikely(offset == 0)) {
+ info->active_bank++;
+ iowrite8(info->active_bank, info->bank);
+ }
+ }
+ mutex_unlock(&info->lock);
+ *retlen = len;
+ return 0;
+}
+
+static void
+lp8x4x_sram_sync(struct mtd_info *mtd)
+{
+}
+
+static struct of_device_id of_flash_match[] = {
+ {
+ .compatible = "icpdas,sram-lp8x4x",
+ },
+ { },
+};
+MODULE_DEVICE_TABLE(of, of_flash_match);
+
+static const char * const probe_types[] = {
+ "cmdlinepart", "RedBoot", "ofpart", "ofoldpart", NULL };
+
+static int
+lp8x4x_sram_probe(struct platform_device *pdev)
+{
+ const struct of_device_id *match;
+ struct lp8x4x_sram_info *info;
+ struct resource *r1, *r2;
+ char sz_str[16];
+ struct mtd_part_parser_data ppdata;
+ int err = 0;
+
+ match = of_match_device(of_flash_match, &pdev->dev);
+ if (!match)
+ return -EINVAL;
+
+ r1 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ r2 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (!r1 || !r2)
+ return -ENODEV;
+
+ info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
+ if (!info)
+ return -ENOMEM;
+
+ info->virt = devm_ioremap_resource(&pdev->dev, r1);
+ if (!info->virt) {
+ dev_err(&pdev->dev, "Failed to ioremap %p\n",
+ info->virt);
+ return -EFAULT;
+ }
+
+ info->bank = devm_ioremap_resource(&pdev->dev, r2);
+ if (!info->bank) {
+ dev_err(&pdev->dev, "Failed to ioremap %p\n",
+ info->bank);
+ return -EFAULT;
+ }
+
+ info->mtd.priv = info;
+ info->mtd.name = "SRAM";
+ info->mtd.type = MTD_RAM;
+ info->mtd.flags = MTD_CAP_RAM;
+ info->mtd.size = resource_size(r1) << 7;
+ info->mtd.erasesize = 512;
+ info->mtd.writesize = 4;
+ info->mtd._erase = lp8x4x_sram_erase;
+ info->mtd._write = lp8x4x_sram_write;
+ info->mtd._read = lp8x4x_sram_read;
+ info->mtd._sync = lp8x4x_sram_sync;
+ info->mtd.owner = THIS_MODULE;
+
+ mutex_init(&info->lock);
+ iowrite8(info->active_bank, info->bank);
+ platform_set_drvdata(pdev, info);
+
+ ppdata.of_node = pdev->dev.of_node;
+ err = mtd_device_parse_register(&info->mtd, probe_types, &ppdata,
+ NULL, 0);
+
+ if (err < 0) {
+ dev_err(&pdev->dev, "Failed to register platform device\n");
+ return err;
+ }
+
+ string_get_size(info->mtd.size, STRING_UNITS_2, sz_str,
+ sizeof(sz_str));
+ dev_info(&pdev->dev, "using %s SRAM on LP-8X4X as %s\n", sz_str,
+ dev_name(&info->mtd.dev));
+ return 0;
+}
+
+static int
+lp8x4x_sram_remove(struct platform_device *dev)
+{
+ struct lp8x4x_sram_info *info = platform_get_drvdata(dev);
+
+ mtd_device_unregister(&info->mtd);
+ platform_set_drvdata(dev, NULL);
+ return 0;
+}
+
+static struct platform_driver lp8x4x_sram_driver = {
+ .driver = {
+ .name = "sram-lp8x4x",
+ .owner = THIS_MODULE,
+ .of_match_table = of_flash_match,
+ },
+ .probe = lp8x4x_sram_probe,
+ .remove = lp8x4x_sram_remove,
+};
+
+module_platform_driver(lp8x4x_sram_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Sergei Ianovich <ynvich@gmail.com>");
+MODULE_DESCRIPTION("MTD driver for SRAM on ICPDAS LP-8x4x");
--
1.8.4.3
^ permalink raw reply related [flat|nested] 148+ messages in thread
* [PATCH v2 09/16] ARM: pxa: support ICP DAS LP-8x4x FPGA irq
[not found] ` <1386901645-28895-1-git-send-email-ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2013-12-13 2:27 ` Sergei Ianovich
0 siblings, 0 replies; 148+ messages in thread
From: Sergei Ianovich @ 2013-12-13 2:27 UTC (permalink / raw)
To: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
Cc: Sergei Ianovich, Arnd Bergmann, Linus Walleij, Rob Herring,
Pawel Moll, Mark Rutland, Stephen Warren, Ian Campbell,
Rob Landley, Russell King, Thomas Gleixner, Grant Likely,
open list:OPEN FIRMWARE AND..., open list:DOCUMENTATION
ICP DAS LP-8x4x contains FPGA chip. The chip functions as a interrupt
source providing 16 additional interrupts among other things. The
interrupt lines are muxed to a GPIO pin. GPIO pins are in turn muxed
to a CPU interrupt line.
Until pxa is completely converted to device tree, it is impossible
to use IRQCHIP_DECLARE() and the irqdomain needs to added manually.
Signed-off-by: Sergei Ianovich <ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
CC: Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org>
CC: Linus Walleij <linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
---
v0..v2
* extract irqchip and move to drivers/irqchip/
* use device tree
* use devm helpers where possible
.../bindings/interrupt-controller/irq-lp8x4x.txt | 49 +++++
arch/arm/boot/dts/pxa27x-lp8x4x.dts | 10 +
drivers/irqchip/Kconfig | 5 +
drivers/irqchip/Makefile | 1 +
drivers/irqchip/irq-lp8x4x.c | 205 +++++++++++++++++++++
5 files changed, 270 insertions(+)
create mode 100644 Documentation/devicetree/bindings/interrupt-controller/irq-lp8x4x.txt
create mode 100644 drivers/irqchip/irq-lp8x4x.c
diff --git a/Documentation/devicetree/bindings/interrupt-controller/irq-lp8x4x.txt b/Documentation/devicetree/bindings/interrupt-controller/irq-lp8x4x.txt
new file mode 100644
index 0000000..c8940d2
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/irq-lp8x4x.txt
@@ -0,0 +1,49 @@
+ICP DAS LP-8x4x FPGA Interrupt Controller
+
+ICP DAS LP-8x4x contains FPGA chip. The chip functions as a interrupt
+source providing 16 additional interrupts among other things.
+
+Required properties:
+- compatible : should be "icpdas,irq-lp8x4x"
+
+- reg: physical base address of the controller and length of memory mapped
+ region.
+
+- interrupt-controller : identifies the node as an interrupt controller
+
+- #interrupt-cells : should be 1
+
+- interrupts : should provide interrupt
+
+- interrupt-parent : should provide a link to interrupt controller either
+ explicitly and implicitly from a parent node
+
+Example:
+
+ fpga: fpga@17000006 {
+ compatible = "icpdas,irq-lp8x4x";
+ reg = <0x17000006 0x16>;
+ interrupt-parent = <&gpio>;
+ interrupts = <3 IRQ_TYPE_EDGE_RISING>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ status = "okay";
+ };
+
+ uart@17009050 {
+ compatible = "icpdas,uart-lp8x4x";
+ reg = <0x17009050 0x10
+ 0x17009030 0x02>;
+ interrupt-parent = <&fpga>;
+ interrupts = <13>;
+ status = "okay";
+ };
+
+ uart@17009060 {
+ compatible = "icpdas,uart-lp8x4x";
+ reg = <0x17009060 0x10
+ 0x17009032 0x02>;
+ interrupt-parent = <&fpga>;
+ interrupts = <14>;
+ status = "okay";
+ };
diff --git a/arch/arm/boot/dts/pxa27x-lp8x4x.dts b/arch/arm/boot/dts/pxa27x-lp8x4x.dts
index b7f8cfc..2704760 100644
--- a/arch/arm/boot/dts/pxa27x-lp8x4x.dts
+++ b/arch/arm/boot/dts/pxa27x-lp8x4x.dts
@@ -119,5 +119,15 @@
reg = <0x1700901c 0x1>;
status = "okay";
};
+
+ fpga: fpga@17009006 {
+ compatible = "icpdas,irq-lp8x4x";
+ reg = <0x17009006 0x16>;
+ interrupt-parent = <&gpio>;
+ interrupts = <3 IRQ_TYPE_EDGE_BOTH>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ status = "okay";
+ };
};
};
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 3792a1a..7e22729 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -35,6 +35,11 @@ config IMGPDC_IRQ
select GENERIC_IRQ_CHIP
select IRQ_DOMAIN
+config LP8X4X_IRQ
+ bool
+ depends on OF
+ select IRQ_DOMAIN
+
config ORION_IRQCHIP
bool
select IRQ_DOMAIN
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index c60b901..8a28927 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -22,3 +22,4 @@ obj-$(CONFIG_RENESAS_IRQC) += irq-renesas-irqc.o
obj-$(CONFIG_VERSATILE_FPGA_IRQ) += irq-versatile-fpga.o
obj-$(CONFIG_ARCH_VT8500) += irq-vt8500.o
obj-$(CONFIG_TB10X_IRQC) += irq-tb10x.o
+obj-$(CONFIG_LP8X4X_IRQ) += irq-lp8x4x.o
diff --git a/drivers/irqchip/irq-lp8x4x.c b/drivers/irqchip/irq-lp8x4x.c
new file mode 100644
index 0000000..5d44880b
--- /dev/null
+++ b/drivers/irqchip/irq-lp8x4x.c
@@ -0,0 +1,205 @@
+/*
+ * linux/drivers/irqchip/irq-lp8x4x.c
+ *
+ * Support for ICP DAS LP-8x4x FPGA irq
+ * Copyright (C) 2013 Sergei Ianovich <ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation or any later version.
+ */
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+
+#define EOI 0x00000000
+#define INSINT 0x00000002
+#define ENSYSINT 0x00000004
+#define PRIMINT 0x00000006
+#define SECOINT 0x00000008
+#define ENRISEINT 0x0000000A
+#define CLRRISEINT 0x0000000C
+#define ENHILVINT 0x0000000E
+#define CLRHILVINT 0x00000010
+#define ENFALLINT 0x00000012
+#define CLRFALLINT 0x00000014
+#define LP8X4X_IRQ_MEM_SIZE 0x00000016
+
+static unsigned char irq_sys_enabled;
+static unsigned char irq_high_enabled;
+static void *base;
+static int irq_base;
+static int num_irq = 16;
+
+static void lp8x4x_mask_irq(struct irq_data *d)
+{
+ unsigned mask;
+ int irq = d->irq - irq_base;
+
+ if (irq < 0 || irq > 15) {
+ pr_err("lp8x4x: wrong irq handler for irq %i\n", d->irq);
+ return;
+ }
+
+ if (irq < 8) {
+ irq_high_enabled &= ~(1 << irq);
+
+ mask = ioread8(base + ENHILVINT);
+ mask &= ~(1 << irq);
+ iowrite8(mask, base + ENHILVINT);
+ } else {
+ irq -= 8;
+ irq_sys_enabled &= ~(1 << irq);
+
+ mask = ioread8(base + ENSYSINT);
+ mask &= ~(1 << irq);
+ iowrite8(mask, base + ENSYSINT);
+ }
+}
+
+static void lp8x4x_unmask_irq(struct irq_data *d)
+{
+ unsigned mask;
+ int irq = d->irq - irq_base;
+
+ if (irq < 0 || irq > 15) {
+ pr_err("wrong irq handler for irq %i\n", d->irq);
+ return;
+ }
+
+ if (irq < 8) {
+ irq_high_enabled |= 1 << irq;
+ mask = ioread8(base + CLRHILVINT);
+ mask |= 1 << irq;
+ iowrite8(mask, base + CLRHILVINT);
+
+ mask = ioread8(base + ENHILVINT);
+ mask |= 1 << irq;
+ iowrite8(mask, base + ENHILVINT);
+ } else {
+ irq -= 8;
+ irq_sys_enabled |= 1 << irq;
+
+ mask = ioread8(base + SECOINT);
+ mask |= 1 << irq;
+ iowrite8(mask, base + SECOINT);
+
+ mask = ioread8(base + ENSYSINT);
+ mask |= 1 << irq;
+ iowrite8(mask, base + ENSYSINT);
+ }
+}
+
+static struct irq_chip lp8x4x_irq_chip = {
+ .name = "FPGA",
+ .irq_ack = lp8x4x_mask_irq,
+ .irq_mask = lp8x4x_mask_irq,
+ .irq_mask_ack = lp8x4x_mask_irq,
+ .irq_unmask = lp8x4x_unmask_irq,
+};
+
+static void lp8x4x_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+ int loop, n;
+ unsigned long mask;
+ struct irq_chip *chip = irq_desc_get_chip(desc);
+
+ chained_irq_enter(chip, desc);
+
+ do {
+ loop = 0;
+ mask = ioread8(base + CLRHILVINT) & 0xff;
+ mask |= (ioread8(base + SECOINT) & 0x1f) << 8;
+ mask |= (ioread8(base + PRIMINT) & 0xe0) << 8;
+ mask &= (irq_high_enabled | (irq_sys_enabled << 8));
+ for_each_set_bit(n, &mask, BITS_PER_LONG) {
+ loop = 1;
+
+ generic_handle_irq(irq_base + n);
+ }
+ } while (loop);
+
+ iowrite8(0, base + EOI);
+ chained_irq_exit(chip, desc);
+}
+
+static int lp8x4x_irq_domain_map(struct irq_domain *d, unsigned int irq,
+ irq_hw_number_t hw)
+{
+ irq_set_chip_and_handler(irq, &lp8x4x_irq_chip,
+ handle_level_irq);
+ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+ return 0;
+}
+
+const struct irq_domain_ops lp8x4x_irq_domain_ops = {
+ .map = lp8x4x_irq_domain_map,
+ .xlate = irq_domain_xlate_onecell,
+};
+
+static struct of_device_id lp8x4x_irq_dt_ids[] = {
+ { .compatible = "icpdas,irq-lp8x4x", },
+ {}
+};
+
+static int lp8x4x_irq_probe(struct platform_device *pdev)
+{
+ struct resource *rm, *ri;
+ struct device_node *np = pdev->dev.of_node;
+ struct irq_domain *domain;
+
+ rm = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ ri = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (!rm || !ri || resource_size(rm) < LP8X4X_IRQ_MEM_SIZE)
+ return -ENODEV;
+
+ base = devm_ioremap_resource(&pdev->dev, rm);
+ if (!base) {
+ dev_err(&pdev->dev, "Failed to ioremap %p\n", base);
+ return -EFAULT;
+ }
+
+ irq_base = irq_alloc_descs(-1, 0, num_irq, 0);
+ if (irq_base < 0) {
+ dev_err(&pdev->dev, "Failed to allocate IRQ numbers\n");
+ return irq_base;
+ }
+
+ domain = irq_domain_add_legacy(np, num_irq, irq_base, 0,
+ &lp8x4x_irq_domain_ops, NULL);
+ if (!domain) {
+ dev_err(&pdev->dev, "Failed to add IRQ domain\n");
+ return -ENOMEM;
+ }
+
+ iowrite8(0, base + CLRRISEINT);
+ iowrite8(0, base + ENRISEINT);
+ iowrite8(0, base + CLRFALLINT);
+ iowrite8(0, base + ENFALLINT);
+ iowrite8(0, base + CLRHILVINT);
+ iowrite8(0, base + ENHILVINT);
+ iowrite8(0, base + ENSYSINT);
+ iowrite8(0, base + SECOINT);
+
+ irq_set_chained_handler(ri->start, lp8x4x_irq_handler);
+
+ return 0;
+}
+
+static struct platform_driver lp8x4x_irq_driver = {
+ .probe = lp8x4x_irq_probe,
+ .driver = {
+ .name = "irq-lp8x4x",
+ .of_match_table = lp8x4x_irq_dt_ids,
+ },
+};
+
+static int __init lp8x4x_irq_init(void)
+{
+ return platform_driver_register(&lp8x4x_irq_driver);
+}
+postcore_initcall(lp8x4x_irq_init);
--
1.8.4.3
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 148+ messages in thread
* [PATCH v2 10/16] serial: support for 16550A serial ports on LP-8x4x
[not found] ` <1386901645-28895-1-git-send-email-ynvich@gmail.com>
` (6 preceding siblings ...)
[not found] ` <1386901645-28895-1-git-send-email-ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2013-12-13 2:27 ` Sergei Ianovich
2013-12-13 2:27 ` [PATCH v2 11/16] misc: support for LP-8x4x custom parallel bus Sergei Ianovich
` (2 subsequent siblings)
10 siblings, 0 replies; 148+ messages in thread
From: Sergei Ianovich @ 2013-12-13 2:27 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel
Cc: Sergei Ianovich, Heikki Krogerus, Rob Herring, Pawel Moll,
Mark Rutland, Stephen Warren, Ian Campbell, Rob Landley,
Russell King, Greg Kroah-Hartman, Jiri Slaby, Grant Likely,
Paul Bolle, James Cameron, open list:OPEN FIRMWARE AND...,
open list:DOCUMENTATION, open list:SERIAL DRIVERS
The patch adds support for 3 additional LP-8x4x built-in serial
ports.
The device can also host up to 8 extension cards with 4 serial ports
on each card for a total of 35 ports. However, I don't have
the hardware to test extension cards, so they are not supported, yet.
Signed-off-by: Sergei Ianovich <ynvich@gmail.com>
CC: Heikki Krogerus <heikki.krogerus@linux.intel.com>
---
v0..v2
* register platform driver instead of platform device
* use device tree
* use devm helpers where possible
.../devicetree/bindings/serial/lp8x4x-serial.txt | 35 +++++
arch/arm/boot/dts/pxa27x-lp8x4x.dts | 27 ++++
arch/arm/configs/lp8x4x_defconfig | 1 +
drivers/tty/serial/8250/8250_lp8x4x.c | 162 +++++++++++++++++++++
drivers/tty/serial/8250/Kconfig | 12 ++
drivers/tty/serial/8250/Makefile | 1 +
6 files changed, 238 insertions(+)
create mode 100644 Documentation/devicetree/bindings/serial/lp8x4x-serial.txt
create mode 100644 drivers/tty/serial/8250/8250_lp8x4x.c
diff --git a/Documentation/devicetree/bindings/serial/lp8x4x-serial.txt b/Documentation/devicetree/bindings/serial/lp8x4x-serial.txt
new file mode 100644
index 0000000..eed4ffc
--- /dev/null
+++ b/Documentation/devicetree/bindings/serial/lp8x4x-serial.txt
@@ -0,0 +1,35 @@
+UART ports on ICP DAS LP-8x4x
+
+ICP DAS LP-8x4x contains three additional serial ports interfaced via
+Analog Devices ADM213EA chips in addition to 3 serial ports on PXA CPU.
+
+Required properties:
+- compatible : should be "icpdas,uart-lp8x4x"
+
+- reg : should provide 16 byte man IO memory region and 1 byte region for
+ termios
+
+- interrupts : should provide interrupt
+
+- interrupt-parent : should provide a link to interrupt controller either
+ explicitly and implicitly from a parent node
+
+Examples (from pxa27x-lp8x4x.dts):
+
+ uart@17009050 {
+ compatible = "icpdas,uart-lp8x4x";
+ reg = <0x17009050 0x10
+ 0x17009030 0x02>;
+ interrupt-parent = <&fpga>;
+ interrupts = <13>;
+ status = "okay";
+ };
+
+ uart@17009060 {
+ compatible = "icpdas,uart-lp8x4x";
+ reg = <0x17009060 0x10
+ 0x17009032 0x02>;
+ interrupt-parent = <&fpga>;
+ interrupts = <14>;
+ status = "okay";
+ };
diff --git a/arch/arm/boot/dts/pxa27x-lp8x4x.dts b/arch/arm/boot/dts/pxa27x-lp8x4x.dts
index 2704760..4bcf400 100644
--- a/arch/arm/boot/dts/pxa27x-lp8x4x.dts
+++ b/arch/arm/boot/dts/pxa27x-lp8x4x.dts
@@ -129,5 +129,32 @@
interrupt-controller;
status = "okay";
};
+
+ uart@17009050 {
+ compatible = "icpdas,uart-lp8x4x";
+ reg = <0x17009050 0x10
+ 0x17009030 0x02>;
+ interrupt-parent = <&fpga>;
+ interrupts = <13>;
+ status = "okay";
+ };
+
+ uart@17009060 {
+ compatible = "icpdas,uart-lp8x4x";
+ reg = <0x17009060 0x10
+ 0x17009032 0x02>;
+ interrupt-parent = <&fpga>;
+ interrupts = <14>;
+ status = "okay";
+ };
+
+ uart@17009070 {
+ compatible = "icpdas,uart-lp8x4x";
+ reg = <0x17009070 0x10
+ 0x17009034 0x02>;
+ interrupt-parent = <&fpga>;
+ interrupts = <15>;
+ status = "okay";
+ };
};
};
diff --git a/arch/arm/configs/lp8x4x_defconfig b/arch/arm/configs/lp8x4x_defconfig
index 8fa871e..ea1a4b8 100644
--- a/arch/arm/configs/lp8x4x_defconfig
+++ b/arch/arm/configs/lp8x4x_defconfig
@@ -111,6 +111,7 @@ CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_MANY_PORTS=y
CONFIG_SERIAL_8250_SHARE_IRQ=y
CONFIG_SERIAL_PXA=y
+CONFIG_SERIAL_8250_LP8X4X=m
CONFIG_HW_RANDOM=y
CONFIG_I2C=m
# CONFIG_I2C_COMPAT is not set
diff --git a/drivers/tty/serial/8250/8250_lp8x4x.c b/drivers/tty/serial/8250/8250_lp8x4x.c
new file mode 100644
index 0000000..ec2f215
--- /dev/null
+++ b/drivers/tty/serial/8250/8250_lp8x4x.c
@@ -0,0 +1,162 @@
+/* linux/drivers/tty/serial/8250/8250_lp8x4x.c
+ *
+ * Support for 16550A serial ports on ICP DAS LP-8x4x
+ *
+ * Copyright (C) 2013 Sergei Ianovich <ynvich@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+#include <linux/serial_8250.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+
+struct lp8x4x_serial_data {
+ int line;
+ void *ios_mem;
+};
+
+static void lp8x4x_serial_set_termios(struct uart_port *port,
+ struct ktermios *termios, struct ktermios *old)
+{
+ unsigned int len;
+ unsigned int baud;
+ struct lp8x4x_serial_data *data = port->private_data;
+
+ switch (termios->c_cflag & CSIZE) {
+ case CS5:
+ len = 7;
+ break;
+ case CS6:
+ len = 8;
+ break;
+ case CS7:
+ len = 9;
+ break;
+ default:
+ case CS8:
+ len = 10;
+ break;
+ }
+
+ if (termios->c_cflag & CSTOPB)
+ len++;
+ if (termios->c_cflag & PARENB)
+ len++;
+ if (!(termios->c_cflag & PARODD))
+ len++;
+#ifdef CMSPAR
+ if (termios->c_cflag & CMSPAR)
+ len++;
+#endif
+
+ len -= 9;
+ len &= 3;
+ len <<= 3;
+ /*
+ * Ask the core to calculate the divisor for us.
+ */
+ baud = uart_get_baud_rate(port, termios, old,
+ port->uartclk / 16 / 0xffff,
+ port->uartclk / 16);
+ switch (baud) {
+ case 2400:
+ len |= 1;
+ case 4800:
+ len |= 2;
+ case 19200:
+ len |= 4;
+ case 38400:
+ len |= 5;
+ case 57600:
+ len |= 6;
+ case 115200:
+ len |= 7;
+ case 9600:
+ default:
+ len |= 3;
+ };
+ iowrite8(len, data->ios_mem);
+
+ serial8250_do_set_termios(port, termios, old);
+}
+
+static struct of_device_id lp8x4x_serial_dt_ids[] = {
+ { .compatible = "icpdas,uart-lp8x4x", },
+ {}
+};
+MODULE_DEVICE_TABLE(of, lp8x4x_serial_dt_ids);
+
+static int lp8x4x_serial_probe(struct platform_device *pdev)
+{
+ struct uart_8250_port uart = {};
+ struct lp8x4x_serial_data *data;
+ struct resource *mmres, *mires, *irqres;
+ int ret;
+
+ mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ mires = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ irqres = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (!mmres || !mires || !irqres)
+ return -ENODEV;
+
+ data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ data->ios_mem = devm_ioremap_resource(&pdev->dev, mires);
+ if (!data->ios_mem)
+ return -EFAULT;
+
+ uart.port.iotype = UPIO_MEM;
+ uart.port.mapbase = mmres->start;
+ uart.port.iobase = mmres->start;
+ uart.port.regshift = 1;
+ uart.port.irq = irqres->start;
+ uart.port.flags = UPF_IOREMAP;
+ uart.port.dev = &pdev->dev;
+ uart.port.uartclk = 14745600;
+ uart.port.set_termios = lp8x4x_serial_set_termios;
+ uart.port.private_data = data;
+
+ ret = serial8250_register_8250_port(&uart);
+ if (ret < 0)
+ return ret;
+
+ data->line = ret;
+
+ platform_set_drvdata(pdev, data);
+
+ return 0;
+}
+
+static int lp8x4x_serial_remove(struct platform_device *pdev)
+{
+ struct lp8x4x_serial_data *data = platform_get_drvdata(pdev);
+
+ serial8250_unregister_port(data->line);
+
+ return 0;
+}
+
+static struct platform_driver lp8x4x_serial_driver = {
+ .probe = lp8x4x_serial_probe,
+ .remove = lp8x4x_serial_remove,
+
+ .driver = {
+ .name = "uart-lp8x4x",
+ .owner = THIS_MODULE,
+ .of_match_table = lp8x4x_serial_dt_ids,
+ },
+};
+
+module_platform_driver(lp8x4x_serial_driver);
+
+MODULE_AUTHOR("Sergei Ianovich");
+MODULE_DESCRIPTION("8250 serial port module for LP-8x4x");
+MODULE_LICENSE("GPL");
diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig
index 81bd7c9..9fb0fbb 100644
--- a/drivers/tty/serial/8250/Kconfig
+++ b/drivers/tty/serial/8250/Kconfig
@@ -311,3 +311,15 @@ config SERIAL_PXA
can enable its onboard serial ports by enabling this option.
If you choose M here, the module name will be 8250_pxa.
+
+config SERIAL_8250_LP8X4X
+ tristate "Support 16550A ports on ICP DAS LP-8x4x"
+ depends on OF && SERIAL_8250 && SERIAL_8250_MANY_PORTS && ARCH_PXA
+ select LP8X4X_IRQ
+ help
+ In addition to serial ports on PXA270 SoC, LP-8x4x has 1 dual
+ RS232/RS485 port, 1 RS485 port and 1 RS232 port.
+
+ Say N here, unless you plan to run this kernel on a LP-8x4x system.
+
+ If you choose M here, the module name will be 8250_lp8x4x.
diff --git a/drivers/tty/serial/8250/Makefile b/drivers/tty/serial/8250/Makefile
index b7d1b61..7370bfb 100644
--- a/drivers/tty/serial/8250/Makefile
+++ b/drivers/tty/serial/8250/Makefile
@@ -17,6 +17,7 @@ obj-$(CONFIG_SERIAL_8250_ACCENT) += 8250_accent.o
obj-$(CONFIG_SERIAL_8250_BOCA) += 8250_boca.o
obj-$(CONFIG_SERIAL_8250_EXAR_ST16C554) += 8250_exar_st16c554.o
obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o
+obj-$(CONFIG_SERIAL_8250_LP8X4X) += 8250_lp8x4x.o
obj-$(CONFIG_SERIAL_8250_FSL) += 8250_fsl.o
obj-$(CONFIG_SERIAL_8250_DW) += 8250_dw.o
obj-$(CONFIG_SERIAL_8250_EM) += 8250_em.o
--
1.8.4.3
^ permalink raw reply related [flat|nested] 148+ messages in thread
* [PATCH v2 11/16] misc: support for LP-8x4x custom parallel bus
[not found] ` <1386901645-28895-1-git-send-email-ynvich@gmail.com>
` (7 preceding siblings ...)
2013-12-13 2:27 ` [PATCH v2 10/16] serial: support for 16550A serial ports on LP-8x4x Sergei Ianovich
@ 2013-12-13 2:27 ` Sergei Ianovich
2013-12-13 2:27 ` [PATCH v2 12/16] misc: support for serial slots in LP-8x4x Sergei Ianovich
[not found] ` <1387309071-22382-1-git-send-email-ynvich@gmail.com>
10 siblings, 0 replies; 148+ messages in thread
From: Sergei Ianovich @ 2013-12-13 2:27 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel
Cc: Sergei Ianovich, Rob Herring, Pawel Moll, Mark Rutland,
Stephen Warren, Ian Campbell, Rob Landley, Russell King,
Arnd Bergmann, Greg Kroah-Hartman, Grant Likely,
open list:OPEN FIRMWARE AND..., open list:DOCUMENTATION
This patch implements probing for the bus and reporting the number
of available expansion slots.
Signed-off-by: Sergei Ianovich <ynvich@gmail.com>
---
v0..v2
* use device tree
* use devm helpers where possible
.../devicetree/bindings/misc/lp8x4x-bus.txt | 16 ++
Documentation/misc-devices/lp8x4x_bus.txt | 30 ++++
arch/arm/boot/dts/pxa27x-lp8x4x.dts | 5 +
arch/arm/configs/lp8x4x_defconfig | 1 +
drivers/misc/Kconfig | 13 ++
drivers/misc/Makefile | 1 +
drivers/misc/lp8x4x_bus.c | 165 +++++++++++++++++++++
7 files changed, 231 insertions(+)
create mode 100644 Documentation/devicetree/bindings/misc/lp8x4x-bus.txt
create mode 100644 Documentation/misc-devices/lp8x4x_bus.txt
create mode 100644 drivers/misc/lp8x4x_bus.c
diff --git a/Documentation/devicetree/bindings/misc/lp8x4x-bus.txt b/Documentation/devicetree/bindings/misc/lp8x4x-bus.txt
new file mode 100644
index 0000000..1c87a29
--- /dev/null
+++ b/Documentation/devicetree/bindings/misc/lp8x4x-bus.txt
@@ -0,0 +1,16 @@
+Custom parallel bus on ICP DAS LP-8x4x industrial computers
+
+See Documentation/misc-devices/lp8x4x_bus.txt for details.
+
+Required properties:
+- compatible : should be "icpdas,backplane-lp8x4x"
+
+- reg: physical base address of the slot count register and the length
+ of the memory mapped region.
+
+Example:
+
+ backplane {
+ compatible = "icpdas,backplane-lp8x4x";
+ reg = <0x17009046 0x2>;
+ };
diff --git a/Documentation/misc-devices/lp8x4x_bus.txt b/Documentation/misc-devices/lp8x4x_bus.txt
new file mode 100644
index 0000000..f5392b3
--- /dev/null
+++ b/Documentation/misc-devices/lp8x4x_bus.txt
@@ -0,0 +1,30 @@
+Kernel driver lpx8x4x_bus
+======================
+
+Supported hardare:
+Custom parallel bus on ICP DAS LP-8x4x industrial computers
+
+Data sheet:
+Not freely available
+
+Author:
+Sergei Ianovich <ynvich@gmail.com>
+
+Description
+-----------
+
+http://www.icpdas.com/root/product/solutions/pac/linpac/lp-8x4x_hardware.html
+
+LP-8x4x is an ARM-based industrial computer with a custom parallel bus to
+connect expansion modules with digital input/output, analog input/output,
+serial, CAN and other types of ports.
+
+The bus is implemented by a FPGA.
+
+SYSFS
+-----
+
+/sys/bus/icpdas/devices/backplane:
+
+slot_count
+ RO - shows total number of expansion slots on the device
diff --git a/arch/arm/boot/dts/pxa27x-lp8x4x.dts b/arch/arm/boot/dts/pxa27x-lp8x4x.dts
index 138de0a..6c8e8e6 100644
--- a/arch/arm/boot/dts/pxa27x-lp8x4x.dts
+++ b/arch/arm/boot/dts/pxa27x-lp8x4x.dts
@@ -156,5 +156,10 @@
interrupts = <15>;
status = "okay";
};
+
+ backplane {
+ compatible = "icpdas,backplane-lp8x4x";
+ reg = <0x17009046 0x2>;
+ };
};
};
diff --git a/arch/arm/configs/lp8x4x_defconfig b/arch/arm/configs/lp8x4x_defconfig
index ea1a4b8..31cf46e 100644
--- a/arch/arm/configs/lp8x4x_defconfig
+++ b/arch/arm/configs/lp8x4x_defconfig
@@ -61,6 +61,7 @@ CONFIG_MTD_SRAM_LP8X4X=y
CONFIG_PROC_DEVICETREE=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_LOOP_MIN_COUNT=2
+CONFIG_LP8X4X_BUS=m
CONFIG_SCSI=y
# CONFIG_SCSI_PROC_FS is not set
CONFIG_BLK_DEV_SD=y
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index a3e291d..e4d52da 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -515,6 +515,19 @@ config SRAM
the genalloc API. It is supposed to be used for small on-chip SRAM
areas found on many SoCs.
+config LP8X4X_BUS
+ tristate "ICP DAS LP-8x4x industrial IO bus"
+ depends on OF && ARCH_PXA
+ select SYSFS
+ ---help---
+ This is a driver for ICP DAS LP-8x4x programmable automation
+ controller. It exposes a custom parallel bus. The bus services
+ data acquisition and control modules.
+
+ Say N, unless you plan to run this kernel on a LP-8x4x system.
+
+ If you say M here, the module will be called lp8x4x_bus.
+
source "drivers/misc/c2port/Kconfig"
source "drivers/misc/eeprom/Kconfig"
source "drivers/misc/cb710/Kconfig"
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index f45473e..7578cff 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -53,3 +53,4 @@ obj-$(CONFIG_VMWARE_VMCI) += vmw_vmci/
obj-$(CONFIG_LATTICE_ECP3_CONFIG) += lattice-ecp3-config.o
obj-$(CONFIG_SRAM) += sram.o
obj-y += mic/
+obj-$(CONFIG_LP8X4X_BUS) += lp8x4x_bus.o
diff --git a/drivers/misc/lp8x4x_bus.c b/drivers/misc/lp8x4x_bus.c
new file mode 100644
index 0000000..7119738
--- /dev/null
+++ b/drivers/misc/lp8x4x_bus.c
@@ -0,0 +1,165 @@
+/*
+ * linux/misc/lp8x4x_bus.c
+ *
+ * Support for ICP DAS LP-8x4x programmable automation controller bus
+ * Copyright (C) 2013 Sergei Ianovich <ynvich@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation or any later version.
+ */
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#define MODULE_NAME "lp8x4x-bus"
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Sergei Ianovich <ynvich@gmail.com>");
+MODULE_DESCRIPTION("ICP DAS LP-8x4x parallel bus driver");
+
+struct lp8x4x_master {
+ unsigned int slot_count;
+ void *count_addr;
+ struct device dev;
+};
+
+static int lp8x4x_match(struct device *dev, struct device_driver *drv)
+{
+ return 1;
+}
+
+static struct bus_type lp8x4x_bus_type = {
+ .name = "icpdas",
+ .match = lp8x4x_match,
+};
+
+static void lp8x4x_master_release(struct device *dev)
+{
+ struct lp8x4x_master *m = container_of(dev, struct lp8x4x_master, dev);
+ WARN_ON(!dev);
+
+ kfree(m);
+}
+
+static ssize_t slot_count_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct lp8x4x_master *m = container_of(dev, struct lp8x4x_master, dev);
+
+ return sprintf(buf, "%u\n", m->slot_count);
+}
+
+static DEVICE_ATTR_RO(slot_count);
+
+static struct attribute *master_dev_attrs[] = {
+ &dev_attr_slot_count.attr,
+ NULL,
+};
+ATTRIBUTE_GROUPS(master_dev);
+
+
+static void devm_lp8x4x_bus_release(struct device *dev, void *res)
+{
+ struct lp8x4x_master *m = *(struct lp8x4x_master **)res;
+
+ dev_dbg(dev, "releasing devices\n");
+ device_unregister(&m->dev);
+ bus_unregister(&lp8x4x_bus_type);
+}
+
+static int __init lp8x4x_bus_probe(struct platform_device *pdev)
+{
+ struct lp8x4x_master *m, **p;
+ struct resource *res;
+ int err = 0;
+
+ m = kzalloc(sizeof(*m), GFP_KERNEL);
+ if (!m)
+ return -ENOMEM;
+
+ p = devres_alloc(devm_lp8x4x_bus_release, sizeof(*p), GFP_KERNEL);
+ if (!m) {
+ err = -ENOMEM;
+ goto err1;
+ }
+ *p = m;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ err = -ENODEV;
+ goto err2;
+ }
+
+ m->count_addr = devm_ioremap_resource(&pdev->dev, res);
+ if (!m->count_addr) {
+ dev_err(&pdev->dev, "Failed to ioremap %p\n",
+ m->count_addr);
+ err = -EFAULT;
+ goto err2;
+ }
+
+ m->slot_count = ioread8(m->count_addr);
+ switch (m->slot_count) {
+ case 1:
+ case 4:
+ break;
+ case 7:
+ m->slot_count = 8;
+ break;
+ default:
+ dev_err(&pdev->dev, "unexpected slot number(%u)",
+ m->slot_count);
+ goto err2;
+ };
+
+ dev_info(&pdev->dev, "found bus with up to %u slots\n", m->slot_count);
+
+ err = bus_register(&lp8x4x_bus_type);
+ if (err < 0) {
+ dev_err(&pdev->dev, "failed to register bus type\n");
+ goto err3;
+ }
+
+ m->dev.bus = &lp8x4x_bus_type;
+ dev_set_name(&m->dev, "backplane");
+ m->dev.parent = &pdev->dev;
+ m->dev.release = lp8x4x_master_release;
+ m->dev.groups = master_dev_groups;
+
+ err = device_register(&m->dev);
+ if (err < 0) {
+ dev_err(&pdev->dev, "failed to register backplane device\n");
+ goto err3;
+ }
+
+ devres_add(&pdev->dev, p);
+ return 0;
+
+err3:
+ bus_unregister(&lp8x4x_bus_type);
+err2:
+ devres_free(p);
+err1:
+ kfree(m);
+ return err;
+}
+
+static const struct of_device_id lp8x4x_bus_dt_ids[] = {
+ { .compatible = "icpdas,backplane-lp8x4x" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, lp8x4x_bus_dt_ids);
+
+static struct platform_driver lp8x4x_bus_driver = {
+ .driver = {
+ .name = MODULE_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = lp8x4x_bus_dt_ids,
+ },
+};
+
+module_platform_driver_probe(lp8x4x_bus_driver, lp8x4x_bus_probe);
--
1.8.4.3
^ permalink raw reply related [flat|nested] 148+ messages in thread
* [PATCH v2 12/16] misc: support for serial slots in LP-8x4x
[not found] ` <1386901645-28895-1-git-send-email-ynvich@gmail.com>
` (8 preceding siblings ...)
2013-12-13 2:27 ` [PATCH v2 11/16] misc: support for LP-8x4x custom parallel bus Sergei Ianovich
@ 2013-12-13 2:27 ` Sergei Ianovich
[not found] ` <1387309071-22382-1-git-send-email-ynvich@gmail.com>
10 siblings, 0 replies; 148+ messages in thread
From: Sergei Ianovich @ 2013-12-13 2:27 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel
Cc: Sergei Ianovich, Rob Herring, Pawel Moll, Mark Rutland,
Stephen Warren, Ian Campbell, Rob Landley, Arnd Bergmann,
Greg Kroah-Hartman, open list:OPEN FIRMWARE AND...,
open list:DOCUMENTATION
Serial modules (I-870xxW series) implement DCON protocol which
allows one-master-many-slaves configuration over RS-485. When
these modules are installed into the device, they could be
accessed using the 2nd PXA built-in UART port (/dev/ttySA1).
However, it seems that addresses are not processed by the modules.
So the parallel bus needs to select which slot is connected.
Signed-off-by: Sergei Ianovich <ynvich@gmail.com>
---
v0..v2
* use device tree
* use devm helpers where possible
.../devicetree/bindings/misc/lp8x4x-bus.txt | 8 ++-
Documentation/misc-devices/lp8x4x_bus.txt | 15 ++++-
drivers/misc/lp8x4x_bus.c | 75 ++++++++++++++++++++--
3 files changed, 87 insertions(+), 11 deletions(-)
diff --git a/Documentation/devicetree/bindings/misc/lp8x4x-bus.txt b/Documentation/devicetree/bindings/misc/lp8x4x-bus.txt
index 1c87a29..61ac96e 100644
--- a/Documentation/devicetree/bindings/misc/lp8x4x-bus.txt
+++ b/Documentation/devicetree/bindings/misc/lp8x4x-bus.txt
@@ -5,12 +5,14 @@ See Documentation/misc-devices/lp8x4x_bus.txt for details.
Required properties:
- compatible : should be "icpdas,backplane-lp8x4x"
-- reg: physical base address of the slot count register and the length
- of the memory mapped region.
+- reg: physical base addresses and region lengths of
+ * the slot count register
+ * the serial slot select register
Example:
backplane {
compatible = "icpdas,backplane-lp8x4x";
- reg = <0x17009046 0x2>;
+ reg = <0x17009046 0x2
+ 0x17009004 0x2>;
};
diff --git a/Documentation/misc-devices/lp8x4x_bus.txt b/Documentation/misc-devices/lp8x4x_bus.txt
index f5392b3..d9a069d 100644
--- a/Documentation/misc-devices/lp8x4x_bus.txt
+++ b/Documentation/misc-devices/lp8x4x_bus.txt
@@ -19,7 +19,14 @@ LP-8x4x is an ARM-based industrial computer with a custom parallel bus to
connect expansion modules with digital input/output, analog input/output,
serial, CAN and other types of ports.
-The bus is implemented by a FPGA.
+The bus is implemented by a FPGA. There are two major groups of expansion
+modules: serial and parallel.
+
+Serial modules (I-870xxW series) implement DCON protocol which allows one-
+master-many-slaves configuration over RS-485. When these modules are installed
+into the device, they could be accessed using the 2nd PXA built-in UART port
+(/dev/ttyS1). However, it seems that addresses are not processed by
+the modules. So the parallel bus needs to select which slot is connected.
SYSFS
-----
@@ -28,3 +35,9 @@ SYSFS
slot_count
RO - shows total number of expansion slots on the device
+
+active_slot
+ RW - connects the select slot for serial communications. If there
+ is a parallel module in the selected slot, it simply ignores
+ incoming packets. So it is safe to activate any available
+ slot.
diff --git a/drivers/misc/lp8x4x_bus.c b/drivers/misc/lp8x4x_bus.c
index 7119738..cffe121 100644
--- a/drivers/misc/lp8x4x_bus.c
+++ b/drivers/misc/lp8x4x_bus.c
@@ -24,6 +24,8 @@ MODULE_DESCRIPTION("ICP DAS LP-8x4x parallel bus driver");
struct lp8x4x_master {
unsigned int slot_count;
void *count_addr;
+ unsigned int active_slot;
+ void *switch_addr;
struct device dev;
};
@@ -55,8 +57,45 @@ static ssize_t slot_count_show(struct device *dev,
static DEVICE_ATTR_RO(slot_count);
+static ssize_t active_slot_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct lp8x4x_master *m = container_of(dev, struct lp8x4x_master, dev);
+
+ return sprintf(buf, "%u\n", m->active_slot);
+}
+
+static ssize_t active_slot_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct lp8x4x_master *m = container_of(dev, struct lp8x4x_master, dev);
+ unsigned int active_slot = 0;
+ int err;
+
+ if (!buf)
+ return count;
+ if (0 == count)
+ return count;
+
+ err = kstrtouint(buf, 10, &active_slot);
+ if (err != 0 || !active_slot || active_slot > m->slot_count) {
+ dev_err(dev, "slot number is out of range 1..%u\n",
+ m->slot_count);
+ return count;
+ }
+
+ m->active_slot = active_slot;
+
+ iowrite8((1 << (m->active_slot - 1)) ^ 0xff, m->switch_addr);
+
+ return count;
+}
+
+static DEVICE_ATTR_RW(active_slot);
+
static struct attribute *master_dev_attrs[] = {
&dev_attr_slot_count.attr,
+ &dev_attr_active_slot.attr,
NULL,
};
ATTRIBUTE_GROUPS(master_dev);
@@ -69,6 +108,9 @@ static void devm_lp8x4x_bus_release(struct device *dev, void *res)
dev_dbg(dev, "releasing devices\n");
device_unregister(&m->dev);
bus_unregister(&lp8x4x_bus_type);
+
+ /* Disable serial communications */
+ iowrite8(0xff, m->switch_addr);
}
static int __init lp8x4x_bus_probe(struct platform_device *pdev)
@@ -90,8 +132,9 @@ static int __init lp8x4x_bus_probe(struct platform_device *pdev)
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
+ dev_err(&pdev->dev, "Failed to get slot number address\n");
err = -ENODEV;
- goto err2;
+ goto err_free;
}
m->count_addr = devm_ioremap_resource(&pdev->dev, res);
@@ -99,7 +142,22 @@ static int __init lp8x4x_bus_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "Failed to ioremap %p\n",
m->count_addr);
err = -EFAULT;
- goto err2;
+ goto err_free;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (!res) {
+ dev_err(&pdev->dev, "Failed to get slot switch address\n");
+ err = -ENODEV;
+ goto err_free;
+ }
+
+ m->switch_addr = devm_ioremap_resource(&pdev->dev, res);
+ if (!m->switch_addr) {
+ dev_err(&pdev->dev, "Failed to ioremap %p\n",
+ m->switch_addr);
+ err = -EFAULT;
+ goto err_free;
}
m->slot_count = ioread8(m->count_addr);
@@ -113,15 +171,18 @@ static int __init lp8x4x_bus_probe(struct platform_device *pdev)
default:
dev_err(&pdev->dev, "unexpected slot number(%u)",
m->slot_count);
- goto err2;
+ goto err_free;
};
dev_info(&pdev->dev, "found bus with up to %u slots\n", m->slot_count);
+ /* Disable serial communications until explicitly enabled */
+ iowrite8(0xff, m->switch_addr);
+
err = bus_register(&lp8x4x_bus_type);
if (err < 0) {
dev_err(&pdev->dev, "failed to register bus type\n");
- goto err3;
+ goto err_free;
}
m->dev.bus = &lp8x4x_bus_type;
@@ -133,15 +194,15 @@ static int __init lp8x4x_bus_probe(struct platform_device *pdev)
err = device_register(&m->dev);
if (err < 0) {
dev_err(&pdev->dev, "failed to register backplane device\n");
- goto err3;
+ goto err_bus;
}
devres_add(&pdev->dev, p);
return 0;
-err3:
+err_bus:
bus_unregister(&lp8x4x_bus_type);
-err2:
+err_free:
devres_free(p);
err1:
kfree(m);
--
1.8.4.3
^ permalink raw reply related [flat|nested] 148+ messages in thread
* Re: [PATCH v2 03/16] ARM: dts: provide DMA config to pxamci
2013-12-13 2:27 ` [PATCH v2 03/16] ARM: dts: provide DMA config to pxamci Sergei Ianovich
@ 2013-12-14 19:06 ` Arnd Bergmann
2013-12-14 19:34 ` Sergei Ianovich
0 siblings, 1 reply; 148+ messages in thread
From: Arnd Bergmann @ 2013-12-14 19:06 UTC (permalink / raw)
To: Sergei Ianovich
Cc: Mark Rutland, open list:OPEN FIRMWARE AND..., Shawn Guo,
Russell King, Pawel Moll, Stephen Warren, Viresh Kumar,
Ian Campbell, open list:DOCUMENTATION, linux-kernel, Rob Herring,
Daniel Mack, Haojian Zhuang, Rob Landley, linux-mmc, Chris Ball,
linux-arm-kernel
On Friday 13 December 2013, Sergei Ianovich wrote:
> Non-dts implementation supply required DMA channel numbers as
> IORESOURCE_DMA. However, there is was no way to get them from
> device tree.
Please update this changeset comment, I think it still refers to
the earlier version.
> Signed-off-by: Sergei Ianovich <ynvich@gmail.com>
> CC: Daniel Mack <zonque@gmail.com>
> CC: Arnd Bergmann <arnd@arndb.de>
The patch looks ok in case we are merging your patches for 3.14
and Daniel's patches later than that. If they end up in the
same merge window however, we'd have to be care to resolve
the obvious conflict in a proper way.
Arnd
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH v2 03/16] ARM: dts: provide DMA config to pxamci
2013-12-14 19:06 ` Arnd Bergmann
@ 2013-12-14 19:34 ` Sergei Ianovich
2013-12-14 23:39 ` Arnd Bergmann
2013-12-16 9:58 ` Daniel Mack
0 siblings, 2 replies; 148+ messages in thread
From: Sergei Ianovich @ 2013-12-14 19:34 UTC (permalink / raw)
To: Arnd Bergmann
Cc: linux-kernel, linux-arm-kernel, Daniel Mack, Rob Herring,
Pawel Moll, Mark Rutland, Stephen Warren, Ian Campbell,
Rob Landley, Russell King, Chris Ball, Viresh Kumar, Shawn Guo,
Haojian Zhuang, open list:OPEN FIRMWARE AND...,
open list:DOCUMENTATION, linux-mmc
On Sat, 2013-12-14 at 20:06 +0100, Arnd Bergmann wrote:
> On Friday 13 December 2013, Sergei Ianovich wrote:
> > Non-dts implementation supply required DMA channel numbers as
> > IORESOURCE_DMA. However, there is was no way to get them from
> > device tree.
>
> Please update this changeset comment, I think it still refers to
> the earlier version.
---
Non-dts implementation supply required DMA channel numbers as
IORESOURCE_DMA. We can also get them from the device tree, if it
is present.
---
Is this fine?
Should I post v3, if so?
> > Signed-off-by: Sergei Ianovich <ynvich@gmail.com>
> > CC: Daniel Mack <zonque@gmail.com>
> > CC: Arnd Bergmann <arnd@arndb.de>
>
> The patch looks ok in case we are merging your patches for 3.14
> and Daniel's patches later than that. If they end up in the
> same merge window however, we'd have to be care to resolve
> the obvious conflict in a proper way.
The most recently published Daniel's patch (Aug 2013) wraps
IORESOURCE_DMA handling on DT presence in a similar way, but doesn't do
any actual DT processing. So there is no conflict at the moment. Daniel
can comment better on this, though.
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH v2 03/16] ARM: dts: provide DMA config to pxamci
2013-12-14 19:34 ` Sergei Ianovich
@ 2013-12-14 23:39 ` Arnd Bergmann
2013-12-16 9:58 ` Daniel Mack
1 sibling, 0 replies; 148+ messages in thread
From: Arnd Bergmann @ 2013-12-14 23:39 UTC (permalink / raw)
To: Sergei Ianovich
Cc: linux-kernel, linux-arm-kernel, Daniel Mack, Rob Herring,
Pawel Moll, Mark Rutland, Stephen Warren, Ian Campbell,
Rob Landley, Russell King, Chris Ball, Viresh Kumar, Shawn Guo,
Haojian Zhuang, open list:OPEN FIRMWARE AND...,
open list:DOCUMENTATION, linux-mmc
On Saturday 14 December 2013, Sergei Ianovich wrote:
> On Sat, 2013-12-14 at 20:06 +0100, Arnd Bergmann wrote:
> > On Friday 13 December 2013, Sergei Ianovich wrote:
> > > Non-dts implementation supply required DMA channel numbers as
> > > IORESOURCE_DMA. However, there is was no way to get them from
> > > device tree.
> >
> > Please update this changeset comment, I think it still refers to
> > the earlier version.
>
> ---
> Non-dts implementation supply required DMA channel numbers as
> IORESOURCE_DMA. We can also get them from the device tree, if it
> is present.
> ---
>
> Is this fine?
I would mention that the binding is designed to work with the dmaengine
framework as soon as we have figured out how to make that work without
the problems you found.
> Should I post v3, if so?
I'd wait a little longer for more comments.
Arnd
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH v2 03/16] ARM: dts: provide DMA config to pxamci
2013-12-14 19:34 ` Sergei Ianovich
2013-12-14 23:39 ` Arnd Bergmann
@ 2013-12-16 9:58 ` Daniel Mack
2013-12-16 11:47 ` Sergei Ianovich
1 sibling, 1 reply; 148+ messages in thread
From: Daniel Mack @ 2013-12-16 9:58 UTC (permalink / raw)
To: Sergei Ianovich, Arnd Bergmann
Cc: Mark Rutland, open list:OPEN FIRMWARE AND..., Shawn Guo,
Russell King, Pawel Moll, Stephen Warren, Viresh Kumar,
Ian Campbell, DOCUMENTATION, linux-kernel, Rob Herring,
Haojian Zhuang, Rob Landley, linux-mmc, Chris Ball,
linux-arm-kernel
On 12/14/2013 08:34 PM, Sergei Ianovich wrote:
> On Sat, 2013-12-14 at 20:06 +0100, Arnd Bergmann wrote:
>> The patch looks ok in case we are merging your patches for 3.14
>> and Daniel's patches later than that. If they end up in the
>> same merge window however, we'd have to be care to resolve
>> the obvious conflict in a proper way.
>
> The most recently published Daniel's patch (Aug 2013) wraps
> IORESOURCE_DMA handling on DT presence in a similar way,
Erm, no it doesn't. My patch uses dma_request_slave_channel_compat() in
DT case, and that works fine with the current version of pdma, and
there's no need to read the "dmas" properties directly.
If you want to provide a way to simply denote the dma channel numbers,
without looking at the actual phandle, then yes, we could merge this
patch first, but it would be effectively reverted a proper implementation.
Daniel
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH v2 03/16] ARM: dts: provide DMA config to pxamci
2013-12-16 9:58 ` Daniel Mack
@ 2013-12-16 11:47 ` Sergei Ianovich
[not found] ` <1387194450.13062.134.camel-7ZSkjCHmnyFmet/iJI8ZvA@public.gmane.org>
0 siblings, 1 reply; 148+ messages in thread
From: Sergei Ianovich @ 2013-12-16 11:47 UTC (permalink / raw)
To: Daniel Mack
Cc: Arnd Bergmann, linux-kernel, linux-arm-kernel, Rob Herring,
Pawel Moll, Mark Rutland, Stephen Warren, Ian Campbell,
Rob Landley, Russell King, Chris Ball, Viresh Kumar, Shawn Guo,
Haojian Zhuang, open list:OPEN FIRMWARE AND..., DOCUMENTATION,
linux-mmc
On Mon, 2013-12-16 at 10:58 +0100, Daniel Mack wrote:
> On 12/14/2013 08:34 PM, Sergei Ianovich wrote:
> > On Sat, 2013-12-14 at 20:06 +0100, Arnd Bergmann wrote:
>
> >> The patch looks ok in case we are merging your patches for 3.14
> >> and Daniel's patches later than that. If they end up in the
> >> same merge window however, we'd have to be care to resolve
> >> the obvious conflict in a proper way.
> >
> > The most recently published Daniel's patch (Aug 2013) wraps
> > IORESOURCE_DMA handling on DT presence in a similar way,
>
> Erm, no it doesn't. My patch uses dma_request_slave_channel_compat() in
> DT case, and that works fine with the current version of pdma, and
> there's no need to read the "dmas" properties directly.
>
> If you want to provide a way to simply denote the dma channel numbers,
> without looking at the actual phandle, then yes, we could merge this
> patch first, but it would be effectively reverted a proper implementation.
Daniel is right. His patch doesn't need to read "dmas" directly. So my
patch won't need to change drivers/mmc/host/pxamci.c at all, if it is
applied after Daniel's one.
What are we going to do in this context?
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH v2 03/16] ARM: dts: provide DMA config to pxamci
[not found] ` <1387194450.13062.134.camel-7ZSkjCHmnyFmet/iJI8ZvA@public.gmane.org>
@ 2013-12-16 11:58 ` Lars-Peter Clausen
2013-12-16 12:03 ` Sergei Ianovich
0 siblings, 1 reply; 148+ messages in thread
From: Lars-Peter Clausen @ 2013-12-16 11:58 UTC (permalink / raw)
To: Sergei Ianovich
Cc: Daniel Mack, Arnd Bergmann, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Rob Herring,
Pawel Moll, Mark Rutland, Stephen Warren, Ian Campbell,
Rob Landley, Russell King, Chris Ball, Viresh Kumar, Shawn Guo,
Haojian Zhuang, open list:OPEN FIRMWARE AND..., DOCUMENTATION,
linux-mmc-u79uwXL29TY76Z2rM5mHXA
On 12/16/2013 12:47 PM, Sergei Ianovich wrote:
> On Mon, 2013-12-16 at 10:58 +0100, Daniel Mack wrote:
>> On 12/14/2013 08:34 PM, Sergei Ianovich wrote:
>>> On Sat, 2013-12-14 at 20:06 +0100, Arnd Bergmann wrote:
>>
>>>> The patch looks ok in case we are merging your patches for 3.14
>>>> and Daniel's patches later than that. If they end up in the
>>>> same merge window however, we'd have to be care to resolve
>>>> the obvious conflict in a proper way.
>>>
>>> The most recently published Daniel's patch (Aug 2013) wraps
>>> IORESOURCE_DMA handling on DT presence in a similar way,
>>
>> Erm, no it doesn't. My patch uses dma_request_slave_channel_compat() in
>> DT case, and that works fine with the current version of pdma, and
>> there's no need to read the "dmas" properties directly.
>>
>> If you want to provide a way to simply denote the dma channel numbers,
>> without looking at the actual phandle, then yes, we could merge this
>> patch first, but it would be effectively reverted a proper implementation.
>
> Daniel is right. His patch doesn't need to read "dmas" directly. So my
> patch won't need to change drivers/mmc/host/pxamci.c at all, if it is
> applied after Daniel's one.
>
Btw. any driver that parses the dmas property manually should be considered
broken. This is a classical layering violation. The layout of the dma
specifier is DMA controller specific and should be completely transparent to
the device driver.
- Lars
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH v2 03/16] ARM: dts: provide DMA config to pxamci
2013-12-16 11:58 ` Lars-Peter Clausen
@ 2013-12-16 12:03 ` Sergei Ianovich
0 siblings, 0 replies; 148+ messages in thread
From: Sergei Ianovich @ 2013-12-16 12:03 UTC (permalink / raw)
To: Lars-Peter Clausen
Cc: Daniel Mack, Arnd Bergmann, linux-kernel, linux-arm-kernel,
Rob Herring, Pawel Moll, Mark Rutland, Stephen Warren,
Ian Campbell, Rob Landley, Russell King, Chris Ball, Viresh Kumar,
Shawn Guo, Haojian Zhuang, open list:OPEN FIRMWARE AND...,
DOCUMENTATION, linux-mmc
On Mon, 2013-12-16 at 12:58 +0100, Lars-Peter Clausen wrote:
> Btw. any driver that parses the dmas property manually should be considered
> broken. This is a classical layering violation. The layout of the dma
> specifier is DMA controller specific and should be completely transparent to
> the device driver.
PXA as a whole is broken in this respect at the moment. The problem is
how to move to a "fixed" state without breaking things which work now.
^ permalink raw reply [flat|nested] 148+ messages in thread
* [PATCH v3 01/21 resend] serial: rewrite pxa2xx-uart to use 8250_core
[not found] ` <1387309071-22382-1-git-send-email-ynvich@gmail.com>
@ 2013-12-17 19:37 ` Sergei Ianovich
2013-12-18 23:55 ` Greg Kroah-Hartman
2013-12-19 8:51 ` Heikki Krogerus
2013-12-17 19:37 ` [PATCH v3 02/21] ARM: dts: pxa2xx fix compatible strings Sergei Ianovich
` (15 subsequent siblings)
16 siblings, 2 replies; 148+ messages in thread
From: Sergei Ianovich @ 2013-12-17 19:37 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel
Cc: Sergei Ianovich, Greg Kroah-Hartman, Russell King, Jiri Slaby,
Grant Likely, Rob Herring, Heikki Krogerus, James Cameron,
Zhou Zhu, Haojian Zhuang, Arnd Bergmann, open list:SERIAL DRIVERS,
open list:OPEN FIRMWARE AND...
pxa2xx-uart was a separate uart platform driver. It was declaring
the same device names and numbers as 8250 driver. As a result,
it was impossible to use 8250 driver on PXA SoCs.
Upon closer examination pxa2xx-uart turned out to be a clone of
8250_core driver.
Workaround for Erratum #19 according to Marvel(R) PXA270M Processor
Specification Update (April 19, 2010) is dropped. 8250_core reads
from FIFO immediately after checking DR bit in LSR.
Signed-off-by: Sergei Ianovich <ynvich@gmail.com>
Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Reviewed-by: James Cameron <quozl@laptop.org>
CC: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
Resenging together with the rest of the series as the series
breaks with this one at [PATCH 12/21]
changes v2..v3
* remove devm_free/put as suggested by Heikki Krogerus
* use SET_SYSTEM_SLEEP_PM_OPS macro to set pm ops as suggested
by Heikki Krogerus
changes v1..v2
* actually implement workaround for E74 in dl_write as spooted
by James Cameron
* added comment about E19 in commit message
arch/arm/configs/am200epdkit_defconfig | 3 +-
arch/arm/configs/cm_x2xx_defconfig | 3 +-
arch/arm/configs/cm_x300_defconfig | 3 +-
arch/arm/configs/colibri_pxa270_defconfig | 3 +-
arch/arm/configs/colibri_pxa300_defconfig | 3 +-
arch/arm/configs/corgi_defconfig | 4 +-
arch/arm/configs/em_x270_defconfig | 3 +-
arch/arm/configs/ezx_defconfig | 3 +-
arch/arm/configs/h5000_defconfig | 3 +-
arch/arm/configs/imote2_defconfig | 3 +-
arch/arm/configs/lpd270_defconfig | 3 +-
arch/arm/configs/lubbock_defconfig | 3 +-
arch/arm/configs/mainstone_defconfig | 3 +-
arch/arm/configs/mmp2_defconfig | 3 +-
arch/arm/configs/pcm027_defconfig | 3 +-
arch/arm/configs/pxa168_defconfig | 3 +-
arch/arm/configs/pxa255-idp_defconfig | 3 +-
arch/arm/configs/pxa3xx_defconfig | 3 +-
arch/arm/configs/pxa910_defconfig | 3 +-
arch/arm/configs/raumfeld_defconfig | 3 +-
arch/arm/configs/spitz_defconfig | 4 +-
arch/arm/configs/trizeps4_defconfig | 3 +-
arch/arm/configs/viper_defconfig | 4 +-
arch/arm/configs/xcep_defconfig | 3 +-
drivers/tty/serial/8250/8250_pxa.c | 178 ++++++
drivers/tty/serial/8250/Kconfig | 9 +
drivers/tty/serial/8250/Makefile | 1 +
drivers/tty/serial/Kconfig | 23 -
drivers/tty/serial/Makefile | 1 -
drivers/tty/serial/pxa.c | 971 ------------------------------
30 files changed, 236 insertions(+), 1022 deletions(-)
create mode 100644 drivers/tty/serial/8250/8250_pxa.c
delete mode 100644 drivers/tty/serial/pxa.c
diff --git a/arch/arm/configs/am200epdkit_defconfig b/arch/arm/configs/am200epdkit_defconfig
index f0dea52..0cde234 100644
--- a/arch/arm/configs/am200epdkit_defconfig
+++ b/arch/arm/configs/am200epdkit_defconfig
@@ -60,8 +60,9 @@ CONFIG_BLK_DEV_IDECS=m
CONFIG_NETDEVICES=y
CONFIG_NET_ETHERNET=y
CONFIG_SMC91X=m
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_PXA=y
-CONFIG_SERIAL_PXA_CONSOLE=y
# CONFIG_LEGACY_PTYS is not set
# CONFIG_HW_RANDOM is not set
# CONFIG_HWMON is not set
diff --git a/arch/arm/configs/cm_x2xx_defconfig b/arch/arm/configs/cm_x2xx_defconfig
index a93ff8d..b9fbe65 100644
--- a/arch/arm/configs/cm_x2xx_defconfig
+++ b/arch/arm/configs/cm_x2xx_defconfig
@@ -96,8 +96,9 @@ CONFIG_KEYBOARD_PXA27x=m
CONFIG_INPUT_TOUCHSCREEN=y
CONFIG_TOUCHSCREEN_UCB1400=m
# CONFIG_SERIO_SERPORT is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_PXA=y
-CONFIG_SERIAL_PXA_CONSOLE=y
CONFIG_LEGACY_PTY_COUNT=16
# CONFIG_HW_RANDOM is not set
CONFIG_I2C=y
diff --git a/arch/arm/configs/cm_x300_defconfig b/arch/arm/configs/cm_x300_defconfig
index f4b7672..53a82ae 100644
--- a/arch/arm/configs/cm_x300_defconfig
+++ b/arch/arm/configs/cm_x300_defconfig
@@ -80,8 +80,9 @@ CONFIG_TOUCHSCREEN_WM97XX=m
# CONFIG_TOUCHSCREEN_WM9713 is not set
# CONFIG_SERIO is not set
# CONFIG_LEGACY_PTYS is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_PXA=y
-CONFIG_SERIAL_PXA_CONSOLE=y
# CONFIG_HW_RANDOM is not set
CONFIG_I2C=y
CONFIG_I2C_PXA=y
diff --git a/arch/arm/configs/colibri_pxa270_defconfig b/arch/arm/configs/colibri_pxa270_defconfig
index 2ef2c5e..1ce0409 100644
--- a/arch/arm/configs/colibri_pxa270_defconfig
+++ b/arch/arm/configs/colibri_pxa270_defconfig
@@ -103,8 +103,9 @@ CONFIG_INPUT_TOUCHSCREEN=y
CONFIG_INPUT_MISC=y
CONFIG_INPUT_UINPUT=m
CONFIG_SERIO_LIBPS2=y
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_PXA=y
-CONFIG_SERIAL_PXA_CONSOLE=y
CONFIG_HW_RANDOM=y
CONFIG_I2C=y
CONFIG_I2C_CHARDEV=y
diff --git a/arch/arm/configs/colibri_pxa300_defconfig b/arch/arm/configs/colibri_pxa300_defconfig
index b985334..f96bda0 100644
--- a/arch/arm/configs/colibri_pxa300_defconfig
+++ b/arch/arm/configs/colibri_pxa300_defconfig
@@ -31,8 +31,9 @@ CONFIG_INPUT_EVDEV=y
# CONFIG_INPUT_MOUSE is not set
CONFIG_INPUT_MISC=y
CONFIG_INPUT_GPIO_ROTARY_ENCODER=y
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_PXA=y
-CONFIG_SERIAL_PXA_CONSOLE=y
CONFIG_HW_RANDOM=y
CONFIG_DEBUG_GPIO=y
# CONFIG_HWMON is not set
diff --git a/arch/arm/configs/corgi_defconfig b/arch/arm/configs/corgi_defconfig
index 1fd1d1d..bb4842d 100644
--- a/arch/arm/configs/corgi_defconfig
+++ b/arch/arm/configs/corgi_defconfig
@@ -131,10 +131,10 @@ CONFIG_TOUCHSCREEN_ADS7846=y
CONFIG_INPUT_MISC=y
CONFIG_INPUT_UINPUT=m
# CONFIG_SERIO is not set
-CONFIG_SERIAL_8250=m
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_CS=m
CONFIG_SERIAL_PXA=y
-CONFIG_SERIAL_PXA_CONSOLE=y
# CONFIG_LEGACY_PTYS is not set
CONFIG_I2C=y
CONFIG_I2C_PXA=y
diff --git a/arch/arm/configs/em_x270_defconfig b/arch/arm/configs/em_x270_defconfig
index 60a21e0..ec0ec54 100644
--- a/arch/arm/configs/em_x270_defconfig
+++ b/arch/arm/configs/em_x270_defconfig
@@ -90,8 +90,9 @@ CONFIG_TOUCHSCREEN_WM97XX=m
# CONFIG_TOUCHSCREEN_WM9705 is not set
# CONFIG_TOUCHSCREEN_WM9713 is not set
# CONFIG_SERIO_SERPORT is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_PXA=y
-CONFIG_SERIAL_PXA_CONSOLE=y
CONFIG_LEGACY_PTY_COUNT=16
# CONFIG_HW_RANDOM is not set
CONFIG_I2C=y
diff --git a/arch/arm/configs/ezx_defconfig b/arch/arm/configs/ezx_defconfig
index d95763d..631e2ec 100644
--- a/arch/arm/configs/ezx_defconfig
+++ b/arch/arm/configs/ezx_defconfig
@@ -215,8 +215,9 @@ CONFIG_INPUT_MISC=y
CONFIG_INPUT_UINPUT=y
CONFIG_INPUT_PCAP=y
# CONFIG_SERIO is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_PXA=y
-CONFIG_SERIAL_PXA_CONSOLE=y
CONFIG_LEGACY_PTY_COUNT=8
# CONFIG_HW_RANDOM is not set
CONFIG_I2C=y
diff --git a/arch/arm/configs/h5000_defconfig b/arch/arm/configs/h5000_defconfig
index 37903e3..655b735 100644
--- a/arch/arm/configs/h5000_defconfig
+++ b/arch/arm/configs/h5000_defconfig
@@ -47,8 +47,9 @@ CONFIG_MTD_PHYSMAP=y
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not set
# CONFIG_SERIO is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_PXA=y
-CONFIG_SERIAL_PXA_CONSOLE=y
CONFIG_LEGACY_PTY_COUNT=32
# CONFIG_HW_RANDOM is not set
# CONFIG_HWMON is not set
diff --git a/arch/arm/configs/imote2_defconfig b/arch/arm/configs/imote2_defconfig
index fd996bb..49d45e9 100644
--- a/arch/arm/configs/imote2_defconfig
+++ b/arch/arm/configs/imote2_defconfig
@@ -193,8 +193,9 @@ CONFIG_INPUT_TOUCHSCREEN=y
CONFIG_INPUT_MISC=y
CONFIG_INPUT_UINPUT=y
# CONFIG_SERIO is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_PXA=y
-CONFIG_SERIAL_PXA_CONSOLE=y
CONFIG_LEGACY_PTY_COUNT=8
# CONFIG_HW_RANDOM is not set
CONFIG_I2C=y
diff --git a/arch/arm/configs/lpd270_defconfig b/arch/arm/configs/lpd270_defconfig
index 1c8c9ee..c3927b6 100644
--- a/arch/arm/configs/lpd270_defconfig
+++ b/arch/arm/configs/lpd270_defconfig
@@ -38,8 +38,9 @@ CONFIG_SMC91X=y
CONFIG_INPUT_EVDEV=y
# CONFIG_INPUT_MOUSE is not set
# CONFIG_SERIO_SERPORT is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_PXA=y
-CONFIG_SERIAL_PXA_CONSOLE=y
# CONFIG_HW_RANDOM is not set
CONFIG_FB=y
CONFIG_FB_PXA=y
diff --git a/arch/arm/configs/lubbock_defconfig b/arch/arm/configs/lubbock_defconfig
index c4ba274..c8b0436 100644
--- a/arch/arm/configs/lubbock_defconfig
+++ b/arch/arm/configs/lubbock_defconfig
@@ -37,8 +37,9 @@ CONFIG_PCMCIA_PCNET=y
CONFIG_INPUT_EVDEV=y
# CONFIG_SERIO_SERPORT is not set
CONFIG_SERIO_SA1111=y
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_PXA=y
-CONFIG_SERIAL_PXA_CONSOLE=y
# CONFIG_VGA_CONSOLE is not set
CONFIG_USB_GADGET=y
CONFIG_USB_G_SERIAL=m
diff --git a/arch/arm/configs/mainstone_defconfig b/arch/arm/configs/mainstone_defconfig
index 04efa1b..768892c 100644
--- a/arch/arm/configs/mainstone_defconfig
+++ b/arch/arm/configs/mainstone_defconfig
@@ -34,8 +34,9 @@ CONFIG_SMC91X=y
CONFIG_INPUT_EVDEV=y
# CONFIG_INPUT_MOUSE is not set
# CONFIG_SERIO_SERPORT is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_PXA=y
-CONFIG_SERIAL_PXA_CONSOLE=y
CONFIG_FB=y
CONFIG_FB_PXA=y
# CONFIG_VGA_CONSOLE is not set
diff --git a/arch/arm/configs/mmp2_defconfig b/arch/arm/configs/mmp2_defconfig
index f1cb95e..1ced9df 100644
--- a/arch/arm/configs/mmp2_defconfig
+++ b/arch/arm/configs/mmp2_defconfig
@@ -44,8 +44,9 @@ CONFIG_SMC91X=y
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not set
# CONFIG_SERIO is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_PXA=y
-CONFIG_SERIAL_PXA_CONSOLE=y
# CONFIG_LEGACY_PTYS is not set
# CONFIG_HW_RANDOM is not set
CONFIG_I2C=y
diff --git a/arch/arm/configs/pcm027_defconfig b/arch/arm/configs/pcm027_defconfig
index 2f136c3..1280128 100644
--- a/arch/arm/configs/pcm027_defconfig
+++ b/arch/arm/configs/pcm027_defconfig
@@ -60,8 +60,9 @@ CONFIG_SMC91X=y
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not set
# CONFIG_SERIO is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_PXA=y
-CONFIG_SERIAL_PXA_CONSOLE=y
# CONFIG_LEGACY_PTYS is not set
# CONFIG_HW_RANDOM is not set
CONFIG_I2C=y
diff --git a/arch/arm/configs/pxa168_defconfig b/arch/arm/configs/pxa168_defconfig
index 74d7e01..1668dac 100644
--- a/arch/arm/configs/pxa168_defconfig
+++ b/arch/arm/configs/pxa168_defconfig
@@ -40,8 +40,9 @@ CONFIG_SMC91X=y
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not set
# CONFIG_SERIO is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_PXA=y
-CONFIG_SERIAL_PXA_CONSOLE=y
# CONFIG_LEGACY_PTYS is not set
# CONFIG_HW_RANDOM is not set
# CONFIG_HWMON is not set
diff --git a/arch/arm/configs/pxa255-idp_defconfig b/arch/arm/configs/pxa255-idp_defconfig
index 917a070..399a706 100644
--- a/arch/arm/configs/pxa255-idp_defconfig
+++ b/arch/arm/configs/pxa255-idp_defconfig
@@ -35,8 +35,9 @@ CONFIG_SMC91X=y
CONFIG_INPUT_EVDEV=y
# CONFIG_INPUT_MOUSE is not set
# CONFIG_SERIO_SERPORT is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_PXA=y
-CONFIG_SERIAL_PXA_CONSOLE=y
CONFIG_FB=y
CONFIG_FB_PXA=y
# CONFIG_VGA_CONSOLE is not set
diff --git a/arch/arm/configs/pxa3xx_defconfig b/arch/arm/configs/pxa3xx_defconfig
index 60e3138..7c3e052 100644
--- a/arch/arm/configs/pxa3xx_defconfig
+++ b/arch/arm/configs/pxa3xx_defconfig
@@ -56,8 +56,9 @@ CONFIG_KEYBOARD_PXA27x=y
CONFIG_KEYBOARD_PXA930_ROTARY=y
CONFIG_MOUSE_PXA930_TRKBALL=y
CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_PXA=y
-CONFIG_SERIAL_PXA_CONSOLE=y
# CONFIG_LEGACY_PTYS is not set
# CONFIG_HW_RANDOM is not set
CONFIG_I2C=y
diff --git a/arch/arm/configs/pxa910_defconfig b/arch/arm/configs/pxa910_defconfig
index 3bb7771..cdacfcb 100644
--- a/arch/arm/configs/pxa910_defconfig
+++ b/arch/arm/configs/pxa910_defconfig
@@ -40,8 +40,9 @@ CONFIG_SMC91X=y
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not set
# CONFIG_SERIO is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_PXA=y
-CONFIG_SERIAL_PXA_CONSOLE=y
CONFIG_SPI=y
CONFIG_FB=y
CONFIG_MMP_DISP=y
diff --git a/arch/arm/configs/raumfeld_defconfig b/arch/arm/configs/raumfeld_defconfig
index f7caa90..f1e16f2 100644
--- a/arch/arm/configs/raumfeld_defconfig
+++ b/arch/arm/configs/raumfeld_defconfig
@@ -67,8 +67,9 @@ CONFIG_INPUT_TOUCHSCREEN=y
CONFIG_TOUCHSCREEN_EETI=m
CONFIG_INPUT_MISC=y
CONFIG_INPUT_GPIO_ROTARY_ENCODER=y
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_PXA=y
-CONFIG_SERIAL_PXA_CONSOLE=y
CONFIG_HW_RANDOM=y
CONFIG_I2C=y
CONFIG_I2C_CHARDEV=y
diff --git a/arch/arm/configs/spitz_defconfig b/arch/arm/configs/spitz_defconfig
index 2e0419d..b6efcf5 100644
--- a/arch/arm/configs/spitz_defconfig
+++ b/arch/arm/configs/spitz_defconfig
@@ -128,10 +128,10 @@ CONFIG_TOUCHSCREEN_ADS7846=y
CONFIG_INPUT_MISC=y
CONFIG_INPUT_UINPUT=m
# CONFIG_SERIO is not set
-CONFIG_SERIAL_8250=m
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_CS=m
CONFIG_SERIAL_PXA=y
-CONFIG_SERIAL_PXA_CONSOLE=y
# CONFIG_LEGACY_PTYS is not set
CONFIG_SPI=y
CONFIG_SPI_PXA2XX=y
diff --git a/arch/arm/configs/trizeps4_defconfig b/arch/arm/configs/trizeps4_defconfig
index 3162173..453c79c 100644
--- a/arch/arm/configs/trizeps4_defconfig
+++ b/arch/arm/configs/trizeps4_defconfig
@@ -132,8 +132,9 @@ CONFIG_INPUT_TOUCHSCREEN=y
CONFIG_INPUT_MISC=y
CONFIG_INPUT_UINPUT=m
CONFIG_SERIO_LIBPS2=y
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_PXA=y
-CONFIG_SERIAL_PXA_CONSOLE=y
CONFIG_HW_RANDOM=y
CONFIG_I2C=y
CONFIG_I2C_CHARDEV=y
diff --git a/arch/arm/configs/viper_defconfig b/arch/arm/configs/viper_defconfig
index d36e0d3..4efac06 100644
--- a/arch/arm/configs/viper_defconfig
+++ b/arch/arm/configs/viper_defconfig
@@ -101,11 +101,11 @@ CONFIG_INPUT_MISC=y
CONFIG_INPUT_UINPUT=m
# CONFIG_CONSOLE_TRANSLATIONS is not set
# CONFIG_VT_CONSOLE is not set
-CONFIG_SERIAL_8250=m
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_NR_UARTS=5
CONFIG_SERIAL_8250_RUNTIME_UARTS=5
CONFIG_SERIAL_PXA=y
-CONFIG_SERIAL_PXA_CONSOLE=y
# CONFIG_LEGACY_PTYS is not set
CONFIG_I2C=y
CONFIG_I2C_CHARDEV=y
diff --git a/arch/arm/configs/xcep_defconfig b/arch/arm/configs/xcep_defconfig
index 721832f..b67aeaf 100644
--- a/arch/arm/configs/xcep_defconfig
+++ b/arch/arm/configs/xcep_defconfig
@@ -60,8 +60,9 @@ CONFIG_NET_ETHERNET=y
# CONFIG_INPUT_MOUSE is not set
# CONFIG_SERIO is not set
# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_PXA=y
-CONFIG_SERIAL_PXA_CONSOLE=y
# CONFIG_LEGACY_PTYS is not set
# CONFIG_HW_RANDOM is not set
CONFIG_I2C=m
diff --git a/drivers/tty/serial/8250/8250_pxa.c b/drivers/tty/serial/8250/8250_pxa.c
new file mode 100644
index 0000000..0da0d40
--- /dev/null
+++ b/drivers/tty/serial/8250/8250_pxa.c
@@ -0,0 +1,178 @@
+/*
+ * drivers/tty/serial/8250/8250_pxa.c -- driver for PXA on-board UARTS
+ * Copyright: (C) 2013 Sergei Ianovich <ynvich@gmail.com>
+ *
+ * replaces drivers/serial/pxa.c by Nicolas Pitre
+ * Created: Feb 20, 2003
+ * Copyright: (C) 2003 Monta Vista Software, Inc.
+ *
+ * Based on drivers/serial/8250.c by Russell King.
+ *
+ * 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 <linux/device.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/serial_8250.h>
+#include <linux/serial_core.h>
+#include <linux/serial_reg.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/clk.h>
+#include <linux/pm_runtime.h>
+
+#include "8250.h"
+
+struct pxa8250_data {
+ int line;
+ struct clk *clk;
+};
+
+#ifdef CONFIG_PM
+static int serial_pxa_suspend(struct device *dev)
+{
+ struct pxa8250_data *data = dev_get_drvdata(dev);
+
+ serial8250_suspend_port(data->line);
+
+ return 0;
+}
+
+static int serial_pxa_resume(struct device *dev)
+{
+ struct pxa8250_data *data = dev_get_drvdata(dev);
+
+ serial8250_resume_port(data->line);
+
+ return 0;
+}
+#endif
+
+static const struct dev_pm_ops serial_pxa_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(serial_pxa_suspend, serial_pxa_resume)
+};
+
+static struct of_device_id serial_pxa_dt_ids[] = {
+ { .compatible = "mrvl,pxa-uart", },
+ { .compatible = "mrvl,mmp-uart", },
+ {}
+};
+MODULE_DEVICE_TABLE(of, serial_pxa_dt_ids);
+
+/* Uart divisor latch write */
+static void serial_pxa_dl_write(struct uart_8250_port *up, int value)
+{
+ unsigned int dll;
+
+ serial_out(up, UART_DLL, value & 0xff);
+ /*
+ * work around Erratum #74 according to Marvel(R) PXA270M Processor
+ * Specification Update (April 19, 2010)
+ */
+ dll = serial_in(up, UART_DLL);
+ WARN_ON(dll != (value & 0xff));
+
+ serial_out(up, UART_DLM, value >> 8 & 0xff);
+}
+
+
+static void serial_pxa_pm(struct uart_port *port, unsigned int state,
+ unsigned int oldstate)
+{
+ struct pxa8250_data *data = port->private_data;
+
+ if (!state)
+ clk_prepare_enable(data->clk);
+ else
+ clk_disable_unprepare(data->clk);
+}
+
+static int serial_pxa_probe(struct platform_device *pdev)
+{
+ struct uart_8250_port uart = {};
+ struct pxa8250_data *data;
+ struct resource *mmres, *irqres;
+ int ret;
+
+ mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ irqres = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (!mmres || !irqres)
+ return -ENODEV;
+
+ data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ data->clk = devm_clk_get(&pdev->dev, NULL);
+ if (IS_ERR(data->clk))
+ return PTR_ERR(data->clk);
+
+ ret = clk_prepare(data->clk);
+ if (ret)
+ return ret;
+
+ uart.port.type = PORT_XSCALE;
+ uart.port.iotype = UPIO_MEM32;
+ uart.port.mapbase = mmres->start;
+ uart.port.regshift = 2;
+ uart.port.irq = irqres->start;
+ uart.port.fifosize = 64;
+ uart.port.flags = UPF_IOREMAP | UPF_SKIP_TEST;
+ uart.port.dev = &pdev->dev;
+ uart.port.uartclk = clk_get_rate(data->clk);
+ uart.port.pm = serial_pxa_pm;
+ uart.port.private_data = data;
+ uart.dl_write = serial_pxa_dl_write;
+
+ ret = serial8250_register_8250_port(&uart);
+ if (ret < 0)
+ goto err_clk;
+
+ data->line = ret;
+
+ platform_set_drvdata(pdev, data);
+
+ return 0;
+
+ err_clk:
+ clk_unprepare(data->clk);
+ return ret;
+}
+
+static int serial_pxa_remove(struct platform_device *pdev)
+{
+ struct pxa8250_data *data = platform_get_drvdata(pdev);
+
+ serial8250_unregister_port(data->line);
+
+ clk_unprepare(data->clk);
+
+ return 0;
+}
+
+static struct platform_driver serial_pxa_driver = {
+ .probe = serial_pxa_probe,
+ .remove = serial_pxa_remove,
+
+ .driver = {
+ .name = "pxa2xx-uart",
+ .owner = THIS_MODULE,
+ .pm = &serial_pxa_pm_ops,
+ .of_match_table = serial_pxa_dt_ids,
+ },
+};
+
+module_platform_driver(serial_pxa_driver);
+
+MODULE_AUTHOR("Sergei Ianovich");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:pxa2xx-uart");
diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig
index 2332991..81bd7c9 100644
--- a/drivers/tty/serial/8250/Kconfig
+++ b/drivers/tty/serial/8250/Kconfig
@@ -302,3 +302,12 @@ config SERIAL_8250_RT288X
If you have a Ralink RT288x/RT305x SoC based board and want to use the
serial port, say Y to this option. The driver can handle up to 2 serial
ports. If unsure, say N.
+
+config SERIAL_PXA
+ tristate "PXA serial port support"
+ depends on SERIAL_8250 && (ARCH_PXA || ARCH_MMP)
+ help
+ If you have a machine based on an Intel XScale PXA2xx CPU you
+ can enable its onboard serial ports by enabling this option.
+
+ If you choose M here, the module name will be 8250_pxa.
diff --git a/drivers/tty/serial/8250/Makefile b/drivers/tty/serial/8250/Makefile
index 36d68d0..b7d1b61 100644
--- a/drivers/tty/serial/8250/Makefile
+++ b/drivers/tty/serial/8250/Makefile
@@ -20,3 +20,4 @@ obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o
obj-$(CONFIG_SERIAL_8250_FSL) += 8250_fsl.o
obj-$(CONFIG_SERIAL_8250_DW) += 8250_dw.o
obj-$(CONFIG_SERIAL_8250_EM) += 8250_em.o
+obj-$(CONFIG_SERIAL_PXA) += 8250_pxa.o
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index a3817ab..2ad7184b 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -396,29 +396,6 @@ config SERIAL_MPSC_CONSOLE
help
Say Y here if you want to support a serial console on a Marvell MPSC.
-config SERIAL_PXA
- bool "PXA serial port support"
- depends on ARCH_PXA || ARCH_MMP
- select SERIAL_CORE
- help
- If you have a machine based on an Intel XScale PXA2xx CPU you
- can enable its onboard serial ports by enabling this option.
-
-config SERIAL_PXA_CONSOLE
- bool "Console on PXA serial port"
- depends on SERIAL_PXA
- select SERIAL_CORE_CONSOLE
- help
- If you have enabled the serial port on the Intel XScale PXA
- CPU you can make it the console by answering Y to this option.
-
- Even if you say Y here, the currently visible virtual console
- (/dev/tty0) will still be used as the system console by default, but
- you can alter that using a kernel command line option such as
- "console=ttySA0". (Try "man bootparam" or see the documentation of
- your boot loader (lilo or loadlin) about how to pass options to the
- kernel at boot time.)
-
config SERIAL_SA1100
bool "SA1100 serial port support"
depends on ARCH_SA1100
diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile
index 3068c77..4ac337b 100644
--- a/drivers/tty/serial/Makefile
+++ b/drivers/tty/serial/Makefile
@@ -20,7 +20,6 @@ obj-$(CONFIG_SERIAL_8250) += 8250/
obj-$(CONFIG_SERIAL_AMBA_PL010) += amba-pl010.o
obj-$(CONFIG_SERIAL_AMBA_PL011) += amba-pl011.o
obj-$(CONFIG_SERIAL_CLPS711X) += clps711x.o
-obj-$(CONFIG_SERIAL_PXA) += pxa.o
obj-$(CONFIG_SERIAL_PNX8XXX) += pnx8xxx_uart.o
obj-$(CONFIG_SERIAL_SA1100) += sa1100.o
obj-$(CONFIG_SERIAL_BCM63XX) += bcm63xx_uart.o
diff --git a/drivers/tty/serial/pxa.c b/drivers/tty/serial/pxa.c
deleted file mode 100644
index f9f20f3..0000000
--- a/drivers/tty/serial/pxa.c
+++ /dev/null
@@ -1,971 +0,0 @@
-/*
- * Based on drivers/serial/8250.c by Russell King.
- *
- * Author: Nicolas Pitre
- * Created: Feb 20, 2003
- * Copyright: (C) 2003 Monta Vista Software, Inc.
- *
- * 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.
- *
- * Note 1: This driver is made separate from the already too overloaded
- * 8250.c because it needs some kirks of its own and that'll make it
- * easier to add DMA support.
- *
- * Note 2: I'm too sick of device allocation policies for serial ports.
- * If someone else wants to request an "official" allocation of major/minor
- * for this driver please be my guest. And don't forget that new hardware
- * to come from Intel might have more than 3 or 4 of those UARTs. Let's
- * hope for a better port registration and dynamic device allocation scheme
- * with the serial core maintainer satisfaction to appear soon.
- */
-
-
-#if defined(CONFIG_SERIAL_PXA_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
-#define SUPPORT_SYSRQ
-#endif
-
-#include <linux/module.h>
-#include <linux/ioport.h>
-#include <linux/init.h>
-#include <linux/console.h>
-#include <linux/sysrq.h>
-#include <linux/serial_reg.h>
-#include <linux/circ_buf.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/of.h>
-#include <linux/platform_device.h>
-#include <linux/tty.h>
-#include <linux/tty_flip.h>
-#include <linux/serial_core.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/slab.h>
-
-#define PXA_NAME_LEN 8
-
-struct uart_pxa_port {
- struct uart_port port;
- unsigned char ier;
- unsigned char lcr;
- unsigned char mcr;
- unsigned int lsr_break_flag;
- struct clk *clk;
- char name[PXA_NAME_LEN];
-};
-
-static inline unsigned int serial_in(struct uart_pxa_port *up, int offset)
-{
- offset <<= 2;
- return readl(up->port.membase + offset);
-}
-
-static inline void serial_out(struct uart_pxa_port *up, int offset, int value)
-{
- offset <<= 2;
- writel(value, up->port.membase + offset);
-}
-
-static void serial_pxa_enable_ms(struct uart_port *port)
-{
- struct uart_pxa_port *up = (struct uart_pxa_port *)port;
-
- up->ier |= UART_IER_MSI;
- serial_out(up, UART_IER, up->ier);
-}
-
-static void serial_pxa_stop_tx(struct uart_port *port)
-{
- struct uart_pxa_port *up = (struct uart_pxa_port *)port;
-
- if (up->ier & UART_IER_THRI) {
- up->ier &= ~UART_IER_THRI;
- serial_out(up, UART_IER, up->ier);
- }
-}
-
-static void serial_pxa_stop_rx(struct uart_port *port)
-{
- struct uart_pxa_port *up = (struct uart_pxa_port *)port;
-
- up->ier &= ~UART_IER_RLSI;
- up->port.read_status_mask &= ~UART_LSR_DR;
- serial_out(up, UART_IER, up->ier);
-}
-
-static inline void receive_chars(struct uart_pxa_port *up, int *status)
-{
- unsigned int ch, flag;
- int max_count = 256;
-
- do {
- /* work around Errata #20 according to
- * Intel(R) PXA27x Processor Family
- * Specification Update (May 2005)
- *
- * Step 2
- * Disable the Reciever Time Out Interrupt via IER[RTOEI]
- */
- up->ier &= ~UART_IER_RTOIE;
- serial_out(up, UART_IER, up->ier);
-
- ch = serial_in(up, UART_RX);
- flag = TTY_NORMAL;
- up->port.icount.rx++;
-
- if (unlikely(*status & (UART_LSR_BI | UART_LSR_PE |
- UART_LSR_FE | UART_LSR_OE))) {
- /*
- * For statistics only
- */
- if (*status & UART_LSR_BI) {
- *status &= ~(UART_LSR_FE | UART_LSR_PE);
- up->port.icount.brk++;
- /*
- * We do the SysRQ and SAK checking
- * here because otherwise the break
- * may get masked by ignore_status_mask
- * or read_status_mask.
- */
- if (uart_handle_break(&up->port))
- goto ignore_char;
- } else if (*status & UART_LSR_PE)
- up->port.icount.parity++;
- else if (*status & UART_LSR_FE)
- up->port.icount.frame++;
- if (*status & UART_LSR_OE)
- up->port.icount.overrun++;
-
- /*
- * Mask off conditions which should be ignored.
- */
- *status &= up->port.read_status_mask;
-
-#ifdef CONFIG_SERIAL_PXA_CONSOLE
- if (up->port.line == up->port.cons->index) {
- /* Recover the break flag from console xmit */
- *status |= up->lsr_break_flag;
- up->lsr_break_flag = 0;
- }
-#endif
- if (*status & UART_LSR_BI) {
- flag = TTY_BREAK;
- } else if (*status & UART_LSR_PE)
- flag = TTY_PARITY;
- else if (*status & UART_LSR_FE)
- flag = TTY_FRAME;
- }
-
- if (uart_handle_sysrq_char(&up->port, ch))
- goto ignore_char;
-
- uart_insert_char(&up->port, *status, UART_LSR_OE, ch, flag);
-
- ignore_char:
- *status = serial_in(up, UART_LSR);
- } while ((*status & UART_LSR_DR) && (max_count-- > 0));
- tty_flip_buffer_push(&up->port.state->port);
-
- /* work around Errata #20 according to
- * Intel(R) PXA27x Processor Family
- * Specification Update (May 2005)
- *
- * Step 6:
- * No more data in FIFO: Re-enable RTO interrupt via IER[RTOIE]
- */
- up->ier |= UART_IER_RTOIE;
- serial_out(up, UART_IER, up->ier);
-}
-
-static void transmit_chars(struct uart_pxa_port *up)
-{
- struct circ_buf *xmit = &up->port.state->xmit;
- int count;
-
- if (up->port.x_char) {
- serial_out(up, UART_TX, up->port.x_char);
- up->port.icount.tx++;
- up->port.x_char = 0;
- return;
- }
- if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) {
- serial_pxa_stop_tx(&up->port);
- return;
- }
-
- count = up->port.fifosize / 2;
- do {
- serial_out(up, UART_TX, xmit->buf[xmit->tail]);
- xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
- up->port.icount.tx++;
- if (uart_circ_empty(xmit))
- break;
- } while (--count > 0);
-
- if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
- uart_write_wakeup(&up->port);
-
-
- if (uart_circ_empty(xmit))
- serial_pxa_stop_tx(&up->port);
-}
-
-static void serial_pxa_start_tx(struct uart_port *port)
-{
- struct uart_pxa_port *up = (struct uart_pxa_port *)port;
-
- if (!(up->ier & UART_IER_THRI)) {
- up->ier |= UART_IER_THRI;
- serial_out(up, UART_IER, up->ier);
- }
-}
-
-static inline void check_modem_status(struct uart_pxa_port *up)
-{
- int status;
-
- status = serial_in(up, UART_MSR);
-
- if ((status & UART_MSR_ANY_DELTA) == 0)
- return;
-
- if (status & UART_MSR_TERI)
- up->port.icount.rng++;
- if (status & UART_MSR_DDSR)
- up->port.icount.dsr++;
- if (status & UART_MSR_DDCD)
- uart_handle_dcd_change(&up->port, status & UART_MSR_DCD);
- if (status & UART_MSR_DCTS)
- uart_handle_cts_change(&up->port, status & UART_MSR_CTS);
-
- wake_up_interruptible(&up->port.state->port.delta_msr_wait);
-}
-
-/*
- * This handles the interrupt from one port.
- */
-static inline irqreturn_t serial_pxa_irq(int irq, void *dev_id)
-{
- struct uart_pxa_port *up = dev_id;
- unsigned int iir, lsr;
-
- iir = serial_in(up, UART_IIR);
- if (iir & UART_IIR_NO_INT)
- return IRQ_NONE;
- lsr = serial_in(up, UART_LSR);
- if (lsr & UART_LSR_DR)
- receive_chars(up, &lsr);
- check_modem_status(up);
- if (lsr & UART_LSR_THRE)
- transmit_chars(up);
- return IRQ_HANDLED;
-}
-
-static unsigned int serial_pxa_tx_empty(struct uart_port *port)
-{
- struct uart_pxa_port *up = (struct uart_pxa_port *)port;
- unsigned long flags;
- unsigned int ret;
-
- spin_lock_irqsave(&up->port.lock, flags);
- ret = serial_in(up, UART_LSR) & UART_LSR_TEMT ? TIOCSER_TEMT : 0;
- spin_unlock_irqrestore(&up->port.lock, flags);
-
- return ret;
-}
-
-static unsigned int serial_pxa_get_mctrl(struct uart_port *port)
-{
- struct uart_pxa_port *up = (struct uart_pxa_port *)port;
- unsigned char status;
- unsigned int ret;
-
- status = serial_in(up, UART_MSR);
-
- ret = 0;
- if (status & UART_MSR_DCD)
- ret |= TIOCM_CAR;
- if (status & UART_MSR_RI)
- ret |= TIOCM_RNG;
- if (status & UART_MSR_DSR)
- ret |= TIOCM_DSR;
- if (status & UART_MSR_CTS)
- ret |= TIOCM_CTS;
- return ret;
-}
-
-static void serial_pxa_set_mctrl(struct uart_port *port, unsigned int mctrl)
-{
- struct uart_pxa_port *up = (struct uart_pxa_port *)port;
- unsigned char mcr = 0;
-
- if (mctrl & TIOCM_RTS)
- mcr |= UART_MCR_RTS;
- if (mctrl & TIOCM_DTR)
- mcr |= UART_MCR_DTR;
- if (mctrl & TIOCM_OUT1)
- mcr |= UART_MCR_OUT1;
- if (mctrl & TIOCM_OUT2)
- mcr |= UART_MCR_OUT2;
- if (mctrl & TIOCM_LOOP)
- mcr |= UART_MCR_LOOP;
-
- mcr |= up->mcr;
-
- serial_out(up, UART_MCR, mcr);
-}
-
-static void serial_pxa_break_ctl(struct uart_port *port, int break_state)
-{
- struct uart_pxa_port *up = (struct uart_pxa_port *)port;
- unsigned long flags;
-
- spin_lock_irqsave(&up->port.lock, flags);
- if (break_state == -1)
- up->lcr |= UART_LCR_SBC;
- else
- up->lcr &= ~UART_LCR_SBC;
- serial_out(up, UART_LCR, up->lcr);
- spin_unlock_irqrestore(&up->port.lock, flags);
-}
-
-static int serial_pxa_startup(struct uart_port *port)
-{
- struct uart_pxa_port *up = (struct uart_pxa_port *)port;
- unsigned long flags;
- int retval;
-
- if (port->line == 3) /* HWUART */
- up->mcr |= UART_MCR_AFE;
- else
- up->mcr = 0;
-
- up->port.uartclk = clk_get_rate(up->clk);
-
- /*
- * Allocate the IRQ
- */
- retval = request_irq(up->port.irq, serial_pxa_irq, 0, up->name, up);
- if (retval)
- return retval;
-
- /*
- * Clear the FIFO buffers and disable them.
- * (they will be reenabled in set_termios())
- */
- serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO);
- serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO |
- UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
- serial_out(up, UART_FCR, 0);
-
- /*
- * Clear the interrupt registers.
- */
- (void) serial_in(up, UART_LSR);
- (void) serial_in(up, UART_RX);
- (void) serial_in(up, UART_IIR);
- (void) serial_in(up, UART_MSR);
-
- /*
- * Now, initialize the UART
- */
- serial_out(up, UART_LCR, UART_LCR_WLEN8);
-
- spin_lock_irqsave(&up->port.lock, flags);
- up->port.mctrl |= TIOCM_OUT2;
- serial_pxa_set_mctrl(&up->port, up->port.mctrl);
- spin_unlock_irqrestore(&up->port.lock, flags);
-
- /*
- * Finally, enable interrupts. Note: Modem status interrupts
- * are set via set_termios(), which will be occurring imminently
- * anyway, so we don't enable them here.
- */
- up->ier = UART_IER_RLSI | UART_IER_RDI | UART_IER_RTOIE | UART_IER_UUE;
- serial_out(up, UART_IER, up->ier);
-
- /*
- * And clear the interrupt registers again for luck.
- */
- (void) serial_in(up, UART_LSR);
- (void) serial_in(up, UART_RX);
- (void) serial_in(up, UART_IIR);
- (void) serial_in(up, UART_MSR);
-
- return 0;
-}
-
-static void serial_pxa_shutdown(struct uart_port *port)
-{
- struct uart_pxa_port *up = (struct uart_pxa_port *)port;
- unsigned long flags;
-
- free_irq(up->port.irq, up);
-
- /*
- * Disable interrupts from this port
- */
- up->ier = 0;
- serial_out(up, UART_IER, 0);
-
- spin_lock_irqsave(&up->port.lock, flags);
- up->port.mctrl &= ~TIOCM_OUT2;
- serial_pxa_set_mctrl(&up->port, up->port.mctrl);
- spin_unlock_irqrestore(&up->port.lock, flags);
-
- /*
- * Disable break condition and FIFOs
- */
- serial_out(up, UART_LCR, serial_in(up, UART_LCR) & ~UART_LCR_SBC);
- serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO |
- UART_FCR_CLEAR_RCVR |
- UART_FCR_CLEAR_XMIT);
- serial_out(up, UART_FCR, 0);
-}
-
-static void
-serial_pxa_set_termios(struct uart_port *port, struct ktermios *termios,
- struct ktermios *old)
-{
- struct uart_pxa_port *up = (struct uart_pxa_port *)port;
- unsigned char cval, fcr = 0;
- unsigned long flags;
- unsigned int baud, quot;
- unsigned int dll;
-
- switch (termios->c_cflag & CSIZE) {
- case CS5:
- cval = UART_LCR_WLEN5;
- break;
- case CS6:
- cval = UART_LCR_WLEN6;
- break;
- case CS7:
- cval = UART_LCR_WLEN7;
- break;
- default:
- case CS8:
- cval = UART_LCR_WLEN8;
- break;
- }
-
- if (termios->c_cflag & CSTOPB)
- cval |= UART_LCR_STOP;
- if (termios->c_cflag & PARENB)
- cval |= UART_LCR_PARITY;
- if (!(termios->c_cflag & PARODD))
- cval |= UART_LCR_EPAR;
-
- /*
- * Ask the core to calculate the divisor for us.
- */
- baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
- quot = uart_get_divisor(port, baud);
-
- if ((up->port.uartclk / quot) < (2400 * 16))
- fcr = UART_FCR_ENABLE_FIFO | UART_FCR_PXAR1;
- else if ((up->port.uartclk / quot) < (230400 * 16))
- fcr = UART_FCR_ENABLE_FIFO | UART_FCR_PXAR8;
- else
- fcr = UART_FCR_ENABLE_FIFO | UART_FCR_PXAR32;
-
- /*
- * Ok, we're now changing the port state. Do it with
- * interrupts disabled.
- */
- spin_lock_irqsave(&up->port.lock, flags);
-
- /*
- * Ensure the port will be enabled.
- * This is required especially for serial console.
- */
- up->ier |= UART_IER_UUE;
-
- /*
- * Update the per-port timeout.
- */
- uart_update_timeout(port, termios->c_cflag, baud);
-
- up->port.read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR;
- if (termios->c_iflag & INPCK)
- up->port.read_status_mask |= UART_LSR_FE | UART_LSR_PE;
- if (termios->c_iflag & (BRKINT | PARMRK))
- up->port.read_status_mask |= UART_LSR_BI;
-
- /*
- * Characters to ignore
- */
- up->port.ignore_status_mask = 0;
- if (termios->c_iflag & IGNPAR)
- up->port.ignore_status_mask |= UART_LSR_PE | UART_LSR_FE;
- if (termios->c_iflag & IGNBRK) {
- up->port.ignore_status_mask |= UART_LSR_BI;
- /*
- * If we're ignoring parity and break indicators,
- * ignore overruns too (for real raw support).
- */
- if (termios->c_iflag & IGNPAR)
- up->port.ignore_status_mask |= UART_LSR_OE;
- }
-
- /*
- * ignore all characters if CREAD is not set
- */
- if ((termios->c_cflag & CREAD) == 0)
- up->port.ignore_status_mask |= UART_LSR_DR;
-
- /*
- * CTS flow control flag and modem status interrupts
- */
- up->ier &= ~UART_IER_MSI;
- if (UART_ENABLE_MS(&up->port, termios->c_cflag))
- up->ier |= UART_IER_MSI;
-
- serial_out(up, UART_IER, up->ier);
-
- if (termios->c_cflag & CRTSCTS)
- up->mcr |= UART_MCR_AFE;
- else
- up->mcr &= ~UART_MCR_AFE;
-
- serial_out(up, UART_LCR, cval | UART_LCR_DLAB); /* set DLAB */
- serial_out(up, UART_DLL, quot & 0xff); /* LS of divisor */
-
- /*
- * work around Errata #75 according to Intel(R) PXA27x Processor Family
- * Specification Update (Nov 2005)
- */
- dll = serial_in(up, UART_DLL);
- WARN_ON(dll != (quot & 0xff));
-
- serial_out(up, UART_DLM, quot >> 8); /* MS of divisor */
- serial_out(up, UART_LCR, cval); /* reset DLAB */
- up->lcr = cval; /* Save LCR */
- serial_pxa_set_mctrl(&up->port, up->port.mctrl);
- serial_out(up, UART_FCR, fcr);
- spin_unlock_irqrestore(&up->port.lock, flags);
-}
-
-static void
-serial_pxa_pm(struct uart_port *port, unsigned int state,
- unsigned int oldstate)
-{
- struct uart_pxa_port *up = (struct uart_pxa_port *)port;
-
- if (!state)
- clk_prepare_enable(up->clk);
- else
- clk_disable_unprepare(up->clk);
-}
-
-static void serial_pxa_release_port(struct uart_port *port)
-{
-}
-
-static int serial_pxa_request_port(struct uart_port *port)
-{
- return 0;
-}
-
-static void serial_pxa_config_port(struct uart_port *port, int flags)
-{
- struct uart_pxa_port *up = (struct uart_pxa_port *)port;
- up->port.type = PORT_PXA;
-}
-
-static int
-serial_pxa_verify_port(struct uart_port *port, struct serial_struct *ser)
-{
- /* we don't want the core code to modify any port params */
- return -EINVAL;
-}
-
-static const char *
-serial_pxa_type(struct uart_port *port)
-{
- struct uart_pxa_port *up = (struct uart_pxa_port *)port;
- return up->name;
-}
-
-static struct uart_pxa_port *serial_pxa_ports[4];
-static struct uart_driver serial_pxa_reg;
-
-#ifdef CONFIG_SERIAL_PXA_CONSOLE
-
-#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
-
-/*
- * Wait for transmitter & holding register to empty
- */
-static inline void wait_for_xmitr(struct uart_pxa_port *up)
-{
- unsigned int status, tmout = 10000;
-
- /* Wait up to 10ms for the character(s) to be sent. */
- do {
- status = serial_in(up, UART_LSR);
-
- if (status & UART_LSR_BI)
- up->lsr_break_flag = UART_LSR_BI;
-
- if (--tmout == 0)
- break;
- udelay(1);
- } while ((status & BOTH_EMPTY) != BOTH_EMPTY);
-
- /* Wait up to 1s for flow control if necessary */
- if (up->port.flags & UPF_CONS_FLOW) {
- tmout = 1000000;
- while (--tmout &&
- ((serial_in(up, UART_MSR) & UART_MSR_CTS) == 0))
- udelay(1);
- }
-}
-
-static void serial_pxa_console_putchar(struct uart_port *port, int ch)
-{
- struct uart_pxa_port *up = (struct uart_pxa_port *)port;
-
- wait_for_xmitr(up);
- serial_out(up, UART_TX, ch);
-}
-
-/*
- * Print a string to the serial port trying not to disturb
- * any possible real use of the port...
- *
- * The console_lock must be held when we get here.
- */
-static void
-serial_pxa_console_write(struct console *co, const char *s, unsigned int count)
-{
- struct uart_pxa_port *up = serial_pxa_ports[co->index];
- unsigned int ier;
- unsigned long flags;
- int locked = 1;
-
- clk_enable(up->clk);
- local_irq_save(flags);
- if (up->port.sysrq)
- locked = 0;
- else if (oops_in_progress)
- locked = spin_trylock(&up->port.lock);
- else
- spin_lock(&up->port.lock);
-
- /*
- * First save the IER then disable the interrupts
- */
- ier = serial_in(up, UART_IER);
- serial_out(up, UART_IER, UART_IER_UUE);
-
- uart_console_write(&up->port, s, count, serial_pxa_console_putchar);
-
- /*
- * Finally, wait for transmitter to become empty
- * and restore the IER
- */
- wait_for_xmitr(up);
- serial_out(up, UART_IER, ier);
-
- if (locked)
- spin_unlock(&up->port.lock);
- local_irq_restore(flags);
- clk_disable(up->clk);
-
-}
-
-#ifdef CONFIG_CONSOLE_POLL
-/*
- * Console polling routines for writing and reading from the uart while
- * in an interrupt or debug context.
- */
-
-static int serial_pxa_get_poll_char(struct uart_port *port)
-{
- struct uart_pxa_port *up = (struct uart_pxa_port *)port;
- unsigned char lsr = serial_in(up, UART_LSR);
-
- while (!(lsr & UART_LSR_DR))
- lsr = serial_in(up, UART_LSR);
-
- return serial_in(up, UART_RX);
-}
-
-
-static void serial_pxa_put_poll_char(struct uart_port *port,
- unsigned char c)
-{
- unsigned int ier;
- struct uart_pxa_port *up = (struct uart_pxa_port *)port;
-
- /*
- * First save the IER then disable the interrupts
- */
- ier = serial_in(up, UART_IER);
- serial_out(up, UART_IER, UART_IER_UUE);
-
- wait_for_xmitr(up);
- /*
- * Send the character out.
- * If a LF, also do CR...
- */
- serial_out(up, UART_TX, c);
- if (c == 10) {
- wait_for_xmitr(up);
- serial_out(up, UART_TX, 13);
- }
-
- /*
- * Finally, wait for transmitter to become empty
- * and restore the IER
- */
- wait_for_xmitr(up);
- serial_out(up, UART_IER, ier);
-}
-
-#endif /* CONFIG_CONSOLE_POLL */
-
-static int __init
-serial_pxa_console_setup(struct console *co, char *options)
-{
- struct uart_pxa_port *up;
- int baud = 9600;
- int bits = 8;
- int parity = 'n';
- int flow = 'n';
-
- if (co->index == -1 || co->index >= serial_pxa_reg.nr)
- co->index = 0;
- up = serial_pxa_ports[co->index];
- if (!up)
- return -ENODEV;
-
- if (options)
- uart_parse_options(options, &baud, &parity, &bits, &flow);
-
- return uart_set_options(&up->port, co, baud, parity, bits, flow);
-}
-
-static struct console serial_pxa_console = {
- .name = "ttyS",
- .write = serial_pxa_console_write,
- .device = uart_console_device,
- .setup = serial_pxa_console_setup,
- .flags = CON_PRINTBUFFER,
- .index = -1,
- .data = &serial_pxa_reg,
-};
-
-#define PXA_CONSOLE &serial_pxa_console
-#else
-#define PXA_CONSOLE NULL
-#endif
-
-static struct uart_ops serial_pxa_pops = {
- .tx_empty = serial_pxa_tx_empty,
- .set_mctrl = serial_pxa_set_mctrl,
- .get_mctrl = serial_pxa_get_mctrl,
- .stop_tx = serial_pxa_stop_tx,
- .start_tx = serial_pxa_start_tx,
- .stop_rx = serial_pxa_stop_rx,
- .enable_ms = serial_pxa_enable_ms,
- .break_ctl = serial_pxa_break_ctl,
- .startup = serial_pxa_startup,
- .shutdown = serial_pxa_shutdown,
- .set_termios = serial_pxa_set_termios,
- .pm = serial_pxa_pm,
- .type = serial_pxa_type,
- .release_port = serial_pxa_release_port,
- .request_port = serial_pxa_request_port,
- .config_port = serial_pxa_config_port,
- .verify_port = serial_pxa_verify_port,
-#ifdef CONFIG_CONSOLE_POLL
- .poll_get_char = serial_pxa_get_poll_char,
- .poll_put_char = serial_pxa_put_poll_char,
-#endif
-};
-
-static struct uart_driver serial_pxa_reg = {
- .owner = THIS_MODULE,
- .driver_name = "PXA serial",
- .dev_name = "ttyS",
- .major = TTY_MAJOR,
- .minor = 64,
- .nr = 4,
- .cons = PXA_CONSOLE,
-};
-
-#ifdef CONFIG_PM
-static int serial_pxa_suspend(struct device *dev)
-{
- struct uart_pxa_port *sport = dev_get_drvdata(dev);
-
- if (sport)
- uart_suspend_port(&serial_pxa_reg, &sport->port);
-
- return 0;
-}
-
-static int serial_pxa_resume(struct device *dev)
-{
- struct uart_pxa_port *sport = dev_get_drvdata(dev);
-
- if (sport)
- uart_resume_port(&serial_pxa_reg, &sport->port);
-
- return 0;
-}
-
-static const struct dev_pm_ops serial_pxa_pm_ops = {
- .suspend = serial_pxa_suspend,
- .resume = serial_pxa_resume,
-};
-#endif
-
-static struct of_device_id serial_pxa_dt_ids[] = {
- { .compatible = "mrvl,pxa-uart", },
- { .compatible = "mrvl,mmp-uart", },
- {}
-};
-MODULE_DEVICE_TABLE(of, serial_pxa_dt_ids);
-
-static int serial_pxa_probe_dt(struct platform_device *pdev,
- struct uart_pxa_port *sport)
-{
- struct device_node *np = pdev->dev.of_node;
- int ret;
-
- if (!np)
- return 1;
-
- ret = of_alias_get_id(np, "serial");
- if (ret < 0) {
- dev_err(&pdev->dev, "failed to get alias id, errno %d\n", ret);
- return ret;
- }
- sport->port.line = ret;
- return 0;
-}
-
-static int serial_pxa_probe(struct platform_device *dev)
-{
- struct uart_pxa_port *sport;
- struct resource *mmres, *irqres;
- int ret;
-
- mmres = platform_get_resource(dev, IORESOURCE_MEM, 0);
- irqres = platform_get_resource(dev, IORESOURCE_IRQ, 0);
- if (!mmres || !irqres)
- return -ENODEV;
-
- sport = kzalloc(sizeof(struct uart_pxa_port), GFP_KERNEL);
- if (!sport)
- return -ENOMEM;
-
- sport->clk = clk_get(&dev->dev, NULL);
- if (IS_ERR(sport->clk)) {
- ret = PTR_ERR(sport->clk);
- goto err_free;
- }
-
- ret = clk_prepare(sport->clk);
- if (ret) {
- clk_put(sport->clk);
- goto err_free;
- }
-
- sport->port.type = PORT_PXA;
- sport->port.iotype = UPIO_MEM;
- sport->port.mapbase = mmres->start;
- sport->port.irq = irqres->start;
- sport->port.fifosize = 64;
- sport->port.ops = &serial_pxa_pops;
- sport->port.dev = &dev->dev;
- sport->port.flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF;
- sport->port.uartclk = clk_get_rate(sport->clk);
-
- ret = serial_pxa_probe_dt(dev, sport);
- if (ret > 0)
- sport->port.line = dev->id;
- else if (ret < 0)
- goto err_clk;
- snprintf(sport->name, PXA_NAME_LEN - 1, "UART%d", sport->port.line + 1);
-
- sport->port.membase = ioremap(mmres->start, resource_size(mmres));
- if (!sport->port.membase) {
- ret = -ENOMEM;
- goto err_clk;
- }
-
- serial_pxa_ports[sport->port.line] = sport;
-
- uart_add_one_port(&serial_pxa_reg, &sport->port);
- platform_set_drvdata(dev, sport);
-
- return 0;
-
- err_clk:
- clk_unprepare(sport->clk);
- clk_put(sport->clk);
- err_free:
- kfree(sport);
- return ret;
-}
-
-static int serial_pxa_remove(struct platform_device *dev)
-{
- struct uart_pxa_port *sport = platform_get_drvdata(dev);
-
- uart_remove_one_port(&serial_pxa_reg, &sport->port);
-
- clk_unprepare(sport->clk);
- clk_put(sport->clk);
- kfree(sport);
-
- return 0;
-}
-
-static struct platform_driver serial_pxa_driver = {
- .probe = serial_pxa_probe,
- .remove = serial_pxa_remove,
-
- .driver = {
- .name = "pxa2xx-uart",
- .owner = THIS_MODULE,
-#ifdef CONFIG_PM
- .pm = &serial_pxa_pm_ops,
-#endif
- .of_match_table = serial_pxa_dt_ids,
- },
-};
-
-static int __init serial_pxa_init(void)
-{
- int ret;
-
- ret = uart_register_driver(&serial_pxa_reg);
- if (ret != 0)
- return ret;
-
- ret = platform_driver_register(&serial_pxa_driver);
- if (ret != 0)
- uart_unregister_driver(&serial_pxa_reg);
-
- return ret;
-}
-
-static void __exit serial_pxa_exit(void)
-{
- platform_driver_unregister(&serial_pxa_driver);
- uart_unregister_driver(&serial_pxa_reg);
-}
-
-module_init(serial_pxa_init);
-module_exit(serial_pxa_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:pxa2xx-uart");
--
1.8.4.2
^ permalink raw reply related [flat|nested] 148+ messages in thread
* [PATCH v3 02/21] ARM: dts: pxa2xx fix compatible strings
[not found] ` <1387309071-22382-1-git-send-email-ynvich@gmail.com>
2013-12-17 19:37 ` [PATCH v3 01/21 resend] serial: rewrite pxa2xx-uart to use 8250_core Sergei Ianovich
@ 2013-12-17 19:37 ` Sergei Ianovich
[not found] ` <1387309071-22382-1-git-send-email-ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
` (14 subsequent siblings)
16 siblings, 0 replies; 148+ messages in thread
From: Sergei Ianovich @ 2013-12-17 19:37 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel
Cc: Sergei Ianovich, Daniel Mack, Arnd Bergmann, Rob Herring,
Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala, Russell King,
open list:OPEN FIRMWARE AND...
Signed-off-by: Sergei Ianovich <ynvich@gmail.com>
CC: Daniel Mack <zonque@gmail.com>
CC: Arnd Bergmann <arnd@arndb.de>
---
v2..v3
v1..v2
* no changes
arch/arm/boot/dts/pxa2xx.dtsi | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/arch/arm/boot/dts/pxa2xx.dtsi b/arch/arm/boot/dts/pxa2xx.dtsi
index a5e90f0..3419f87 100644
--- a/arch/arm/boot/dts/pxa2xx.dtsi
+++ b/arch/arm/boot/dts/pxa2xx.dtsi
@@ -18,7 +18,6 @@
serial1 = &btuart;
serial2 = &stuart;
serial3 = &hwuart;
- i2c0 = &pwri2c;
i2c1 = &pxai2c1;
};
@@ -113,14 +112,14 @@
};
usb0: ohci@4c000000 {
- compatible = "mrvl,pxa-ohci";
+ compatible = "marvell,pxa-ohci";
reg = <0x4c000000 0x10000>;
interrupts = <3>;
status = "disabled";
};
mmc0: mmc@41100000 {
- compatible = "mrvl,pxa-mmc";
+ compatible = "marvell,pxa-mmc";
reg = <0x41100000 0x1000>;
interrupts = <23>;
status = "disabled";
--
1.8.4.2
^ permalink raw reply related [flat|nested] 148+ messages in thread
* [PATCH v3 03/21] ARM: dts: fix pxa27x-gpio interrupts
[not found] ` <1387309071-22382-1-git-send-email-ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2013-12-17 19:37 ` Sergei Ianovich
0 siblings, 0 replies; 148+ messages in thread
From: Sergei Ianovich @ 2013-12-17 19:37 UTC (permalink / raw)
To: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
Cc: Sergei Ianovich, Daniel Mack, Arnd Bergmann, Rob Herring,
Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala, Russell King,
open list:OPEN FIRMWARE AND...
Signed-off-by: Sergei Ianovich <ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
CC: Daniel Mack <zonque-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
CC: Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org>
---
v2..v3
v1..v2
* no changes
arch/arm/boot/dts/pxa27x.dtsi | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/arch/arm/boot/dts/pxa27x.dtsi b/arch/arm/boot/dts/pxa27x.dtsi
index d7c5d72..44df554 100644
--- a/arch/arm/boot/dts/pxa27x.dtsi
+++ b/arch/arm/boot/dts/pxa27x.dtsi
@@ -10,5 +10,11 @@
marvell,intc-priority;
marvell,intc-nr-irqs = <34>;
};
+
+ gpio: gpio@40e00000 {
+ compatible = "intel,pxa27x-gpio";
+ interrupts = <8>, <9>, <10>;
+ interrupt-names = "gpio0", "gpio1", "gpio_mux";
+ };
};
};
--
1.8.4.2
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 148+ messages in thread
* [PATCH v3 06/21] ARM: dts: provide DMA config to pxamci on PXA27x
[not found] ` <1387309071-22382-1-git-send-email-ynvich@gmail.com>
` (2 preceding siblings ...)
[not found] ` <1387309071-22382-1-git-send-email-ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2013-12-17 19:37 ` Sergei Ianovich
2013-12-17 19:37 ` [PATCH v3 08/21] ARM: pxa27x: device tree support ICP DAS LP-8x4x Sergei Ianovich
` (12 subsequent siblings)
16 siblings, 0 replies; 148+ messages in thread
From: Sergei Ianovich @ 2013-12-17 19:37 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel
Cc: Sergei Ianovich, Daniel Mack, Arnd Bergmann, Rob Herring,
Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala, Rob Landley,
Russell King, open list:OPEN FIRMWARE AND...,
open list:DOCUMENTATION
Non-dts implementation supply required DMA channel numbers as
IORESOURCE_DMA. We can also get them from the device tree, if it
is present.
This patch updates device tree with the proper dmaengine-based
"marvell,pdma-1.0" DMA.
There is no actual data handling in this patch, because the existing
driver cannot get DMA channel number from dmaengine API. The patch
in the series will provide temporary workaround by manually parsing
node attributes, until Daniel's series is ready to be merged.
Signed-off-by: Sergei Ianovich <ynvich@gmail.com>
CC: Daniel Mack <zonque@gmail.com>
CC: Arnd Bergmann <arnd@arndb.de>
---
v2..v3
* split into good (this one) and temporary (PATCH 07/21) parts
v1..v2
* add binding for next-gen dma controller
* use correct dma declararion
* number changed from 5 to 3
Documentation/devicetree/bindings/mmc/pxa-mmc.txt | 5 +++++
arch/arm/boot/dts/pxa27x.dtsi | 14 ++++++++++++++
2 files changed, 19 insertions(+)
diff --git a/Documentation/devicetree/bindings/mmc/pxa-mmc.txt b/Documentation/devicetree/bindings/mmc/pxa-mmc.txt
index b7025de..9f54c69 100644
--- a/Documentation/devicetree/bindings/mmc/pxa-mmc.txt
+++ b/Documentation/devicetree/bindings/mmc/pxa-mmc.txt
@@ -5,6 +5,8 @@ Driver bindings for the PXA MCI (MMC/SDIO) interfaces
Required properties:
- compatible: Should be "marvell,pxa-mmc".
- vmmc-supply: A regulator for VMMC
+- dmas: Should be DMA specifiers for RX and TX
+- dma-names: Should be "rx" and "tx"
Optional properties:
- marvell,detect-delay-ms: sets the detection delay timeout in ms.
@@ -21,5 +23,8 @@ mmc0: mmc@41100000 {
interrupts = <23>;
cd-gpios = <&gpio 23 0>;
wp-gpios = <&gpio 24 0>;
+ dmas = <&dma 21
+ &dma 22>;
+ dma-names = "rx", "tx";
};
diff --git a/arch/arm/boot/dts/pxa27x.dtsi b/arch/arm/boot/dts/pxa27x.dtsi
index 44df554..c2a90c5 100644
--- a/arch/arm/boot/dts/pxa27x.dtsi
+++ b/arch/arm/boot/dts/pxa27x.dtsi
@@ -11,10 +11,24 @@
marvell,intc-nr-irqs = <34>;
};
+ dma: dma-controller@40000000 {
+ compatible = "marvell,pdma-1.0";
+ reg = <0x40000000 0x10000>;
+ interrupts = <25>;
+ #dma-cells = <1>;
+ dma-channels = <32>;
+ };
+
gpio: gpio@40e00000 {
compatible = "intel,pxa27x-gpio";
interrupts = <8>, <9>, <10>;
interrupt-names = "gpio0", "gpio1", "gpio_mux";
};
+
+ mmc@41100000 {
+ dmas = <&dma 21
+ &dma 22>;
+ dma-names = "rx", "tx";
+ };
};
};
--
1.8.4.2
^ permalink raw reply related [flat|nested] 148+ messages in thread
* [PATCH v3 08/21] ARM: pxa27x: device tree support ICP DAS LP-8x4x
[not found] ` <1387309071-22382-1-git-send-email-ynvich@gmail.com>
` (3 preceding siblings ...)
2013-12-17 19:37 ` [PATCH v3 06/21] ARM: dts: provide DMA config to pxamci on PXA27x Sergei Ianovich
@ 2013-12-17 19:37 ` Sergei Ianovich
2013-12-17 19:37 ` [PATCH v3 09/21] rtc: support DS1302 RTC on " Sergei Ianovich
` (11 subsequent siblings)
16 siblings, 0 replies; 148+ messages in thread
From: Sergei Ianovich @ 2013-12-17 19:37 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel
Cc: Sergei Ianovich, Daniel Mack, Arnd Bergmann, Rob Herring,
Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala, Russell King,
Eric Miao, Haojian Zhuang, open list:OPEN FIRMWARE AND...
ICP DAS calls LP-8x4x 'programmable automation controller'. It is
an industrial computer based on PXA270 SoC. They ship it with a 2.6.19
kernel and proprietary kernel module and userspace library to access
its industrial IO.
This patch allows to boot the device with a modern kernel with device
tree. It adds support for:
* MMC card interface on PXA270
* USB 1.1 port on PXA270
* 2 NOR flash devices
* 2 onboard ethernet Davicom DM9000 devices
* 3 serial UART ports on PXA270
* front panel red LED
* 64bit 1-wire system ID chip
* 16 kiB EEPROM (reading)
Support for these devices will be added in separate patches, since
they are not currently supported by the kernel:
* DS1302 RTC
* 512kiB SRAM
* FPGA irq chip
* 3 built-in 16550A serial UART ports
* industrial IO parallel bus
* 10 position rotary switch
* 8 pin DIP switch
* 16 kiB EEPROM (writing)
* serial interface for digital and analog industrial IO modules on
parallel bus (all I-87... modules)
* digital and analog industrial IO modules for parallel bus:
** I-8024 4 port analog output
** I-8041 32 port digital output
** I-8042 16 port digital output/16 port digital input
Not supported for now:
* VGA interface on PXA270 for lack of dts binding
* the rest of parallel bus (I-8...) modules for lack of hardware
* GPIO reset for lack of relevance (watchdog reset is working)
NOTE: USB support requires U-Boot patch series which setups GPIO.
Signed-off-by: Sergei Ianovich <ynvich@gmail.com>
CC: Daniel Mack <zonque@gmail.com>
CC: Arnd Bergmann <arnd@arndb.de>
---
v2..v3
* added extbus which maps synchronous, static, and variable-latency
I/O (VLIO) interfaces of PXA27x SoC as suggested by Arnd Bergmann
* map is placed into platform include
* configured existing kernel drivers to support:
- front panel LED using gpio-leds
- 64bit 1-wire system ID chip using w1-gpio
- 16 kiB EEPROM using at24 over i2c-gpio
* number change (06/16 -> 08/21)
v1..v2
* drop left-over extern declaration
* use of_have_populated_dt() instead of a static variable
* drop wildcards in compatible
* drop machine-special machine description
* number changed from 9 to 6 (dropped patches)
arch/arm/boot/dts/Makefile | 1 +
arch/arm/boot/dts/pxa27x-lp8x4x.dts | 153 ++++++++++++++++++++++++++++++++
arch/arm/boot/dts/pxa27x.dtsi | 17 ++++
arch/arm/configs/lp8x4x_defconfig | 168 ++++++++++++++++++++++++++++++++++++
arch/arm/mach-pxa/Kconfig | 15 ++++
arch/arm/mach-pxa/Makefile | 1 +
arch/arm/mach-pxa/pxa27x-dt.c | 64 ++++++++++++++
7 files changed, 419 insertions(+)
create mode 100644 arch/arm/boot/dts/pxa27x-lp8x4x.dts
create mode 100644 arch/arm/configs/lp8x4x_defconfig
create mode 100644 arch/arm/mach-pxa/pxa27x-dt.c
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index d57c1a6..c4752ff 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -206,6 +206,7 @@ dtb-$(CONFIG_ARCH_OMAP2PLUS) += omap2420-h4.dtb \
dra7-evm.dtb
dtb-$(CONFIG_ARCH_ORION5X) += orion5x-lacie-ethernet-disk-mini-v2.dtb
dtb-$(CONFIG_ARCH_PRIMA2) += prima2-evb.dtb
+dtb-$(CONFIG_MACH_PXA27X_DT) += pxa27x-lp8x4x.dtb
dtb-$(CONFIG_ARCH_U8500) += ste-snowball.dtb \
ste-hrefprev60-stuib.dtb \
ste-hrefprev60-tvk.dtb \
diff --git a/arch/arm/boot/dts/pxa27x-lp8x4x.dts b/arch/arm/boot/dts/pxa27x-lp8x4x.dts
new file mode 100644
index 0000000..6a780fe
--- /dev/null
+++ b/arch/arm/boot/dts/pxa27x-lp8x4x.dts
@@ -0,0 +1,153 @@
+/* Device tree for ICP DAS LP-8x4x */
+/dts-v1/;
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include "pxa27x.dtsi"
+
+/ {
+ model = "ICP DAS LP-8x4x programmable automation controller";
+ compatible = "marvell,lp8x4x", "marvell,pxa270";
+
+ aliases {
+ ethernet0 = ð0;
+ ethernet1 = ð1;
+ };
+
+ memory {
+ reg = <0xa0000000 0x08000000>;
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ vmmc: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "vmmc";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ };
+
+ pxabus {
+ pxairq: interrupt-controller@40d00000 {
+ marvell,intc-priority;
+ marvell,intc-nr-irqs = <34>;
+ };
+
+ uart@40100000 {
+ status = "okay";
+ };
+
+ uart@40200000 {
+ status = "okay";
+ };
+
+ uart@40700000 {
+ status = "okay";
+ };
+
+ mmc@41100000 {
+ status = "okay";
+ vmmc-supply = <&vmmc>;
+ };
+
+ ohci@4c000000 {
+ status = "okay";
+ marvell,port-mode = <3>;
+ marvell,oc-mode-perport;
+ marvell,enable-port1;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ status {
+ gpios = <&gpio 84 1>;
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
+ i2c: i2c-gpio {
+ compatible = "i2c-gpio";
+ gpios = <&gpio 22 0 /* sda */
+ &gpio 12 0 /* scl */>;
+ i2c-gpio,delay-us = <1>;
+ i2c-gpio,timeout-ms = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ eeprom@50 {
+ compatible = "atmel,24c128";
+ reg = <0x50>;
+ pagesize = <64>;
+ };
+ };
+
+ w1: w1-gpio {
+ compatible = "w1-gpio";
+ gpios = <&gpio 83 0>;
+ };
+ };
+
+ extbus {
+ flash@0 {
+ compatible = "cfi-flash";
+ reg = <0 0 0x02000000>;
+ bank-width = <4>;
+ device-width = <2>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ fs@0 {
+ label = "u-boot";
+ reg = <0 0x40000>;
+ };
+ fs@40000 {
+ label = "settings";
+ reg = <0x40000 0x40000>;
+ };
+ fs@80000 {
+ label = "kernel";
+ reg = <0x80000 0x280000>;
+ };
+ fs@300000 {
+ label = "root_fs";
+ reg = <0x300000 0x1d00000>;
+ };
+ };
+
+ flash@1 {
+ compatible = "cfi-flash";
+ reg = <1 0x0 0x01000000>;
+ bank-width = <2>;
+ device-width = <1>;
+ };
+
+ netio@3 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 3 0 0x02000000>;
+ interrupt-parent = <&gpio>;
+
+ eth0: eth@0 {
+ compatible = "davicom,dm9000";
+ reg = <0x0 0x2
+ 0x4000 0x2>;
+ interrupts = <9 IRQ_TYPE_EDGE_RISING>;
+ status = "okay";
+ };
+
+ eth1: eth@1000000 {
+ compatible = "davicom,dm9000";
+ reg = <0x1000000 0x2
+ 0x1004000 0x2>;
+ interrupts = <82 IRQ_TYPE_EDGE_RISING>;
+ status = "okay";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/pxa27x.dtsi b/arch/arm/boot/dts/pxa27x.dtsi
index c2a90c5..29d878d 100644
--- a/arch/arm/boot/dts/pxa27x.dtsi
+++ b/arch/arm/boot/dts/pxa27x.dtsi
@@ -31,4 +31,21 @@
dma-names = "rx", "tx";
};
};
+
+ extbus {
+ /*
+ * PXA27x synchrous, static and
+ * variable-latency IO interfaces
+ */
+ compatible = "simple-bus";
+
+ #address-cells = <2>; /* first cell is nCS, second is address */
+ #size-cells = <1>;
+ ranges = <0 0 0 0x04000000
+ 1 0 0x04000000 0x04000000
+ 2 0 0x08000000 0x04000000
+ 3 0 0x0c000000 0x04000000
+ 4 0 0x10000000 0x04000000
+ 5 0 0x14000000 0x04000000>;
+ };
};
diff --git a/arch/arm/configs/lp8x4x_defconfig b/arch/arm/configs/lp8x4x_defconfig
new file mode 100644
index 0000000..9f1efb6
--- /dev/null
+++ b/arch/arm/configs/lp8x4x_defconfig
@@ -0,0 +1,168 @@
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_RCU_BOOST=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+# CONFIG_UID16 is not set
+# CONFIG_SHMEM is not set
+CONFIG_EMBEDDED=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLOB=y
+CONFIG_JUMP_LABEL=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+# CONFIG_LBDAF is not set
+CONFIG_BLK_CMDLINE_PARSER=y
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+CONFIG_ARCH_PXA=y
+CONFIG_MACH_PXA27X_DT=y
+# CONFIG_ARM_THUMB is not set
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+# CONFIG_COMPACTION is not set
+# CONFIG_CROSS_MEMORY_ATTACH is not set
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="init=/sbin/init root=/dev/mmcblk0p1 rw rootfstype=ext4 console=ttyS0,115200 mem=128M rootwait"
+# CONFIG_SUSPEND is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_BRIDGE=m
+CONFIG_BRIDGE_VLAN_FILTERING=y
+CONFIG_VLAN_8021Q=m
+CONFIG_VLAN_8021Q_GVRP=y
+CONFIG_VLAN_8021Q_MVRP=y
+# CONFIG_WIRELESS is not set
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_FW_LOADER is not set
+CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_GEOMETRY=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_PHYSMAP_OF=y
+CONFIG_PROC_DEVICETREE=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_LOOP_MIN_COUNT=2
+CONFIG_EEPROM_AT24=m
+CONFIG_SCSI=y
+# CONFIG_SCSI_PROC_FS is not set
+CONFIG_BLK_DEV_SD=y
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_NETDEVICES=y
+CONFIG_BONDING=m
+CONFIG_MACVLAN=m
+CONFIG_MACVTAP=m
+CONFIG_TUN=m
+# CONFIG_NET_VENDOR_ARC is not set
+# CONFIG_NET_CADENCE is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CIRRUS is not set
+CONFIG_DM9000=y
+CONFIG_DM9000_FORCE_SIMPLE_PHY_POLL=y
+# CONFIG_NET_VENDOR_FARADAY 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_SEEQ is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_VIA is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
+CONFIG_PPP=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPPOE=m
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+# CONFIG_WLAN is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=800
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=600
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_8250=y
+# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=40
+CONFIG_SERIAL_8250_RUNTIME_UARTS=40
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_MANY_PORTS=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_PXA=y
+CONFIG_HW_RANDOM=y
+CONFIG_I2C=m
+# CONFIG_I2C_COMPAT is not set
+CONFIG_I2C_GPIO=m
+CONFIG_W1=m
+CONFIG_W1_MASTER_GPIO=m
+CONFIG_W1_SLAVE_SMEM=m
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_SA1100_WATCHDOG=m
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_FB=y
+CONFIG_FB_PXA=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_LOGO=y
+CONFIG_USB=m
+CONFIG_USB_OHCI_HCD=m
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+CONFIG_USB_STORAGE=m
+CONFIG_USB_SERIAL=m
+CONFIG_MMC=y
+CONFIG_MMC_PXA=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_PXA=m
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_EXT2_FS=m
+CONFIG_EXT3_FS=y
+CONFIG_EXT4_FS=y
+CONFIG_REISERFS_FS=m
+CONFIG_ISO9660_FS=m
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_NTFS_FS=m
+CONFIG_NTFS_RW=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+CONFIG_CIFS=m
+CONFIG_CIFS_STATS=y
+CONFIG_CODA_FS=m
+CONFIG_NLS_DEFAULT="cp855"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_855=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_UTF8=y
+CONFIG_PRINTK_TIME=y
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
index 96100db..df3a79d 100644
--- a/arch/arm/mach-pxa/Kconfig
+++ b/arch/arm/mach-pxa/Kconfig
@@ -4,6 +4,21 @@ menu "Intel PXA2xx/PXA3xx Implementations"
comment "Intel/Marvell Dev Platforms (sorted by hardware release time)"
+config MACH_PXA27X_DT
+ bool "Support PXA27x platforms from device tree"
+ select PXA27x
+ select USE_OF
+ help
+ Include support for Marvell PXA27x based platforms using
+ the device tree.
+
+ While MACH_PXA27X_DT when enabled should boot any PXA27x
+ compatible machine, it still makes sense to select specific
+ machines. Those options will select required features and
+ provide per-machine errata workarounds.
+
+ If unsure, say Y.
+
config MACH_PXA3XX_DT
bool "Support PXA3xx platforms from device tree"
select CPU_PXA300
diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile
index 648867a..adaa72a 100644
--- a/arch/arm/mach-pxa/Makefile
+++ b/arch/arm/mach-pxa/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_CPU_PXA930) += pxa930.o
# NOTE: keep the order of boards in accordance to their order in Kconfig
# Device Tree support
+obj-$(CONFIG_MACH_PXA27X_DT) += pxa27x-dt.o
obj-$(CONFIG_MACH_PXA3XX_DT) += pxa-dt.o
# Intel/Marvell Dev Platforms
diff --git a/arch/arm/mach-pxa/pxa27x-dt.c b/arch/arm/mach-pxa/pxa27x-dt.c
new file mode 100644
index 0000000..865cf46
--- /dev/null
+++ b/arch/arm/mach-pxa/pxa27x-dt.c
@@ -0,0 +1,64 @@
+/*
+ * linux/arch/arm/mach-pxa/pxa27x-dt.c
+ *
+ * Copyright (C) 2013 Sergei Ianovich
+ *
+ * based mostly on linux/arch/arm/mach-pxa/pxa-dt.c by Daniel Mack
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <asm/io.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <mach/irqs.h>
+#include <mach/pxa27x.h>
+
+#include "generic.h"
+
+#ifdef CONFIG_PXA27x
+static const struct of_dev_auxdata pxa27x_auxdata_lookup[] __initconst = {
+ OF_DEV_AUXDATA("mrvl,pxa-uart", 0x40100000, "pxa2xx-uart.0", NULL),
+ OF_DEV_AUXDATA("mrvl,pxa-uart", 0x40200000, "pxa2xx-uart.1", NULL),
+ OF_DEV_AUXDATA("mrvl,pxa-uart", 0x40700000, "pxa2xx-uart.2", NULL),
+ OF_DEV_AUXDATA("mrvl,pxa-uart", 0x41600000, "pxa2xx-uart.3", NULL),
+ OF_DEV_AUXDATA("marvell,pxa-mmc", 0x41100000, "pxa2xx-mci.0", NULL),
+ OF_DEV_AUXDATA("intel,pxa27x-gpio", 0x40e00000, "pxa27x-gpio", NULL),
+ OF_DEV_AUXDATA("marvell,pxa-ohci", 0x4c000000, "pxa27x-ohci", NULL),
+ OF_DEV_AUXDATA("mrvl,pxa-i2c", 0x40301680, "pxa2xx-i2c.0", NULL),
+ {}
+};
+
+static void __init pxa27x_dt_init(void)
+{
+ of_platform_populate(NULL, of_default_bus_match_table,
+ pxa27x_auxdata_lookup, NULL);
+}
+
+static const char * const pxa27x_dt_board_compat[] __initconst = {
+ "marvell,pxa270",
+ "marvell,pxa271",
+ "marvell,pxa272",
+ NULL,
+};
+
+#endif
+
+#ifdef CONFIG_PXA27x
+DT_MACHINE_START(PXA27X_DT, "Marvell PXA27x (Device Tree Support)")
+ .map_io = pxa27x_map_io,
+ .init_irq = pxa27x_dt_init_irq,
+ .handle_irq = pxa27x_handle_irq,
+ .init_time = pxa_timer_init,
+ .restart = pxa_restart,
+ .init_machine = pxa27x_dt_init,
+ .dt_compat = pxa27x_dt_board_compat,
+MACHINE_END
+
+#endif
--
1.8.4.2
^ permalink raw reply related [flat|nested] 148+ messages in thread
* [PATCH v3 09/21] rtc: support DS1302 RTC on ICP DAS LP-8x4x
[not found] ` <1387309071-22382-1-git-send-email-ynvich@gmail.com>
` (4 preceding siblings ...)
2013-12-17 19:37 ` [PATCH v3 08/21] ARM: pxa27x: device tree support ICP DAS LP-8x4x Sergei Ianovich
@ 2013-12-17 19:37 ` Sergei Ianovich
2013-12-17 19:37 ` [PATCH v3 10/21] mtd: support BB SRAM " Sergei Ianovich
` (10 subsequent siblings)
16 siblings, 0 replies; 148+ messages in thread
From: Sergei Ianovich @ 2013-12-17 19:37 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel
Cc: Sergei Ianovich, Rob Herring, Pawel Moll, Mark Rutland,
Ian Campbell, Kumar Gala, Rob Landley, Russell King,
Alessandro Zummo, Grant Likely, open list:OPEN FIRMWARE AND...,
open list:DOCUMENTATION, rtc-linux
Signed-off-by: Sergei Ianovich <ynvich@gmail.com>
---
v2..v3
* use usleep_range instead of custom nsleep
* number change (07/16 -> 09/21)
v0..v2
* use device tree
* use devm helpers where possible
.../devicetree/bindings/rtc/rtc-ds1302.txt | 14 +++
arch/arm/boot/dts/pxa27x-lp8x4x.dts | 13 +++
arch/arm/configs/lp8x4x_defconfig | 1 +
drivers/rtc/Kconfig | 2 +-
drivers/rtc/rtc-ds1302.c | 100 ++++++++++++++++++++-
5 files changed, 127 insertions(+), 3 deletions(-)
create mode 100644 Documentation/devicetree/bindings/rtc/rtc-ds1302.txt
diff --git a/Documentation/devicetree/bindings/rtc/rtc-ds1302.txt b/Documentation/devicetree/bindings/rtc/rtc-ds1302.txt
new file mode 100644
index 0000000..876297c
--- /dev/null
+++ b/Documentation/devicetree/bindings/rtc/rtc-ds1302.txt
@@ -0,0 +1,14 @@
+* Dallas Semiconductor DS-1302 RTC
+
+Simple device which could be used to store date/time between reboots.
+
+Required properties:
+- compatible : Should be "ds,rtc-ds1302"
+- reg : Should be address and size of IO memory region
+
+Examples:
+
+rtc@40900000 {
+ compatible = "ds,rtc-ds1302";
+ reg = <0x1700901c 0x1>;
+};
diff --git a/arch/arm/boot/dts/pxa27x-lp8x4x.dts b/arch/arm/boot/dts/pxa27x-lp8x4x.dts
index 6a780fe..872c386 100644
--- a/arch/arm/boot/dts/pxa27x-lp8x4x.dts
+++ b/arch/arm/boot/dts/pxa27x-lp8x4x.dts
@@ -149,5 +149,18 @@
status = "okay";
};
};
+
+ fpga@5 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 5 0x3000000 0x10000>;
+
+ rtc@901c {
+ compatible = "ds,rtc-ds1302";
+ reg = <0x901c 0x1>;
+ status = "okay";
+ };
+ };
};
};
diff --git a/arch/arm/configs/lp8x4x_defconfig b/arch/arm/configs/lp8x4x_defconfig
index 9f1efb6..d60e37a 100644
--- a/arch/arm/configs/lp8x4x_defconfig
+++ b/arch/arm/configs/lp8x4x_defconfig
@@ -141,6 +141,7 @@ CONFIG_LEDS_GPIO=y
CONFIG_LEDS_TRIGGERS=y
CONFIG_LEDS_TRIGGER_HEARTBEAT=y
CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_DS1302=y
CONFIG_RTC_DRV_PXA=m
# CONFIG_IOMMU_SUPPORT is not set
CONFIG_EXT2_FS=m
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 0077302..501055f 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -676,7 +676,7 @@ config RTC_DRV_DS1286
config RTC_DRV_DS1302
tristate "Dallas DS1302"
- depends on SH_SECUREEDGE5410
+ depends on SH_SECUREEDGE5410 || (ARCH_PXA && HIGH_RES_TIMERS)
help
If you say yes here you get support for the Dallas DS1302 RTC chips.
diff --git a/drivers/rtc/rtc-ds1302.c b/drivers/rtc/rtc-ds1302.c
index 07e8d79..24a75d8 100644
--- a/drivers/rtc/rtc-ds1302.c
+++ b/drivers/rtc/rtc-ds1302.c
@@ -50,7 +50,7 @@
#define ds1302_set_tx()
#define ds1302_set_rx()
-static inline int ds1302_hw_init(void)
+static inline int ds1302_hw_init(struct platform_device *pdev)
{
return 0;
}
@@ -86,6 +86,101 @@ static inline int ds1302_rxbit(void)
return !!(get_dp() & RTC_IODATA);
}
+#elif defined(CONFIG_ARCH_PXA) && defined(CONFIG_HIGH_RES_TIMERS)
+
+#include <linux/delay.h>
+#include <linux/of.h>
+
+#define RTC_CE 0x01
+#define RTC_CLK 0x02
+#define RTC_nWE 0x04
+#define RTC_IODATA 0x08
+
+static unsigned long ds1302_state;
+
+static void *mem;
+
+static inline int ds1302_hw_init(struct platform_device *pdev)
+{
+ struct resource *r;
+
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!r)
+ return -ENODEV;
+
+ mem = devm_ioremap_resource(&pdev->dev, r);
+ if (!mem)
+ return -EFAULT;
+
+ return 0;
+}
+
+static inline void ds1302_reset(void)
+{
+ ds1302_state = 0;
+ iowrite8(ds1302_state, mem);
+ usleep_range(4, 5);
+}
+
+static inline void ds1302_clock(void)
+{
+ usleep_range(1, 2);
+ ds1302_state |= RTC_CLK;
+ iowrite8(ds1302_state, mem);
+ usleep_range(1, 2);
+ ds1302_state &= ~RTC_CLK;
+ iowrite8(ds1302_state, mem);
+}
+
+static inline void ds1302_start(void)
+{
+ ds1302_state &= ~RTC_CLK;
+ ds1302_state |= RTC_CE;
+ iowrite8(ds1302_state, mem);
+ usleep_range(3, 4);
+}
+
+static inline void ds1302_stop(void)
+{
+ ds1302_state &= ~RTC_CE;
+ iowrite8(ds1302_state, mem);
+}
+
+static inline void ds1302_set_tx(void)
+{
+ ds1302_state &= ~RTC_nWE;
+ iowrite8(ds1302_state, mem);
+}
+
+static inline void ds1302_set_rx(void)
+{
+ ds1302_state |= RTC_nWE;
+ iowrite8(ds1302_state, mem);
+}
+
+static inline void ds1302_txbit(int bit)
+{
+ if (bit)
+ ds1302_state |= RTC_IODATA;
+ else
+ ds1302_state &= ~RTC_IODATA;
+ iowrite8(ds1302_state, mem);
+}
+
+static inline int ds1302_rxbit(void)
+{
+ return ioread8(mem) & 0x1;
+}
+
+#ifdef CONFIG_OF
+static const struct of_device_id ds1302_dt_ids[] = {
+ { .compatible = "ds,rtc-ds1302" },
+ { }
+};
+
+MODULE_DEVICE_TABLE(of, ds1302_dt_ids);
+#endif
+
#else
#error "Add support for your platform"
#endif
@@ -216,7 +311,7 @@ static int __init ds1302_rtc_probe(struct platform_device *pdev)
{
struct rtc_device *rtc;
- if (ds1302_hw_init()) {
+ if (ds1302_hw_init(pdev)) {
dev_err(&pdev->dev, "Failed to init communication channel");
return -EINVAL;
}
@@ -245,6 +340,7 @@ static struct platform_driver ds1302_platform_driver = {
.driver = {
.name = DRV_NAME,
.owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(ds1302_dt_ids),
},
};
--
1.8.4.2
^ permalink raw reply related [flat|nested] 148+ messages in thread
* [PATCH v3 10/21] mtd: support BB SRAM on ICP DAS LP-8x4x
[not found] ` <1387309071-22382-1-git-send-email-ynvich@gmail.com>
` (5 preceding siblings ...)
2013-12-17 19:37 ` [PATCH v3 09/21] rtc: support DS1302 RTC on " Sergei Ianovich
@ 2013-12-17 19:37 ` Sergei Ianovich
2014-04-16 5:04 ` Brian Norris
2013-12-17 19:37 ` [PATCH v3 11/21] ARM: pxa: support ICP DAS LP-8x4x FPGA irq Sergei Ianovich
` (9 subsequent siblings)
16 siblings, 1 reply; 148+ messages in thread
From: Sergei Ianovich @ 2013-12-17 19:37 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel
Cc: Sergei Ianovich, Rob Herring, Pawel Moll, Mark Rutland,
Ian Campbell, Kumar Gala, Russell King, David Woodhouse,
Grant Likely, Artem Bityutskiy, Robert Jarzmik, Kees Cook,
Randy Dunlap, Philip Avinash, open list:OPEN FIRMWARE AND...,
open list:MEMORY TECHNOLOGY...
This provides an MTD device driver for 512kB of battery backed up SRAM
on ICPDAS LP-8X4X programmable automation controllers.
SRAM chip is connected via FPGA and is not accessible without a driver,
unlike flash memory which is wired to CPU MMU.
This SRAM becomes an excellent persisent storage of volatile process
data like counter values and sensor statuses. Storing those data in
flash or mmc card is not a viable solution.
Signed-off-by: Sergei Ianovich <ynvich@gmail.com>
---
v2..v3
* no changes (except number 08/16 -> 10/21)
v0..v2
* use device tree
* use devm helpers where possible
arch/arm/boot/dts/pxa27x-lp8x4x.dts | 6 +
arch/arm/configs/lp8x4x_defconfig | 1 +
drivers/mtd/devices/Kconfig | 14 +++
drivers/mtd/devices/Makefile | 1 +
drivers/mtd/devices/sram_lp8x4x.c | 227 ++++++++++++++++++++++++++++++++++++
5 files changed, 249 insertions(+)
create mode 100644 drivers/mtd/devices/sram_lp8x4x.c
diff --git a/arch/arm/boot/dts/pxa27x-lp8x4x.dts b/arch/arm/boot/dts/pxa27x-lp8x4x.dts
index 872c386..07856e0 100644
--- a/arch/arm/boot/dts/pxa27x-lp8x4x.dts
+++ b/arch/arm/boot/dts/pxa27x-lp8x4x.dts
@@ -161,6 +161,12 @@
reg = <0x901c 0x1>;
status = "okay";
};
+
+ sram@a000 {
+ compatible = "icpdas,sram-lp8x4x";
+ reg = <0xa000 0x1000
+ 0x901e 0x1>;
+ };
};
};
};
diff --git a/arch/arm/configs/lp8x4x_defconfig b/arch/arm/configs/lp8x4x_defconfig
index d60e37a..17a4e6f 100644
--- a/arch/arm/configs/lp8x4x_defconfig
+++ b/arch/arm/configs/lp8x4x_defconfig
@@ -57,6 +57,7 @@ CONFIG_MTD_CFI_ADV_OPTIONS=y
CONFIG_MTD_CFI_GEOMETRY=y
CONFIG_MTD_CFI_INTELEXT=y
CONFIG_MTD_PHYSMAP_OF=y
+CONFIG_MTD_SRAM_LP8X4X=y
CONFIG_PROC_DEVICETREE=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_LOOP_MIN_COUNT=2
diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig
index 0128138..95f2075 100644
--- a/drivers/mtd/devices/Kconfig
+++ b/drivers/mtd/devices/Kconfig
@@ -217,4 +217,18 @@ config BCH_CONST_T
default 4
endif
+config MTD_SRAM_LP8X4X
+ tristate "SRAM on ICPDAS LP-8X4X"
+ depends on OF && ARCH_PXA
+ ---help---
+ This provides an MTD device driver for 512kiB of battery backed up SRAM
+ on ICPDAS LP-8X4X programmable automation controllers.
+
+ SRAM chip is connected via FPGA and is not accessible without a driver,
+ unlike flash memory which is wired to CPU MMU.
+
+ Say N, unless you plan to run this kernel on LP-8X4X.
+
+ If you say M, the module will be called sram_lp8x4x.
+
endmenu
diff --git a/drivers/mtd/devices/Makefile b/drivers/mtd/devices/Makefile
index d83bd73..56a74c9 100644
--- a/drivers/mtd/devices/Makefile
+++ b/drivers/mtd/devices/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_MTD_NAND_OMAP_BCH) += elm.o
obj-$(CONFIG_MTD_SPEAR_SMI) += spear_smi.o
obj-$(CONFIG_MTD_SST25L) += sst25l.o
obj-$(CONFIG_MTD_BCM47XXSFLASH) += bcm47xxsflash.o
+obj-$(CONFIG_MTD_SRAM_LP8X4X) += sram_lp8x4x.o
CFLAGS_docg3.o += -I$(src)
diff --git a/drivers/mtd/devices/sram_lp8x4x.c b/drivers/mtd/devices/sram_lp8x4x.c
new file mode 100644
index 0000000..9dc7149
--- /dev/null
+++ b/drivers/mtd/devices/sram_lp8x4x.c
@@ -0,0 +1,227 @@
+/*
+ * linux/drivers/mtd/devices/lp8x4x_sram.c
+ *
+ * MTD Driver for SRAM on ICPDAS LP-8x4x
+ * Copyright (C) 2013 Sergei Ianovich <ynvich@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation or any later version.
+ */
+
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/platform_device.h>
+#include <linux/of_device.h>
+#include <linux/slab.h>
+#include <linux/string_helpers.h>
+#include <linux/types.h>
+
+#include <asm/mach/flash.h>
+
+struct lp8x4x_sram_info {
+ void __iomem *bank;
+ void __iomem *virt;
+ struct mutex lock;
+ unsigned active_bank;
+ struct mtd_info mtd;
+};
+
+static int
+lp8x4x_sram_erase(struct mtd_info *mtd, struct erase_info *instr)
+{
+ struct lp8x4x_sram_info *info = mtd->priv;
+ unsigned bank = instr->addr >> 11;
+ unsigned offset = (instr->addr & 0x7ff) << 1;
+ loff_t i;
+
+ mutex_lock(&info->lock);
+ if (unlikely(bank != info->active_bank)) {
+ info->active_bank = bank;
+ iowrite8(bank, info->bank);
+ }
+ for (i = 0; i < instr->len; i++) {
+ iowrite8(0xff, info->virt + offset);
+ offset += 2;
+ if (unlikely(offset == 0)) {
+ info->active_bank++;
+ iowrite8(info->active_bank, info->bank);
+ }
+ }
+ mutex_unlock(&info->lock);
+ instr->state = MTD_ERASE_DONE;
+ mtd_erase_callback(instr);
+
+ return 0;
+}
+
+static int
+lp8x4x_sram_write(struct mtd_info *mtd, loff_t to, size_t len,
+ size_t *retlen, const u_char *b)
+{
+ struct lp8x4x_sram_info *info = mtd->priv;
+ unsigned bank = to >> 11;
+ unsigned offset = (to & 0x7ff) << 1;
+ loff_t i;
+
+ mutex_lock(&info->lock);
+ if (unlikely(bank != info->active_bank)) {
+ info->active_bank = bank;
+ iowrite8(bank, info->bank);
+ }
+ for (i = 0; i < len; i++) {
+ iowrite8(b[i], info->virt + offset);
+ offset += 2;
+ if (unlikely(offset == 0)) {
+ info->active_bank++;
+ iowrite8(info->active_bank, info->bank);
+ }
+ }
+ mutex_unlock(&info->lock);
+ *retlen = len;
+ return 0;
+}
+
+static int
+lp8x4x_sram_read(struct mtd_info *mtd, loff_t from, size_t len,
+ size_t *retlen, u_char *b)
+{
+ struct lp8x4x_sram_info *info = mtd->priv;
+ unsigned bank = from >> 11;
+ unsigned offset = (from & 0x7ff) << 1;
+ loff_t i;
+
+ mutex_lock(&info->lock);
+ if (unlikely(bank != info->active_bank)) {
+ info->active_bank = bank;
+ iowrite8(bank, info->bank);
+ }
+ for (i = 0; i < len; i++) {
+ b[i] = ioread8(info->virt + offset);
+ offset += 2;
+ if (unlikely(offset == 0)) {
+ info->active_bank++;
+ iowrite8(info->active_bank, info->bank);
+ }
+ }
+ mutex_unlock(&info->lock);
+ *retlen = len;
+ return 0;
+}
+
+static void
+lp8x4x_sram_sync(struct mtd_info *mtd)
+{
+}
+
+static struct of_device_id of_flash_match[] = {
+ {
+ .compatible = "icpdas,sram-lp8x4x",
+ },
+ { },
+};
+MODULE_DEVICE_TABLE(of, of_flash_match);
+
+static const char * const probe_types[] = {
+ "cmdlinepart", "RedBoot", "ofpart", "ofoldpart", NULL };
+
+static int
+lp8x4x_sram_probe(struct platform_device *pdev)
+{
+ const struct of_device_id *match;
+ struct lp8x4x_sram_info *info;
+ struct resource *r1, *r2;
+ char sz_str[16];
+ struct mtd_part_parser_data ppdata;
+ int err = 0;
+
+ match = of_match_device(of_flash_match, &pdev->dev);
+ if (!match)
+ return -EINVAL;
+
+ r1 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ r2 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (!r1 || !r2)
+ return -ENODEV;
+
+ info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
+ if (!info)
+ return -ENOMEM;
+
+ info->virt = devm_ioremap_resource(&pdev->dev, r1);
+ if (!info->virt) {
+ dev_err(&pdev->dev, "Failed to ioremap %p\n",
+ info->virt);
+ return -EFAULT;
+ }
+
+ info->bank = devm_ioremap_resource(&pdev->dev, r2);
+ if (!info->bank) {
+ dev_err(&pdev->dev, "Failed to ioremap %p\n",
+ info->bank);
+ return -EFAULT;
+ }
+
+ info->mtd.priv = info;
+ info->mtd.name = "SRAM";
+ info->mtd.type = MTD_RAM;
+ info->mtd.flags = MTD_CAP_RAM;
+ info->mtd.size = resource_size(r1) << 7;
+ info->mtd.erasesize = 512;
+ info->mtd.writesize = 4;
+ info->mtd._erase = lp8x4x_sram_erase;
+ info->mtd._write = lp8x4x_sram_write;
+ info->mtd._read = lp8x4x_sram_read;
+ info->mtd._sync = lp8x4x_sram_sync;
+ info->mtd.owner = THIS_MODULE;
+
+ mutex_init(&info->lock);
+ iowrite8(info->active_bank, info->bank);
+ platform_set_drvdata(pdev, info);
+
+ ppdata.of_node = pdev->dev.of_node;
+ err = mtd_device_parse_register(&info->mtd, probe_types, &ppdata,
+ NULL, 0);
+
+ if (err < 0) {
+ dev_err(&pdev->dev, "Failed to register platform device\n");
+ return err;
+ }
+
+ string_get_size(info->mtd.size, STRING_UNITS_2, sz_str,
+ sizeof(sz_str));
+ dev_info(&pdev->dev, "using %s SRAM on LP-8X4X as %s\n", sz_str,
+ dev_name(&info->mtd.dev));
+ return 0;
+}
+
+static int
+lp8x4x_sram_remove(struct platform_device *dev)
+{
+ struct lp8x4x_sram_info *info = platform_get_drvdata(dev);
+
+ mtd_device_unregister(&info->mtd);
+ platform_set_drvdata(dev, NULL);
+ return 0;
+}
+
+static struct platform_driver lp8x4x_sram_driver = {
+ .driver = {
+ .name = "sram-lp8x4x",
+ .owner = THIS_MODULE,
+ .of_match_table = of_flash_match,
+ },
+ .probe = lp8x4x_sram_probe,
+ .remove = lp8x4x_sram_remove,
+};
+
+module_platform_driver(lp8x4x_sram_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Sergei Ianovich <ynvich@gmail.com>");
+MODULE_DESCRIPTION("MTD driver for SRAM on ICPDAS LP-8x4x");
--
1.8.4.2
^ permalink raw reply related [flat|nested] 148+ messages in thread
* [PATCH v3 11/21] ARM: pxa: support ICP DAS LP-8x4x FPGA irq
[not found] ` <1387309071-22382-1-git-send-email-ynvich@gmail.com>
` (6 preceding siblings ...)
2013-12-17 19:37 ` [PATCH v3 10/21] mtd: support BB SRAM " Sergei Ianovich
@ 2013-12-17 19:37 ` Sergei Ianovich
2014-01-02 12:32 ` Linus Walleij
[not found] ` <1387309071-22382-12-git-send-email-ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2013-12-17 19:37 ` [PATCH v3 12/21] serial: support for 16550A serial ports on LP-8x4x Sergei Ianovich
` (8 subsequent siblings)
16 siblings, 2 replies; 148+ messages in thread
From: Sergei Ianovich @ 2013-12-17 19:37 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel
Cc: Sergei Ianovich, Arnd Bergmann, Linus Walleij, Rob Herring,
Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala, Rob Landley,
Russell King, Thomas Gleixner, Grant Likely,
open list:OPEN FIRMWARE AND..., open list:DOCUMENTATION
ICP DAS LP-8x4x contains FPGA chip. The chip functions as a interrupt
source providing 16 additional interrupts among other things. The
interrupt lines are muxed to a GPIO pin. GPIO pins are in turn muxed
to a CPU interrupt line.
Until pxa is completely converted to device tree, it is impossible
to use IRQCHIP_DECLARE() and the irqdomain needs to added manually.
Signed-off-by: Sergei Ianovich <ynvich@gmail.com>
CC: Arnd Bergmann <arnd@arndb.de>
CC: Linus Walleij <linus.walleij@linaro.org>
---
v2..v3
* no changes (except number 09/16 -> 10/21)
v0..v2
* extract irqchip and move to drivers/irqchip/
* use device tree
* use devm helpers where possible
.../bindings/interrupt-controller/irq-lp8x4x.txt | 49 +++++
arch/arm/boot/dts/pxa27x-lp8x4x.dts | 10 +
drivers/irqchip/Kconfig | 5 +
drivers/irqchip/Makefile | 1 +
drivers/irqchip/irq-lp8x4x.c | 205 +++++++++++++++++++++
5 files changed, 270 insertions(+)
create mode 100644 Documentation/devicetree/bindings/interrupt-controller/irq-lp8x4x.txt
create mode 100644 drivers/irqchip/irq-lp8x4x.c
diff --git a/Documentation/devicetree/bindings/interrupt-controller/irq-lp8x4x.txt b/Documentation/devicetree/bindings/interrupt-controller/irq-lp8x4x.txt
new file mode 100644
index 0000000..c8940d2
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/irq-lp8x4x.txt
@@ -0,0 +1,49 @@
+ICP DAS LP-8x4x FPGA Interrupt Controller
+
+ICP DAS LP-8x4x contains FPGA chip. The chip functions as a interrupt
+source providing 16 additional interrupts among other things.
+
+Required properties:
+- compatible : should be "icpdas,irq-lp8x4x"
+
+- reg: physical base address of the controller and length of memory mapped
+ region.
+
+- interrupt-controller : identifies the node as an interrupt controller
+
+- #interrupt-cells : should be 1
+
+- interrupts : should provide interrupt
+
+- interrupt-parent : should provide a link to interrupt controller either
+ explicitly and implicitly from a parent node
+
+Example:
+
+ fpga: fpga@17000006 {
+ compatible = "icpdas,irq-lp8x4x";
+ reg = <0x17000006 0x16>;
+ interrupt-parent = <&gpio>;
+ interrupts = <3 IRQ_TYPE_EDGE_RISING>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ status = "okay";
+ };
+
+ uart@17009050 {
+ compatible = "icpdas,uart-lp8x4x";
+ reg = <0x17009050 0x10
+ 0x17009030 0x02>;
+ interrupt-parent = <&fpga>;
+ interrupts = <13>;
+ status = "okay";
+ };
+
+ uart@17009060 {
+ compatible = "icpdas,uart-lp8x4x";
+ reg = <0x17009060 0x10
+ 0x17009032 0x02>;
+ interrupt-parent = <&fpga>;
+ interrupts = <14>;
+ status = "okay";
+ };
diff --git a/arch/arm/boot/dts/pxa27x-lp8x4x.dts b/arch/arm/boot/dts/pxa27x-lp8x4x.dts
index 07856e0..78dfd2e 100644
--- a/arch/arm/boot/dts/pxa27x-lp8x4x.dts
+++ b/arch/arm/boot/dts/pxa27x-lp8x4x.dts
@@ -167,6 +167,16 @@
reg = <0xa000 0x1000
0x901e 0x1>;
};
+
+ fpgairq: irq@9006 {
+ compatible = "icpdas,irq-lp8x4x";
+ reg = <0x9006 0x16>;
+ interrupt-parent = <&gpio>;
+ interrupts = <3 IRQ_TYPE_EDGE_FALLING>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ status = "okay";
+ };
};
};
};
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 3792a1a..7e22729 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -35,6 +35,11 @@ config IMGPDC_IRQ
select GENERIC_IRQ_CHIP
select IRQ_DOMAIN
+config LP8X4X_IRQ
+ bool
+ depends on OF
+ select IRQ_DOMAIN
+
config ORION_IRQCHIP
bool
select IRQ_DOMAIN
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index c60b901..8a28927 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -22,3 +22,4 @@ obj-$(CONFIG_RENESAS_IRQC) += irq-renesas-irqc.o
obj-$(CONFIG_VERSATILE_FPGA_IRQ) += irq-versatile-fpga.o
obj-$(CONFIG_ARCH_VT8500) += irq-vt8500.o
obj-$(CONFIG_TB10X_IRQC) += irq-tb10x.o
+obj-$(CONFIG_LP8X4X_IRQ) += irq-lp8x4x.o
diff --git a/drivers/irqchip/irq-lp8x4x.c b/drivers/irqchip/irq-lp8x4x.c
new file mode 100644
index 0000000..5d44880b
--- /dev/null
+++ b/drivers/irqchip/irq-lp8x4x.c
@@ -0,0 +1,205 @@
+/*
+ * linux/drivers/irqchip/irq-lp8x4x.c
+ *
+ * Support for ICP DAS LP-8x4x FPGA irq
+ * Copyright (C) 2013 Sergei Ianovich <ynvich@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation or any later version.
+ */
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+
+#define EOI 0x00000000
+#define INSINT 0x00000002
+#define ENSYSINT 0x00000004
+#define PRIMINT 0x00000006
+#define SECOINT 0x00000008
+#define ENRISEINT 0x0000000A
+#define CLRRISEINT 0x0000000C
+#define ENHILVINT 0x0000000E
+#define CLRHILVINT 0x00000010
+#define ENFALLINT 0x00000012
+#define CLRFALLINT 0x00000014
+#define LP8X4X_IRQ_MEM_SIZE 0x00000016
+
+static unsigned char irq_sys_enabled;
+static unsigned char irq_high_enabled;
+static void *base;
+static int irq_base;
+static int num_irq = 16;
+
+static void lp8x4x_mask_irq(struct irq_data *d)
+{
+ unsigned mask;
+ int irq = d->irq - irq_base;
+
+ if (irq < 0 || irq > 15) {
+ pr_err("lp8x4x: wrong irq handler for irq %i\n", d->irq);
+ return;
+ }
+
+ if (irq < 8) {
+ irq_high_enabled &= ~(1 << irq);
+
+ mask = ioread8(base + ENHILVINT);
+ mask &= ~(1 << irq);
+ iowrite8(mask, base + ENHILVINT);
+ } else {
+ irq -= 8;
+ irq_sys_enabled &= ~(1 << irq);
+
+ mask = ioread8(base + ENSYSINT);
+ mask &= ~(1 << irq);
+ iowrite8(mask, base + ENSYSINT);
+ }
+}
+
+static void lp8x4x_unmask_irq(struct irq_data *d)
+{
+ unsigned mask;
+ int irq = d->irq - irq_base;
+
+ if (irq < 0 || irq > 15) {
+ pr_err("wrong irq handler for irq %i\n", d->irq);
+ return;
+ }
+
+ if (irq < 8) {
+ irq_high_enabled |= 1 << irq;
+ mask = ioread8(base + CLRHILVINT);
+ mask |= 1 << irq;
+ iowrite8(mask, base + CLRHILVINT);
+
+ mask = ioread8(base + ENHILVINT);
+ mask |= 1 << irq;
+ iowrite8(mask, base + ENHILVINT);
+ } else {
+ irq -= 8;
+ irq_sys_enabled |= 1 << irq;
+
+ mask = ioread8(base + SECOINT);
+ mask |= 1 << irq;
+ iowrite8(mask, base + SECOINT);
+
+ mask = ioread8(base + ENSYSINT);
+ mask |= 1 << irq;
+ iowrite8(mask, base + ENSYSINT);
+ }
+}
+
+static struct irq_chip lp8x4x_irq_chip = {
+ .name = "FPGA",
+ .irq_ack = lp8x4x_mask_irq,
+ .irq_mask = lp8x4x_mask_irq,
+ .irq_mask_ack = lp8x4x_mask_irq,
+ .irq_unmask = lp8x4x_unmask_irq,
+};
+
+static void lp8x4x_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+ int loop, n;
+ unsigned long mask;
+ struct irq_chip *chip = irq_desc_get_chip(desc);
+
+ chained_irq_enter(chip, desc);
+
+ do {
+ loop = 0;
+ mask = ioread8(base + CLRHILVINT) & 0xff;
+ mask |= (ioread8(base + SECOINT) & 0x1f) << 8;
+ mask |= (ioread8(base + PRIMINT) & 0xe0) << 8;
+ mask &= (irq_high_enabled | (irq_sys_enabled << 8));
+ for_each_set_bit(n, &mask, BITS_PER_LONG) {
+ loop = 1;
+
+ generic_handle_irq(irq_base + n);
+ }
+ } while (loop);
+
+ iowrite8(0, base + EOI);
+ chained_irq_exit(chip, desc);
+}
+
+static int lp8x4x_irq_domain_map(struct irq_domain *d, unsigned int irq,
+ irq_hw_number_t hw)
+{
+ irq_set_chip_and_handler(irq, &lp8x4x_irq_chip,
+ handle_level_irq);
+ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+ return 0;
+}
+
+const struct irq_domain_ops lp8x4x_irq_domain_ops = {
+ .map = lp8x4x_irq_domain_map,
+ .xlate = irq_domain_xlate_onecell,
+};
+
+static struct of_device_id lp8x4x_irq_dt_ids[] = {
+ { .compatible = "icpdas,irq-lp8x4x", },
+ {}
+};
+
+static int lp8x4x_irq_probe(struct platform_device *pdev)
+{
+ struct resource *rm, *ri;
+ struct device_node *np = pdev->dev.of_node;
+ struct irq_domain *domain;
+
+ rm = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ ri = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (!rm || !ri || resource_size(rm) < LP8X4X_IRQ_MEM_SIZE)
+ return -ENODEV;
+
+ base = devm_ioremap_resource(&pdev->dev, rm);
+ if (!base) {
+ dev_err(&pdev->dev, "Failed to ioremap %p\n", base);
+ return -EFAULT;
+ }
+
+ irq_base = irq_alloc_descs(-1, 0, num_irq, 0);
+ if (irq_base < 0) {
+ dev_err(&pdev->dev, "Failed to allocate IRQ numbers\n");
+ return irq_base;
+ }
+
+ domain = irq_domain_add_legacy(np, num_irq, irq_base, 0,
+ &lp8x4x_irq_domain_ops, NULL);
+ if (!domain) {
+ dev_err(&pdev->dev, "Failed to add IRQ domain\n");
+ return -ENOMEM;
+ }
+
+ iowrite8(0, base + CLRRISEINT);
+ iowrite8(0, base + ENRISEINT);
+ iowrite8(0, base + CLRFALLINT);
+ iowrite8(0, base + ENFALLINT);
+ iowrite8(0, base + CLRHILVINT);
+ iowrite8(0, base + ENHILVINT);
+ iowrite8(0, base + ENSYSINT);
+ iowrite8(0, base + SECOINT);
+
+ irq_set_chained_handler(ri->start, lp8x4x_irq_handler);
+
+ return 0;
+}
+
+static struct platform_driver lp8x4x_irq_driver = {
+ .probe = lp8x4x_irq_probe,
+ .driver = {
+ .name = "irq-lp8x4x",
+ .of_match_table = lp8x4x_irq_dt_ids,
+ },
+};
+
+static int __init lp8x4x_irq_init(void)
+{
+ return platform_driver_register(&lp8x4x_irq_driver);
+}
+postcore_initcall(lp8x4x_irq_init);
--
1.8.4.2
^ permalink raw reply related [flat|nested] 148+ messages in thread
* [PATCH v3 12/21] serial: support for 16550A serial ports on LP-8x4x
[not found] ` <1387309071-22382-1-git-send-email-ynvich@gmail.com>
` (7 preceding siblings ...)
2013-12-17 19:37 ` [PATCH v3 11/21] ARM: pxa: support ICP DAS LP-8x4x FPGA irq Sergei Ianovich
@ 2013-12-17 19:37 ` Sergei Ianovich
2013-12-19 11:18 ` Heikki Krogerus
2013-12-17 19:37 ` [PATCH v3 13/21] misc: support for LP-8x4x custom parallel bus Sergei Ianovich
` (7 subsequent siblings)
16 siblings, 1 reply; 148+ messages in thread
From: Sergei Ianovich @ 2013-12-17 19:37 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel
Cc: Sergei Ianovich, Heikki Krogerus, Rob Herring, Pawel Moll,
Mark Rutland, Ian Campbell, Kumar Gala, Rob Landley, Russell King,
Greg Kroah-Hartman, Jiri Slaby, Grant Likely, Randy Dunlap,
Arnd Bergmann, James Cameron, open list:OPEN FIRMWARE AND...,
open list:DOCUMENTATION, open list:SERIAL DRIVERS
The patch adds support for 3 additional LP-8x4x built-in serial
ports.
The device can also host up to 8 extension cards with 4 serial ports
on each card for a total of 35 ports. However, I don't have
the hardware to test extension cards, so they are not supported, yet.
Signed-off-by: Sergei Ianovich <ynvich@gmail.com>
CC: Heikki Krogerus <heikki.krogerus@linux.intel.com>
---
v2..v3
* no changes (except number 10/16 -> 12/21)
v0..v2
* register platform driver instead of platform device
* use device tree
* use devm helpers where possible
.../devicetree/bindings/serial/lp8x4x-serial.txt | 35 +++++
arch/arm/boot/dts/pxa27x-lp8x4x.dts | 25 ++++
arch/arm/configs/lp8x4x_defconfig | 1 +
drivers/tty/serial/8250/8250_lp8x4x.c | 162 +++++++++++++++++++++
drivers/tty/serial/8250/Kconfig | 12 ++
drivers/tty/serial/8250/Makefile | 1 +
6 files changed, 236 insertions(+)
create mode 100644 Documentation/devicetree/bindings/serial/lp8x4x-serial.txt
create mode 100644 drivers/tty/serial/8250/8250_lp8x4x.c
diff --git a/Documentation/devicetree/bindings/serial/lp8x4x-serial.txt b/Documentation/devicetree/bindings/serial/lp8x4x-serial.txt
new file mode 100644
index 0000000..eed4ffc
--- /dev/null
+++ b/Documentation/devicetree/bindings/serial/lp8x4x-serial.txt
@@ -0,0 +1,35 @@
+UART ports on ICP DAS LP-8x4x
+
+ICP DAS LP-8x4x contains three additional serial ports interfaced via
+Analog Devices ADM213EA chips in addition to 3 serial ports on PXA CPU.
+
+Required properties:
+- compatible : should be "icpdas,uart-lp8x4x"
+
+- reg : should provide 16 byte man IO memory region and 1 byte region for
+ termios
+
+- interrupts : should provide interrupt
+
+- interrupt-parent : should provide a link to interrupt controller either
+ explicitly and implicitly from a parent node
+
+Examples (from pxa27x-lp8x4x.dts):
+
+ uart@17009050 {
+ compatible = "icpdas,uart-lp8x4x";
+ reg = <0x17009050 0x10
+ 0x17009030 0x02>;
+ interrupt-parent = <&fpga>;
+ interrupts = <13>;
+ status = "okay";
+ };
+
+ uart@17009060 {
+ compatible = "icpdas,uart-lp8x4x";
+ reg = <0x17009060 0x10
+ 0x17009032 0x02>;
+ interrupt-parent = <&fpga>;
+ interrupts = <14>;
+ status = "okay";
+ };
diff --git a/arch/arm/boot/dts/pxa27x-lp8x4x.dts b/arch/arm/boot/dts/pxa27x-lp8x4x.dts
index 78dfd2e..ee0d8b7 100644
--- a/arch/arm/boot/dts/pxa27x-lp8x4x.dts
+++ b/arch/arm/boot/dts/pxa27x-lp8x4x.dts
@@ -155,6 +155,7 @@
#address-cells = <1>;
#size-cells = <1>;
ranges = <0 5 0x3000000 0x10000>;
+ interrupt-parent = <&fpgairq>;
rtc@901c {
compatible = "ds,rtc-ds1302";
@@ -177,6 +178,30 @@
interrupt-controller;
status = "okay";
};
+
+ uart@9050 {
+ compatible = "icpdas,uart-lp8x4x";
+ reg = <0x9050 0x10
+ 0x9030 0x02>;
+ interrupts = <13>;
+ status = "okay";
+ };
+
+ uart@9060 {
+ compatible = "icpdas,uart-lp8x4x";
+ reg = <0x9060 0x10
+ 0x9032 0x02>;
+ interrupts = <14>;
+ status = "okay";
+ };
+
+ uart@9070 {
+ compatible = "icpdas,uart-lp8x4x";
+ reg = <0x9070 0x10
+ 0x9034 0x02>;
+ interrupts = <15>;
+ status = "okay";
+ };
};
};
};
diff --git a/arch/arm/configs/lp8x4x_defconfig b/arch/arm/configs/lp8x4x_defconfig
index 17a4e6f..9116ce1 100644
--- a/arch/arm/configs/lp8x4x_defconfig
+++ b/arch/arm/configs/lp8x4x_defconfig
@@ -112,6 +112,7 @@ CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_MANY_PORTS=y
CONFIG_SERIAL_8250_SHARE_IRQ=y
CONFIG_SERIAL_PXA=y
+CONFIG_SERIAL_8250_LP8X4X=m
CONFIG_HW_RANDOM=y
CONFIG_I2C=m
# CONFIG_I2C_COMPAT is not set
diff --git a/drivers/tty/serial/8250/8250_lp8x4x.c b/drivers/tty/serial/8250/8250_lp8x4x.c
new file mode 100644
index 0000000..ec2f215
--- /dev/null
+++ b/drivers/tty/serial/8250/8250_lp8x4x.c
@@ -0,0 +1,162 @@
+/* linux/drivers/tty/serial/8250/8250_lp8x4x.c
+ *
+ * Support for 16550A serial ports on ICP DAS LP-8x4x
+ *
+ * Copyright (C) 2013 Sergei Ianovich <ynvich@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+#include <linux/serial_8250.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+
+struct lp8x4x_serial_data {
+ int line;
+ void *ios_mem;
+};
+
+static void lp8x4x_serial_set_termios(struct uart_port *port,
+ struct ktermios *termios, struct ktermios *old)
+{
+ unsigned int len;
+ unsigned int baud;
+ struct lp8x4x_serial_data *data = port->private_data;
+
+ switch (termios->c_cflag & CSIZE) {
+ case CS5:
+ len = 7;
+ break;
+ case CS6:
+ len = 8;
+ break;
+ case CS7:
+ len = 9;
+ break;
+ default:
+ case CS8:
+ len = 10;
+ break;
+ }
+
+ if (termios->c_cflag & CSTOPB)
+ len++;
+ if (termios->c_cflag & PARENB)
+ len++;
+ if (!(termios->c_cflag & PARODD))
+ len++;
+#ifdef CMSPAR
+ if (termios->c_cflag & CMSPAR)
+ len++;
+#endif
+
+ len -= 9;
+ len &= 3;
+ len <<= 3;
+ /*
+ * Ask the core to calculate the divisor for us.
+ */
+ baud = uart_get_baud_rate(port, termios, old,
+ port->uartclk / 16 / 0xffff,
+ port->uartclk / 16);
+ switch (baud) {
+ case 2400:
+ len |= 1;
+ case 4800:
+ len |= 2;
+ case 19200:
+ len |= 4;
+ case 38400:
+ len |= 5;
+ case 57600:
+ len |= 6;
+ case 115200:
+ len |= 7;
+ case 9600:
+ default:
+ len |= 3;
+ };
+ iowrite8(len, data->ios_mem);
+
+ serial8250_do_set_termios(port, termios, old);
+}
+
+static struct of_device_id lp8x4x_serial_dt_ids[] = {
+ { .compatible = "icpdas,uart-lp8x4x", },
+ {}
+};
+MODULE_DEVICE_TABLE(of, lp8x4x_serial_dt_ids);
+
+static int lp8x4x_serial_probe(struct platform_device *pdev)
+{
+ struct uart_8250_port uart = {};
+ struct lp8x4x_serial_data *data;
+ struct resource *mmres, *mires, *irqres;
+ int ret;
+
+ mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ mires = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ irqres = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (!mmres || !mires || !irqres)
+ return -ENODEV;
+
+ data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ data->ios_mem = devm_ioremap_resource(&pdev->dev, mires);
+ if (!data->ios_mem)
+ return -EFAULT;
+
+ uart.port.iotype = UPIO_MEM;
+ uart.port.mapbase = mmres->start;
+ uart.port.iobase = mmres->start;
+ uart.port.regshift = 1;
+ uart.port.irq = irqres->start;
+ uart.port.flags = UPF_IOREMAP;
+ uart.port.dev = &pdev->dev;
+ uart.port.uartclk = 14745600;
+ uart.port.set_termios = lp8x4x_serial_set_termios;
+ uart.port.private_data = data;
+
+ ret = serial8250_register_8250_port(&uart);
+ if (ret < 0)
+ return ret;
+
+ data->line = ret;
+
+ platform_set_drvdata(pdev, data);
+
+ return 0;
+}
+
+static int lp8x4x_serial_remove(struct platform_device *pdev)
+{
+ struct lp8x4x_serial_data *data = platform_get_drvdata(pdev);
+
+ serial8250_unregister_port(data->line);
+
+ return 0;
+}
+
+static struct platform_driver lp8x4x_serial_driver = {
+ .probe = lp8x4x_serial_probe,
+ .remove = lp8x4x_serial_remove,
+
+ .driver = {
+ .name = "uart-lp8x4x",
+ .owner = THIS_MODULE,
+ .of_match_table = lp8x4x_serial_dt_ids,
+ },
+};
+
+module_platform_driver(lp8x4x_serial_driver);
+
+MODULE_AUTHOR("Sergei Ianovich");
+MODULE_DESCRIPTION("8250 serial port module for LP-8x4x");
+MODULE_LICENSE("GPL");
diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig
index 81bd7c9..9fb0fbb 100644
--- a/drivers/tty/serial/8250/Kconfig
+++ b/drivers/tty/serial/8250/Kconfig
@@ -311,3 +311,15 @@ config SERIAL_PXA
can enable its onboard serial ports by enabling this option.
If you choose M here, the module name will be 8250_pxa.
+
+config SERIAL_8250_LP8X4X
+ tristate "Support 16550A ports on ICP DAS LP-8x4x"
+ depends on OF && SERIAL_8250 && SERIAL_8250_MANY_PORTS && ARCH_PXA
+ select LP8X4X_IRQ
+ help
+ In addition to serial ports on PXA270 SoC, LP-8x4x has 1 dual
+ RS232/RS485 port, 1 RS485 port and 1 RS232 port.
+
+ Say N here, unless you plan to run this kernel on a LP-8x4x system.
+
+ If you choose M here, the module name will be 8250_lp8x4x.
diff --git a/drivers/tty/serial/8250/Makefile b/drivers/tty/serial/8250/Makefile
index b7d1b61..7370bfb 100644
--- a/drivers/tty/serial/8250/Makefile
+++ b/drivers/tty/serial/8250/Makefile
@@ -17,6 +17,7 @@ obj-$(CONFIG_SERIAL_8250_ACCENT) += 8250_accent.o
obj-$(CONFIG_SERIAL_8250_BOCA) += 8250_boca.o
obj-$(CONFIG_SERIAL_8250_EXAR_ST16C554) += 8250_exar_st16c554.o
obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o
+obj-$(CONFIG_SERIAL_8250_LP8X4X) += 8250_lp8x4x.o
obj-$(CONFIG_SERIAL_8250_FSL) += 8250_fsl.o
obj-$(CONFIG_SERIAL_8250_DW) += 8250_dw.o
obj-$(CONFIG_SERIAL_8250_EM) += 8250_em.o
--
1.8.4.2
^ permalink raw reply related [flat|nested] 148+ messages in thread
* [PATCH v3 13/21] misc: support for LP-8x4x custom parallel bus
[not found] ` <1387309071-22382-1-git-send-email-ynvich@gmail.com>
` (8 preceding siblings ...)
2013-12-17 19:37 ` [PATCH v3 12/21] serial: support for 16550A serial ports on LP-8x4x Sergei Ianovich
@ 2013-12-17 19:37 ` Sergei Ianovich
2013-12-17 19:37 ` [PATCH v3 14/21] misc: support for LP-8x4x rotary switch Sergei Ianovich
` (6 subsequent siblings)
16 siblings, 0 replies; 148+ messages in thread
From: Sergei Ianovich @ 2013-12-17 19:37 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel
Cc: Sergei Ianovich, Rob Herring, Pawel Moll, Mark Rutland,
Ian Campbell, Kumar Gala, Rob Landley, Russell King,
Arnd Bergmann, Greg Kroah-Hartman, Grant Likely,
open list:OPEN FIRMWARE AND..., open list:DOCUMENTATION
This patch implements probing for the bus and reporting the number
of available expansion slots.
Signed-off-by: Sergei Ianovich <ynvich@gmail.com>
---
v2..v3
* fixed goto after bus_register
* number change (11/16 -> 13/21)
v0..v2
* use device tree
* use devm helpers where possible
.../devicetree/bindings/misc/lp8x4x-bus.txt | 16 ++
Documentation/misc-devices/lp8x4x_bus.txt | 30 ++++
arch/arm/boot/dts/pxa27x-lp8x4x.dts | 5 +
arch/arm/configs/lp8x4x_defconfig | 1 +
drivers/misc/Kconfig | 13 ++
drivers/misc/Makefile | 1 +
drivers/misc/lp8x4x_bus.c | 167 +++++++++++++++++++++
7 files changed, 233 insertions(+)
create mode 100644 Documentation/devicetree/bindings/misc/lp8x4x-bus.txt
create mode 100644 Documentation/misc-devices/lp8x4x_bus.txt
create mode 100644 drivers/misc/lp8x4x_bus.c
diff --git a/Documentation/devicetree/bindings/misc/lp8x4x-bus.txt b/Documentation/devicetree/bindings/misc/lp8x4x-bus.txt
new file mode 100644
index 0000000..1c87a29
--- /dev/null
+++ b/Documentation/devicetree/bindings/misc/lp8x4x-bus.txt
@@ -0,0 +1,16 @@
+Custom parallel bus on ICP DAS LP-8x4x industrial computers
+
+See Documentation/misc-devices/lp8x4x_bus.txt for details.
+
+Required properties:
+- compatible : should be "icpdas,backplane-lp8x4x"
+
+- reg: physical base address of the slot count register and the length
+ of the memory mapped region.
+
+Example:
+
+ backplane {
+ compatible = "icpdas,backplane-lp8x4x";
+ reg = <0x17009046 0x2>;
+ };
diff --git a/Documentation/misc-devices/lp8x4x_bus.txt b/Documentation/misc-devices/lp8x4x_bus.txt
new file mode 100644
index 0000000..f5392b3
--- /dev/null
+++ b/Documentation/misc-devices/lp8x4x_bus.txt
@@ -0,0 +1,30 @@
+Kernel driver lpx8x4x_bus
+======================
+
+Supported hardare:
+Custom parallel bus on ICP DAS LP-8x4x industrial computers
+
+Data sheet:
+Not freely available
+
+Author:
+Sergei Ianovich <ynvich@gmail.com>
+
+Description
+-----------
+
+http://www.icpdas.com/root/product/solutions/pac/linpac/lp-8x4x_hardware.html
+
+LP-8x4x is an ARM-based industrial computer with a custom parallel bus to
+connect expansion modules with digital input/output, analog input/output,
+serial, CAN and other types of ports.
+
+The bus is implemented by a FPGA.
+
+SYSFS
+-----
+
+/sys/bus/icpdas/devices/backplane:
+
+slot_count
+ RO - shows total number of expansion slots on the device
diff --git a/arch/arm/boot/dts/pxa27x-lp8x4x.dts b/arch/arm/boot/dts/pxa27x-lp8x4x.dts
index ee0d8b7..4ea566c 100644
--- a/arch/arm/boot/dts/pxa27x-lp8x4x.dts
+++ b/arch/arm/boot/dts/pxa27x-lp8x4x.dts
@@ -202,6 +202,11 @@
interrupts = <15>;
status = "okay";
};
+
+ backplane {
+ compatible = "icpdas,backplane-lp8x4x";
+ reg = <0x9046 0x2>;
+ };
};
};
};
diff --git a/arch/arm/configs/lp8x4x_defconfig b/arch/arm/configs/lp8x4x_defconfig
index 9116ce1..c34eb2a 100644
--- a/arch/arm/configs/lp8x4x_defconfig
+++ b/arch/arm/configs/lp8x4x_defconfig
@@ -62,6 +62,7 @@ CONFIG_PROC_DEVICETREE=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_LOOP_MIN_COUNT=2
CONFIG_EEPROM_AT24=m
+CONFIG_LP8X4X_BUS=m
CONFIG_SCSI=y
# CONFIG_SCSI_PROC_FS is not set
CONFIG_BLK_DEV_SD=y
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index a3e291d..e4d52da 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -515,6 +515,19 @@ config SRAM
the genalloc API. It is supposed to be used for small on-chip SRAM
areas found on many SoCs.
+config LP8X4X_BUS
+ tristate "ICP DAS LP-8x4x industrial IO bus"
+ depends on OF && ARCH_PXA
+ select SYSFS
+ ---help---
+ This is a driver for ICP DAS LP-8x4x programmable automation
+ controller. It exposes a custom parallel bus. The bus services
+ data acquisition and control modules.
+
+ Say N, unless you plan to run this kernel on a LP-8x4x system.
+
+ If you say M here, the module will be called lp8x4x_bus.
+
source "drivers/misc/c2port/Kconfig"
source "drivers/misc/eeprom/Kconfig"
source "drivers/misc/cb710/Kconfig"
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index f45473e..7578cff 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -53,3 +53,4 @@ obj-$(CONFIG_VMWARE_VMCI) += vmw_vmci/
obj-$(CONFIG_LATTICE_ECP3_CONFIG) += lattice-ecp3-config.o
obj-$(CONFIG_SRAM) += sram.o
obj-y += mic/
+obj-$(CONFIG_LP8X4X_BUS) += lp8x4x_bus.o
diff --git a/drivers/misc/lp8x4x_bus.c b/drivers/misc/lp8x4x_bus.c
new file mode 100644
index 0000000..7aa55cf
--- /dev/null
+++ b/drivers/misc/lp8x4x_bus.c
@@ -0,0 +1,167 @@
+/*
+ * linux/misc/lp8x4x_bus.c
+ *
+ * Support for ICP DAS LP-8x4x programmable automation controller bus
+ * Copyright (C) 2013 Sergei Ianovich <ynvich@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation or any later version.
+ */
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#define MODULE_NAME "lp8x4x-bus"
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Sergei Ianovich <ynvich@gmail.com>");
+MODULE_DESCRIPTION("ICP DAS LP-8x4x parallel bus driver");
+
+struct lp8x4x_master {
+ unsigned int slot_count;
+ void *count_addr;
+ struct device dev;
+};
+
+static int lp8x4x_match(struct device *dev, struct device_driver *drv)
+{
+ return 1;
+}
+
+static struct bus_type lp8x4x_bus_type = {
+ .name = "icpdas",
+ .match = lp8x4x_match,
+};
+
+static void lp8x4x_master_release(struct device *dev)
+{
+ struct lp8x4x_master *m = container_of(dev, struct lp8x4x_master, dev);
+ WARN_ON(!dev);
+
+ kfree(m);
+}
+
+static ssize_t slot_count_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct lp8x4x_master *m = container_of(dev, struct lp8x4x_master, dev);
+
+ return sprintf(buf, "%u\n", m->slot_count);
+}
+
+static DEVICE_ATTR_RO(slot_count);
+
+static struct attribute *master_dev_attrs[] = {
+ &dev_attr_slot_count.attr,
+ NULL,
+};
+ATTRIBUTE_GROUPS(master_dev);
+
+
+static void devm_lp8x4x_bus_release(struct device *dev, void *res)
+{
+ struct lp8x4x_master *m = *(struct lp8x4x_master **)res;
+
+ dev_dbg(dev, "releasing devices\n");
+ device_unregister(&m->dev);
+ bus_unregister(&lp8x4x_bus_type);
+}
+
+static int __init lp8x4x_bus_probe(struct platform_device *pdev)
+{
+ struct lp8x4x_master *m, **p;
+ struct resource *res;
+ int err = 0;
+
+ m = kzalloc(sizeof(*m), GFP_KERNEL);
+ if (!m)
+ return -ENOMEM;
+
+ p = devres_alloc(devm_lp8x4x_bus_release, sizeof(*p), GFP_KERNEL);
+ if (!p) {
+ err = -ENOMEM;
+ goto err1;
+ }
+ *p = m;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "could not get slot count address\n");
+ err = -ENODEV;
+ goto err2;
+ }
+
+ m->count_addr = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(m->count_addr)) {
+ dev_err(&pdev->dev, "Failed to ioremap slot count address\n");
+ err = PTR_ERR(m->count_addr);
+ goto err2;
+ }
+
+ m->slot_count = ioread8(m->count_addr);
+ switch (m->slot_count) {
+ case 1:
+ case 4:
+ break;
+ case 7:
+ m->slot_count = 8;
+ break;
+ default:
+ dev_err(&pdev->dev, "unexpected slot number(%u)",
+ m->slot_count);
+ err = -ENODEV;
+ goto err2;
+ };
+
+ dev_info(&pdev->dev, "found bus with up to %u slots\n", m->slot_count);
+
+ err = bus_register(&lp8x4x_bus_type);
+ if (err < 0) {
+ dev_err(&pdev->dev, "failed to register bus type\n");
+ goto err2;
+ }
+
+ m->dev.bus = &lp8x4x_bus_type;
+ dev_set_name(&m->dev, "backplane");
+ m->dev.parent = &pdev->dev;
+ m->dev.release = lp8x4x_master_release;
+ m->dev.groups = master_dev_groups;
+
+ err = device_register(&m->dev);
+ if (err < 0) {
+ dev_err(&pdev->dev, "failed to register backplane device\n");
+ goto err3;
+ }
+
+ devres_add(&pdev->dev, p);
+ return 0;
+
+err3:
+ bus_unregister(&lp8x4x_bus_type);
+err2:
+ devres_free(p);
+err1:
+ kfree(m);
+ return err;
+}
+
+static const struct of_device_id lp8x4x_bus_dt_ids[] = {
+ { .compatible = "icpdas,backplane-lp8x4x" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, lp8x4x_bus_dt_ids);
+
+static struct platform_driver lp8x4x_bus_driver = {
+ .driver = {
+ .name = MODULE_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = lp8x4x_bus_dt_ids,
+ },
+};
+
+module_platform_driver_probe(lp8x4x_bus_driver, lp8x4x_bus_probe);
--
1.8.4.2
^ permalink raw reply related [flat|nested] 148+ messages in thread
* [PATCH v3 14/21] misc: support for LP-8x4x rotary switch
[not found] ` <1387309071-22382-1-git-send-email-ynvich@gmail.com>
` (9 preceding siblings ...)
2013-12-17 19:37 ` [PATCH v3 13/21] misc: support for LP-8x4x custom parallel bus Sergei Ianovich
@ 2013-12-17 19:37 ` Sergei Ianovich
2013-12-17 19:37 ` [PATCH v3 15/21] misc: support for LP-8x4x DIP switch Sergei Ianovich
` (5 subsequent siblings)
16 siblings, 0 replies; 148+ messages in thread
From: Sergei Ianovich @ 2013-12-17 19:37 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel
Cc: Sergei Ianovich, Rob Herring, Pawel Moll, Mark Rutland,
Ian Campbell, Kumar Gala, Rob Landley, Russell King,
Arnd Bergmann, Greg Kroah-Hartman, open list:OPEN FIRMWARE AND...,
open list:DOCUMENTATION
Reorder backplane resources by start address.
Reorder backplane attributes alphabetically.
Signed-off-by: Sergei Ianovich <ynvich@gmail.com>
---
v2..v3
* new patch
.../devicetree/bindings/misc/lp8x4x-bus.txt | 8 ++--
Documentation/misc-devices/lp8x4x_bus.txt | 3 ++
arch/arm/boot/dts/pxa27x-lp8x4x.dts | 3 +-
drivers/misc/lp8x4x_bus.c | 43 ++++++++++++++++++----
4 files changed, 45 insertions(+), 12 deletions(-)
diff --git a/Documentation/devicetree/bindings/misc/lp8x4x-bus.txt b/Documentation/devicetree/bindings/misc/lp8x4x-bus.txt
index 1c87a29..8a55020 100644
--- a/Documentation/devicetree/bindings/misc/lp8x4x-bus.txt
+++ b/Documentation/devicetree/bindings/misc/lp8x4x-bus.txt
@@ -5,12 +5,14 @@ See Documentation/misc-devices/lp8x4x_bus.txt for details.
Required properties:
- compatible : should be "icpdas,backplane-lp8x4x"
-- reg: physical base address of the slot count register and the length
- of the memory mapped region.
+- reg: physical base addresses and region lengths of
+ * the rotary switch
+ * the slot count register
Example:
backplane {
compatible = "icpdas,backplane-lp8x4x";
- reg = <0x17009046 0x2>;
+ reg = <0x0 0x2
+ 0x9046 0x2>;
};
diff --git a/Documentation/misc-devices/lp8x4x_bus.txt b/Documentation/misc-devices/lp8x4x_bus.txt
index f5392b3..bea435b 100644
--- a/Documentation/misc-devices/lp8x4x_bus.txt
+++ b/Documentation/misc-devices/lp8x4x_bus.txt
@@ -26,5 +26,8 @@ SYSFS
/sys/bus/icpdas/devices/backplane:
+rotary
+ RO - shows position of LP-8x4x rotary switch (0-9)
+
slot_count
RO - shows total number of expansion slots on the device
diff --git a/arch/arm/boot/dts/pxa27x-lp8x4x.dts b/arch/arm/boot/dts/pxa27x-lp8x4x.dts
index 4ea566c..b50ce43 100644
--- a/arch/arm/boot/dts/pxa27x-lp8x4x.dts
+++ b/arch/arm/boot/dts/pxa27x-lp8x4x.dts
@@ -205,7 +205,8 @@
backplane {
compatible = "icpdas,backplane-lp8x4x";
- reg = <0x9046 0x2>;
+ reg = <0x0 0x2
+ 0x9046 0x2>;
};
};
};
diff --git a/drivers/misc/lp8x4x_bus.c b/drivers/misc/lp8x4x_bus.c
index 7aa55cf..18ca8f8 100644
--- a/drivers/misc/lp8x4x_bus.c
+++ b/drivers/misc/lp8x4x_bus.c
@@ -25,6 +25,7 @@ MODULE_DESCRIPTION("ICP DAS LP-8x4x parallel bus driver");
struct lp8x4x_master {
unsigned int slot_count;
void *count_addr;
+ void *rotary_addr;
struct device dev;
};
@@ -56,8 +57,19 @@ static ssize_t slot_count_show(struct device *dev,
static DEVICE_ATTR_RO(slot_count);
+static ssize_t rotary_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct lp8x4x_master *m = container_of(dev, struct lp8x4x_master, dev);
+
+ return sprintf(buf, "%u\n", (ioread8(m->rotary_addr) ^ 0xf) & 0xf);
+}
+
+static DEVICE_ATTR_RO(rotary);
+
static struct attribute *master_dev_attrs[] = {
&dev_attr_slot_count.attr,
+ &dev_attr_rotary.attr,
NULL,
};
ATTRIBUTE_GROUPS(master_dev);
@@ -76,6 +88,7 @@ static int __init lp8x4x_bus_probe(struct platform_device *pdev)
{
struct lp8x4x_master *m, **p;
struct resource *res;
+ int r = 0;
int err = 0;
m = kzalloc(sizeof(*m), GFP_KERNEL);
@@ -89,18 +102,32 @@ static int __init lp8x4x_bus_probe(struct platform_device *pdev)
}
*p = m;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ res = platform_get_resource(pdev, IORESOURCE_MEM, r++);
+ if (!res) {
+ dev_err(&pdev->dev, "Failed to get rotary address\n");
+ err = -ENODEV;
+ goto err_free;
+ }
+
+ m->rotary_addr = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(m->rotary_addr)) {
+ dev_err(&pdev->dev, "Failed to ioremap rotary address\n");
+ err = PTR_ERR(m->rotary_addr);
+ goto err_free;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, r++);
if (!res) {
dev_err(&pdev->dev, "could not get slot count address\n");
err = -ENODEV;
- goto err2;
+ goto err_free;
}
m->count_addr = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(m->count_addr)) {
dev_err(&pdev->dev, "Failed to ioremap slot count address\n");
err = PTR_ERR(m->count_addr);
- goto err2;
+ goto err_free;
}
m->slot_count = ioread8(m->count_addr);
@@ -115,7 +142,7 @@ static int __init lp8x4x_bus_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "unexpected slot number(%u)",
m->slot_count);
err = -ENODEV;
- goto err2;
+ goto err_free;
};
dev_info(&pdev->dev, "found bus with up to %u slots\n", m->slot_count);
@@ -123,7 +150,7 @@ static int __init lp8x4x_bus_probe(struct platform_device *pdev)
err = bus_register(&lp8x4x_bus_type);
if (err < 0) {
dev_err(&pdev->dev, "failed to register bus type\n");
- goto err2;
+ goto err_free;
}
m->dev.bus = &lp8x4x_bus_type;
@@ -135,15 +162,15 @@ static int __init lp8x4x_bus_probe(struct platform_device *pdev)
err = device_register(&m->dev);
if (err < 0) {
dev_err(&pdev->dev, "failed to register backplane device\n");
- goto err3;
+ goto err_bus;
}
devres_add(&pdev->dev, p);
return 0;
-err3:
+err_bus:
bus_unregister(&lp8x4x_bus_type);
-err2:
+err_free:
devres_free(p);
err1:
kfree(m);
--
1.8.4.2
^ permalink raw reply related [flat|nested] 148+ messages in thread
* [PATCH v3 15/21] misc: support for LP-8x4x DIP switch
[not found] ` <1387309071-22382-1-git-send-email-ynvich@gmail.com>
` (10 preceding siblings ...)
2013-12-17 19:37 ` [PATCH v3 14/21] misc: support for LP-8x4x rotary switch Sergei Ianovich
@ 2013-12-17 19:37 ` Sergei Ianovich
2013-12-17 19:37 ` [PATCH v3 16/21] misc: support for writing to LP-8x4x EEPROM Sergei Ianovich
` (4 subsequent siblings)
16 siblings, 0 replies; 148+ messages in thread
From: Sergei Ianovich @ 2013-12-17 19:37 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel
Cc: Sergei Ianovich, Rob Herring, Pawel Moll, Mark Rutland,
Ian Campbell, Kumar Gala, Rob Landley, Russell King,
Arnd Bergmann, Greg Kroah-Hartman, open list:OPEN FIRMWARE AND...,
open list:DOCUMENTATION
Signed-off-by: Sergei Ianovich <ynvich@gmail.com>
---
v2..v3
* new patch
.../devicetree/bindings/misc/lp8x4x-bus.txt | 2 ++
Documentation/misc-devices/lp8x4x_bus.txt | 3 +++
arch/arm/boot/dts/pxa27x-lp8x4x.dts | 1 +
drivers/misc/lp8x4x_bus.c | 26 ++++++++++++++++++++++
4 files changed, 32 insertions(+)
diff --git a/Documentation/devicetree/bindings/misc/lp8x4x-bus.txt b/Documentation/devicetree/bindings/misc/lp8x4x-bus.txt
index 8a55020..1b1776a 100644
--- a/Documentation/devicetree/bindings/misc/lp8x4x-bus.txt
+++ b/Documentation/devicetree/bindings/misc/lp8x4x-bus.txt
@@ -7,6 +7,7 @@ Required properties:
- reg: physical base addresses and region lengths of
* the rotary switch
+ * the 8bit DIP switch
* the slot count register
Example:
@@ -14,5 +15,6 @@ Example:
backplane {
compatible = "icpdas,backplane-lp8x4x";
reg = <0x0 0x2
+ 0x9002 0x2
0x9046 0x2>;
};
diff --git a/Documentation/misc-devices/lp8x4x_bus.txt b/Documentation/misc-devices/lp8x4x_bus.txt
index bea435b..829781b 100644
--- a/Documentation/misc-devices/lp8x4x_bus.txt
+++ b/Documentation/misc-devices/lp8x4x_bus.txt
@@ -26,6 +26,9 @@ SYSFS
/sys/bus/icpdas/devices/backplane:
+dip
+ RO - shows status of LP-8x4x 8bit DIP switch
+
rotary
RO - shows position of LP-8x4x rotary switch (0-9)
diff --git a/arch/arm/boot/dts/pxa27x-lp8x4x.dts b/arch/arm/boot/dts/pxa27x-lp8x4x.dts
index b50ce43..09a6bc9 100644
--- a/arch/arm/boot/dts/pxa27x-lp8x4x.dts
+++ b/arch/arm/boot/dts/pxa27x-lp8x4x.dts
@@ -206,6 +206,7 @@
backplane {
compatible = "icpdas,backplane-lp8x4x";
reg = <0x0 0x2
+ 0x9002 0x2
0x9046 0x2>;
};
};
diff --git a/drivers/misc/lp8x4x_bus.c b/drivers/misc/lp8x4x_bus.c
index 18ca8f8..dfbc8c4 100644
--- a/drivers/misc/lp8x4x_bus.c
+++ b/drivers/misc/lp8x4x_bus.c
@@ -26,6 +26,7 @@ struct lp8x4x_master {
unsigned int slot_count;
void *count_addr;
void *rotary_addr;
+ void *dip_addr;
struct device dev;
};
@@ -67,9 +68,20 @@ static ssize_t rotary_show(struct device *dev,
static DEVICE_ATTR_RO(rotary);
+static ssize_t dip_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct lp8x4x_master *m = container_of(dev, struct lp8x4x_master, dev);
+
+ return sprintf(buf, "0x%02x\n", ioread8(m->dip_addr) ^ 0xff);
+}
+
+static DEVICE_ATTR_RO(dip);
+
static struct attribute *master_dev_attrs[] = {
&dev_attr_slot_count.attr,
&dev_attr_rotary.attr,
+ &dev_attr_dip.attr,
NULL,
};
ATTRIBUTE_GROUPS(master_dev);
@@ -118,6 +130,20 @@ static int __init lp8x4x_bus_probe(struct platform_device *pdev)
res = platform_get_resource(pdev, IORESOURCE_MEM, r++);
if (!res) {
+ dev_err(&pdev->dev, "Failed to get DIP switch address\n");
+ err = -ENODEV;
+ goto err_free;
+ }
+
+ m->dip_addr = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(m->dip_addr)) {
+ dev_err(&pdev->dev, "Failed to ioremap DIP switch address\n");
+ err = PTR_ERR(m->dip_addr);
+ goto err_free;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, r++);
+ if (!res) {
dev_err(&pdev->dev, "could not get slot count address\n");
err = -ENODEV;
goto err_free;
--
1.8.4.2
^ permalink raw reply related [flat|nested] 148+ messages in thread
* [PATCH v3 16/21] misc: support for writing to LP-8x4x EEPROM
[not found] ` <1387309071-22382-1-git-send-email-ynvich@gmail.com>
` (11 preceding siblings ...)
2013-12-17 19:37 ` [PATCH v3 15/21] misc: support for LP-8x4x DIP switch Sergei Ianovich
@ 2013-12-17 19:37 ` Sergei Ianovich
2013-12-17 19:37 ` [PATCH v3 17/21] misc: support for serial slots in LP-8x4x Sergei Ianovich
` (3 subsequent siblings)
16 siblings, 0 replies; 148+ messages in thread
From: Sergei Ianovich @ 2013-12-17 19:37 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel
Cc: Sergei Ianovich, Rob Herring, Pawel Moll, Mark Rutland,
Ian Campbell, Kumar Gala, Rob Landley, Russell King,
Arnd Bergmann, Greg Kroah-Hartman, open list:OPEN FIRMWARE AND...,
open list:DOCUMENTATION
at24c128 write protection is implemented by a separate GPIO line.
EEPROM driver doesn't provide this option, so we implement it
in the board-specific device.
Signed-off-by: Sergei Ianovich <ynvich@gmail.com>
---
v2..v3
* new patch
.../devicetree/bindings/misc/lp8x4x-bus.txt | 3 ++
Documentation/misc-devices/lp8x4x_bus.txt | 3 ++
arch/arm/boot/dts/pxa27x-lp8x4x.dts | 1 +
drivers/misc/lp8x4x_bus.c | 50 ++++++++++++++++++++++
4 files changed, 57 insertions(+)
diff --git a/Documentation/devicetree/bindings/misc/lp8x4x-bus.txt b/Documentation/devicetree/bindings/misc/lp8x4x-bus.txt
index 1b1776a..b0fb145 100644
--- a/Documentation/devicetree/bindings/misc/lp8x4x-bus.txt
+++ b/Documentation/devicetree/bindings/misc/lp8x4x-bus.txt
@@ -10,6 +10,8 @@ Required properties:
* the 8bit DIP switch
* the slot count register
+- eeprom-gpios : should point to active-low write enable GPIO
+
Example:
backplane {
@@ -17,4 +19,5 @@ Example:
reg = <0x0 0x2
0x9002 0x2
0x9046 0x2>;
+ eeprom-gpios = <&gpio 4 0>;
};
diff --git a/Documentation/misc-devices/lp8x4x_bus.txt b/Documentation/misc-devices/lp8x4x_bus.txt
index 829781b..78ea0a89 100644
--- a/Documentation/misc-devices/lp8x4x_bus.txt
+++ b/Documentation/misc-devices/lp8x4x_bus.txt
@@ -29,6 +29,9 @@ SYSFS
dip
RO - shows status of LP-8x4x 8bit DIP switch
+eeprom_write_enable
+ RW - controls write access to board's EEPROM (1 - enable)
+
rotary
RO - shows position of LP-8x4x rotary switch (0-9)
diff --git a/arch/arm/boot/dts/pxa27x-lp8x4x.dts b/arch/arm/boot/dts/pxa27x-lp8x4x.dts
index 09a6bc9..52f0036 100644
--- a/arch/arm/boot/dts/pxa27x-lp8x4x.dts
+++ b/arch/arm/boot/dts/pxa27x-lp8x4x.dts
@@ -208,6 +208,7 @@
reg = <0x0 0x2
0x9002 0x2
0x9046 0x2>;
+ eeprom-gpios = <&gpio 4 0>;
};
};
};
diff --git a/drivers/misc/lp8x4x_bus.c b/drivers/misc/lp8x4x_bus.c
index dfbc8c4..567fe078 100644
--- a/drivers/misc/lp8x4x_bus.c
+++ b/drivers/misc/lp8x4x_bus.c
@@ -9,6 +9,7 @@
* published by the Free Software Foundation or any later version.
*/
#include <linux/err.h>
+#include <linux/gpio/consumer.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/list.h>
@@ -27,6 +28,7 @@ struct lp8x4x_master {
void *count_addr;
void *rotary_addr;
void *dip_addr;
+ struct gpio_desc *eeprom_nWE;
struct device dev;
};
@@ -68,6 +70,40 @@ static ssize_t rotary_show(struct device *dev,
static DEVICE_ATTR_RO(rotary);
+static ssize_t eeprom_write_enable_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct lp8x4x_master *m = container_of(dev, struct lp8x4x_master, dev);
+
+ return sprintf(buf, "%u\n", !gpiod_get_value(m->eeprom_nWE));
+}
+
+static ssize_t eeprom_write_enable_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct lp8x4x_master *m = container_of(dev, struct lp8x4x_master, dev);
+ unsigned int val = 0;
+ int err;
+
+ if (!buf)
+ return count;
+
+ if (0 == count)
+ return count;
+
+ err = kstrtouint(buf, 10, &val);
+ if (err != 0) {
+ dev_err(dev, "Bad input %s\n", buf);
+ return count;
+ }
+
+ gpiod_set_value(m->eeprom_nWE, !val);
+
+ return count;
+}
+
+static DEVICE_ATTR_RW(eeprom_write_enable);
+
static ssize_t dip_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -81,6 +117,7 @@ static DEVICE_ATTR_RO(dip);
static struct attribute *master_dev_attrs[] = {
&dev_attr_slot_count.attr,
&dev_attr_rotary.attr,
+ &dev_attr_eeprom_write_enable.attr,
&dev_attr_dip.attr,
NULL,
};
@@ -156,6 +193,19 @@ static int __init lp8x4x_bus_probe(struct platform_device *pdev)
goto err_free;
}
+ m->eeprom_nWE = devm_gpiod_get(&pdev->dev, "eeprom");
+ if (IS_ERR(m->eeprom_nWE)) {
+ err = PTR_ERR(m->eeprom_nWE);
+ dev_err(&pdev->dev, "Failed to get eeprom GPIO\n");
+ goto err_free;
+ }
+
+ err = gpiod_direction_output(m->eeprom_nWE, 1);
+ if (err < 0) {
+ dev_err(&pdev->dev, "Failed to set eeprom GPIO output\n");
+ goto err_free;
+ }
+
m->slot_count = ioread8(m->count_addr);
switch (m->slot_count) {
case 1:
--
1.8.4.2
^ permalink raw reply related [flat|nested] 148+ messages in thread
* [PATCH v3 17/21] misc: support for serial slots in LP-8x4x
[not found] ` <1387309071-22382-1-git-send-email-ynvich@gmail.com>
` (12 preceding siblings ...)
2013-12-17 19:37 ` [PATCH v3 16/21] misc: support for writing to LP-8x4x EEPROM Sergei Ianovich
@ 2013-12-17 19:37 ` Sergei Ianovich
2013-12-17 19:37 ` [PATCH v3 18/21] misc: support for parallel " Sergei Ianovich
` (2 subsequent siblings)
16 siblings, 0 replies; 148+ messages in thread
From: Sergei Ianovich @ 2013-12-17 19:37 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel
Cc: Sergei Ianovich, Rob Herring, Pawel Moll, Mark Rutland,
Ian Campbell, Kumar Gala, Rob Landley, Russell King,
Arnd Bergmann, Greg Kroah-Hartman, open list:OPEN FIRMWARE AND...,
open list:DOCUMENTATION
Serial modules (I-870xxW series) implement DCON protocol which
allows one-master-many-slaves configuration over RS-485. When
these modules are installed into the device, they could be
accessed using the 2nd PXA built-in UART port (/dev/ttyS1).
However, it seems that addresses are not processed by the modules.
So the parallel bus needs to select which slot is connected.
Signed-off-by: Sergei Ianovich <ynvich@gmail.com>
---
v2..v3
* no changes (except number 12/16 -> 17/21)
v0..v2
* use device tree
* use devm helpers where possible
.../devicetree/bindings/misc/lp8x4x-bus.txt | 2 +
Documentation/misc-devices/lp8x4x_bus.txt | 15 +++++-
arch/arm/boot/dts/pxa27x-lp8x4x.dts | 1 +
drivers/misc/lp8x4x_bus.c | 63 ++++++++++++++++++++++
4 files changed, 80 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/misc/lp8x4x-bus.txt b/Documentation/devicetree/bindings/misc/lp8x4x-bus.txt
index b0fb145..24a8c62 100644
--- a/Documentation/devicetree/bindings/misc/lp8x4x-bus.txt
+++ b/Documentation/devicetree/bindings/misc/lp8x4x-bus.txt
@@ -8,6 +8,7 @@ Required properties:
- reg: physical base addresses and region lengths of
* the rotary switch
* the 8bit DIP switch
+ * the serial slot select register
* the slot count register
- eeprom-gpios : should point to active-low write enable GPIO
@@ -18,6 +19,7 @@ Example:
compatible = "icpdas,backplane-lp8x4x";
reg = <0x0 0x2
0x9002 0x2
+ 0x9004 0x2
0x9046 0x2>;
eeprom-gpios = <&gpio 4 0>;
};
diff --git a/Documentation/misc-devices/lp8x4x_bus.txt b/Documentation/misc-devices/lp8x4x_bus.txt
index 78ea0a89..7b86797 100644
--- a/Documentation/misc-devices/lp8x4x_bus.txt
+++ b/Documentation/misc-devices/lp8x4x_bus.txt
@@ -19,13 +19,26 @@ LP-8x4x is an ARM-based industrial computer with a custom parallel bus to
connect expansion modules with digital input/output, analog input/output,
serial, CAN and other types of ports.
-The bus is implemented by a FPGA.
+The bus is implemented by a FPGA. There are two major groups of expansion
+modules: serial and parallel.
+
+Serial modules (I-870xxW series) implement DCON protocol which allows one-
+master-many-slaves configuration over RS-485. When these modules are installed
+into the device, they could be accessed using the 2nd PXA built-in UART port
+(/dev/ttyS1). However, it seems that addresses are not processed by
+the modules. So the parallel bus needs to select which slot is connected.
SYSFS
-----
/sys/bus/icpdas/devices/backplane:
+active_slot
+ RW - connects the select slot for serial communications. If there
+ is a parallel module in the selected slot, it simply ignores
+ incoming packets. So it is safe to activate any available
+ slot.
+
dip
RO - shows status of LP-8x4x 8bit DIP switch
diff --git a/arch/arm/boot/dts/pxa27x-lp8x4x.dts b/arch/arm/boot/dts/pxa27x-lp8x4x.dts
index 52f0036..a6adf45 100644
--- a/arch/arm/boot/dts/pxa27x-lp8x4x.dts
+++ b/arch/arm/boot/dts/pxa27x-lp8x4x.dts
@@ -207,6 +207,7 @@
compatible = "icpdas,backplane-lp8x4x";
reg = <0x0 0x2
0x9002 0x2
+ 0x9004 0x2
0x9046 0x2>;
eeprom-gpios = <&gpio 4 0>;
};
diff --git a/drivers/misc/lp8x4x_bus.c b/drivers/misc/lp8x4x_bus.c
index 567fe078..e805640 100644
--- a/drivers/misc/lp8x4x_bus.c
+++ b/drivers/misc/lp8x4x_bus.c
@@ -29,6 +29,8 @@ struct lp8x4x_master {
void *rotary_addr;
void *dip_addr;
struct gpio_desc *eeprom_nWE;
+ unsigned int active_slot;
+ void *switch_addr;
struct device dev;
};
@@ -47,6 +49,9 @@ static void lp8x4x_master_release(struct device *dev)
struct lp8x4x_master *m = container_of(dev, struct lp8x4x_master, dev);
WARN_ON(!dev);
+ /* Disable serial communications */
+ iowrite8(0xff, m->switch_addr);
+
kfree(m);
}
@@ -114,11 +119,52 @@ static ssize_t dip_show(struct device *dev,
static DEVICE_ATTR_RO(dip);
+static ssize_t active_slot_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct lp8x4x_master *m = container_of(dev, struct lp8x4x_master, dev);
+
+ return sprintf(buf, "%u\n", m->active_slot);
+}
+
+static ssize_t active_slot_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct lp8x4x_master *m = container_of(dev, struct lp8x4x_master, dev);
+ unsigned int active_slot = 0;
+ int err;
+
+ if (!buf)
+ return count;
+ if (0 == count)
+ return count;
+
+ err = kstrtouint(buf, 10, &active_slot);
+ if (err != 0 || active_slot > m->slot_count) {
+ dev_err(dev, "slot number is out of range 1..%u\n",
+ m->slot_count);
+ return count;
+ }
+
+ if (!active_slot) {
+ m->active_slot = 0;
+ iowrite8(0xff, m->switch_addr);
+ return count;
+ }
+
+ m->active_slot = active_slot;
+ iowrite8((1 << (m->active_slot - 1)) ^ 0xff, m->switch_addr);
+ return count;
+}
+
+static DEVICE_ATTR_RW(active_slot);
+
static struct attribute *master_dev_attrs[] = {
&dev_attr_slot_count.attr,
&dev_attr_rotary.attr,
&dev_attr_eeprom_write_enable.attr,
&dev_attr_dip.attr,
+ &dev_attr_active_slot.attr,
NULL,
};
ATTRIBUTE_GROUPS(master_dev);
@@ -181,6 +227,20 @@ static int __init lp8x4x_bus_probe(struct platform_device *pdev)
res = platform_get_resource(pdev, IORESOURCE_MEM, r++);
if (!res) {
+ dev_err(&pdev->dev, "Failed to get slot switch address\n");
+ err = -ENODEV;
+ goto err_free;
+ }
+
+ m->switch_addr = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(m->switch_addr)) {
+ dev_err(&pdev->dev, "Failed to ioremap switch address\n");
+ err = PTR_ERR(m->switch_addr);
+ goto err_free;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, r++);
+ if (!res) {
dev_err(&pdev->dev, "could not get slot count address\n");
err = -ENODEV;
goto err_free;
@@ -223,6 +283,9 @@ static int __init lp8x4x_bus_probe(struct platform_device *pdev)
dev_info(&pdev->dev, "found bus with up to %u slots\n", m->slot_count);
+ /* Disable serial communications until explicitly enabled */
+ iowrite8(0xff, m->switch_addr);
+
err = bus_register(&lp8x4x_bus_type);
if (err < 0) {
dev_err(&pdev->dev, "failed to register bus type\n");
--
1.8.4.2
^ permalink raw reply related [flat|nested] 148+ messages in thread
* [PATCH v3 18/21] misc: support for parallel slots in LP-8x4x
[not found] ` <1387309071-22382-1-git-send-email-ynvich@gmail.com>
` (13 preceding siblings ...)
2013-12-17 19:37 ` [PATCH v3 17/21] misc: support for serial slots in LP-8x4x Sergei Ianovich
@ 2013-12-17 19:37 ` Sergei Ianovich
[not found] ` <1397668411-27162-1-git-send-email-ynvich@gmail.com>
[not found] ` <1449700088-28076-1-git-send-email-ynvich@gmail.com>
16 siblings, 0 replies; 148+ messages in thread
From: Sergei Ianovich @ 2013-12-17 19:37 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel
Cc: Sergei Ianovich, Rob Herring, Pawel Moll, Mark Rutland,
Ian Campbell, Kumar Gala, Rob Landley, Russell King,
Arnd Bergmann, Greg Kroah-Hartman, open list:OPEN FIRMWARE AND...,
open list:DOCUMENTATION
This patch enumerates parallel modules in expansion slots and exposes
model numbers via sysfs.
Signed-off-by: Sergei Ianovich <ynvich@gmail.com>
---
v2..v3
* no changes (except number 13/16 -> 18/21)
v0..v2
* use device tree
* use devm helpers where possible
.../devicetree/bindings/misc/lp8x4x-bus.txt | 9 ++
Documentation/misc-devices/lp8x4x_bus.txt | 8 ++
arch/arm/boot/dts/pxa27x-lp8x4x.dts | 8 ++
drivers/misc/lp8x4x_bus.c | 119 +++++++++++++++++++++
4 files changed, 144 insertions(+)
diff --git a/Documentation/devicetree/bindings/misc/lp8x4x-bus.txt b/Documentation/devicetree/bindings/misc/lp8x4x-bus.txt
index 24a8c62..75ac3b2 100644
--- a/Documentation/devicetree/bindings/misc/lp8x4x-bus.txt
+++ b/Documentation/devicetree/bindings/misc/lp8x4x-bus.txt
@@ -7,6 +7,7 @@ Required properties:
- reg: physical base addresses and region lengths of
* the rotary switch
+ * 8 plugable industrial IO slots
* the 8bit DIP switch
* the serial slot select register
* the slot count register
@@ -18,6 +19,14 @@ Example:
backplane {
compatible = "icpdas,backplane-lp8x4x";
reg = <0x0 0x2
+ 0x1000 0x10
+ 0x2000 0x10
+ 0x3000 0x10
+ 0x4000 0x10
+ 0x5000 0x10
+ 0x6000 0x10
+ 0x7000 0x10
+ 0x8000 0x10
0x9002 0x2
0x9004 0x2
0x9046 0x2>;
diff --git a/Documentation/misc-devices/lp8x4x_bus.txt b/Documentation/misc-devices/lp8x4x_bus.txt
index 7b86797..09380fd 100644
--- a/Documentation/misc-devices/lp8x4x_bus.txt
+++ b/Documentation/misc-devices/lp8x4x_bus.txt
@@ -28,6 +28,9 @@ into the device, they could be accessed using the 2nd PXA built-in UART port
(/dev/ttyS1). However, it seems that addresses are not processed by
the modules. So the parallel bus needs to select which slot is connected.
+Parallel modules allow much faster communication. There are accessed using
+IO memory through the FPGA. Their ports are exposed via sysfs.
+
SYSFS
-----
@@ -50,3 +53,8 @@ rotary
slot_count
RO - shows total number of expansion slots on the device
+
+/sys/bus/icpdas/devices/slot%02i:
+
+model
+ RO - shows expansion module model number
diff --git a/arch/arm/boot/dts/pxa27x-lp8x4x.dts b/arch/arm/boot/dts/pxa27x-lp8x4x.dts
index a6adf45..f13b276 100644
--- a/arch/arm/boot/dts/pxa27x-lp8x4x.dts
+++ b/arch/arm/boot/dts/pxa27x-lp8x4x.dts
@@ -206,6 +206,14 @@
backplane {
compatible = "icpdas,backplane-lp8x4x";
reg = <0x0 0x2
+ 0x1000 0x10
+ 0x2000 0x10
+ 0x3000 0x10
+ 0x4000 0x10
+ 0x5000 0x10
+ 0x6000 0x10
+ 0x7000 0x10
+ 0x8000 0x10
0x9002 0x2
0x9004 0x2
0x9046 0x2>;
diff --git a/drivers/misc/lp8x4x_bus.c b/drivers/misc/lp8x4x_bus.c
index e805640..59dc767 100644
--- a/drivers/misc/lp8x4x_bus.c
+++ b/drivers/misc/lp8x4x_bus.c
@@ -23,6 +23,13 @@ MODULE_LICENSE("GPL");
MODULE_AUTHOR("Sergei Ianovich <ynvich@gmail.com>");
MODULE_DESCRIPTION("ICP DAS LP-8x4x parallel bus driver");
+struct lp8x4x_slot {
+ void *data_addr;
+ unsigned int model;
+ struct device dev;
+};
+
+#define LP8X4X_MAX_SLOT_COUNT 8
struct lp8x4x_master {
unsigned int slot_count;
void *count_addr;
@@ -31,9 +38,45 @@ struct lp8x4x_master {
struct gpio_desc *eeprom_nWE;
unsigned int active_slot;
void *switch_addr;
+ struct lp8x4x_slot slot[LP8X4X_MAX_SLOT_COUNT];
struct device dev;
};
+static unsigned char lp8x4x_model[256] = {
+ 0, 0, 0, 0x11, 0, 0x18, 0x13, 0x11,
+ 0x0e, 0x11, 0, 0, 0, 0x5a, 0x5b, 0x5c,
+ 0x3c, 0x44, 0x34, 0x3a, 0x39, 0x36, 0x37, 0x33,
+ 0x35, 0x40, 0x41, 0x42, 0x38, 0x3f, 0x32, 0x45,
+ 0xac, 0x70, 0x8e, 0x8e, 0x1e, 0x72, 0x90, 0x29,
+ 0x4a, 0x22, 0xd3, 0xd2, 0x28, 0x25, 0x2a, 0x29,
+ 0x48, 0x49, 0x5d, 0x1f, 0x20, 0x23, 0x24, 0x4d,
+ 0x3d, 0x3e, 0, 0, 0, 0, 0, 0,
+ 0, 0x78, 0x72, 0x2b, 0x5e, 0x5e, 0x36, 0xae,
+ 0x30, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0x5c, 0x5e, 0, 0x5e, 0, 0,
+ 0, 0x3b, 0, 0, 0, 0, 0, 0,
+ 0, 0x50, 0x2e, 0, 0x58, 0, 0, 0x43,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0x54, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0
+};
+
static int lp8x4x_match(struct device *dev, struct device_driver *drv)
{
return 1;
@@ -44,6 +87,26 @@ static struct bus_type lp8x4x_bus_type = {
.match = lp8x4x_match,
};
+static void lp8x4x_slot_release(struct device *dev)
+{
+}
+
+static ssize_t model_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct lp8x4x_slot *s = container_of(dev, struct lp8x4x_slot, dev);
+
+ return sprintf(buf, "%u\n", s->model + 8000);
+}
+
+static DEVICE_ATTR_RO(model);
+
+static struct attribute *slot_dev_attrs[] = {
+ &dev_attr_model.attr,
+ NULL,
+};
+ATTRIBUTE_GROUPS(slot_dev);
+
static void lp8x4x_master_release(struct device *dev)
{
struct lp8x4x_master *m = container_of(dev, struct lp8x4x_master, dev);
@@ -173,18 +236,50 @@ ATTRIBUTE_GROUPS(master_dev);
static void devm_lp8x4x_bus_release(struct device *dev, void *res)
{
struct lp8x4x_master *m = *(struct lp8x4x_master **)res;
+ struct lp8x4x_slot *s;
+ int i;
dev_dbg(dev, "releasing devices\n");
+ for (i = 0; i < LP8X4X_MAX_SLOT_COUNT; i++) {
+ s = &m->slot[i];
+ if (s->model)
+ device_unregister(&s->dev);
+ }
device_unregister(&m->dev);
bus_unregister(&lp8x4x_bus_type);
}
+static void __init lp8x4x_bus_probe_slot(struct lp8x4x_master *m, int i,
+ unsigned char model)
+{
+ struct lp8x4x_slot *s = &m->slot[i];
+ int err;
+
+ dev_info(&m->dev, "found %u in slot %i\n", 8000 + model, i + 1);
+
+ s->dev.bus = &lp8x4x_bus_type;
+ dev_set_name(&s->dev, "slot%02i", i + 1);
+ s->dev.parent = &m->dev;
+ s->dev.release = lp8x4x_slot_release;
+ s->dev.groups = slot_dev_groups;
+ s->model = model;
+
+ err = device_register(&s->dev);
+ if (err < 0) {
+ dev_err(&s->dev, "failed to register device\n");
+ s->model = 0;
+ return;
+ }
+}
+
static int __init lp8x4x_bus_probe(struct platform_device *pdev)
{
struct lp8x4x_master *m, **p;
struct resource *res;
int r = 0;
+ int i;
int err = 0;
+ unsigned int model;
m = kzalloc(sizeof(*m), GFP_KERNEL);
if (!m)
@@ -211,6 +306,23 @@ static int __init lp8x4x_bus_probe(struct platform_device *pdev)
goto err_free;
}
+ for (i = 0; i < LP8X4X_MAX_SLOT_COUNT; i++) {
+ res = platform_get_resource(pdev, IORESOURCE_MEM, r++);
+ if (!res) {
+ dev_err(&pdev->dev, "Failed to get slot %i address\n",
+ i);
+ err = -ENODEV;
+ goto err_free;
+ }
+
+ m->slot[i].data_addr = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(m->slot[i].data_addr)) {
+ dev_err(&pdev->dev, "Failed to ioremap slot %i\n", i);
+ err = PTR_ERR(m->slot[i].data_addr);
+ goto err_free;
+ }
+ }
+
res = platform_get_resource(pdev, IORESOURCE_MEM, r++);
if (!res) {
dev_err(&pdev->dev, "Failed to get DIP switch address\n");
@@ -305,6 +417,13 @@ static int __init lp8x4x_bus_probe(struct platform_device *pdev)
}
devres_add(&pdev->dev, p);
+ for (i = 0; i < LP8X4X_MAX_SLOT_COUNT; i++) {
+ model = lp8x4x_model[ioread8(m->slot[i].data_addr)];
+ if (!model)
+ continue;
+
+ lp8x4x_bus_probe_slot(m, i, model);
+ }
return 0;
err_bus:
--
1.8.4.2
^ permalink raw reply related [flat|nested] 148+ messages in thread
* Re: [PATCH v3 01/21 resend] serial: rewrite pxa2xx-uart to use 8250_core
2013-12-17 19:37 ` [PATCH v3 01/21 resend] serial: rewrite pxa2xx-uart to use 8250_core Sergei Ianovich
@ 2013-12-18 23:55 ` Greg Kroah-Hartman
2013-12-19 8:51 ` Heikki Krogerus
1 sibling, 0 replies; 148+ messages in thread
From: Greg Kroah-Hartman @ 2013-12-18 23:55 UTC (permalink / raw)
To: Sergei Ianovich
Cc: linux-kernel, linux-arm-kernel, Russell King, Jiri Slaby,
Grant Likely, Rob Herring, Heikki Krogerus, James Cameron,
Zhou Zhu, Haojian Zhuang, Arnd Bergmann, open list:SERIAL DRIVERS,
open list:OPEN FIRMWARE AND...
On Tue, Dec 17, 2013 at 11:37:31PM +0400, Sergei Ianovich wrote:
> pxa2xx-uart was a separate uart platform driver. It was declaring
> the same device names and numbers as 8250 driver. As a result,
> it was impossible to use 8250 driver on PXA SoCs.
>
> Upon closer examination pxa2xx-uart turned out to be a clone of
> 8250_core driver.
>
> Workaround for Erratum #19 according to Marvel(R) PXA270M Processor
> Specification Update (April 19, 2010) is dropped. 8250_core reads
> from FIFO immediately after checking DR bit in LSR.
>
> Signed-off-by: Sergei Ianovich <ynvich@gmail.com>
> Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
> Reviewed-by: James Cameron <quozl@laptop.org>
> CC: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH v3 01/21 resend] serial: rewrite pxa2xx-uart to use 8250_core
2013-12-17 19:37 ` [PATCH v3 01/21 resend] serial: rewrite pxa2xx-uart to use 8250_core Sergei Ianovich
2013-12-18 23:55 ` Greg Kroah-Hartman
@ 2013-12-19 8:51 ` Heikki Krogerus
2013-12-19 9:35 ` Sergei Ianovich
1 sibling, 1 reply; 148+ messages in thread
From: Heikki Krogerus @ 2013-12-19 8:51 UTC (permalink / raw)
To: Sergei Ianovich
Cc: linux-kernel, linux-arm-kernel, Greg Kroah-Hartman, Russell King,
Jiri Slaby, Grant Likely, Rob Herring, James Cameron, Zhou Zhu,
Haojian Zhuang, Arnd Bergmann, open list:SERIAL DRIVERS,
open list:OPEN FIRMWARE AND...
Hi Sergei,
I noticed one more thing. I'm sorry about commenting this late.
On Tue, Dec 17, 2013 at 11:37:31PM +0400, Sergei Ianovich wrote:
> +static int serial_pxa_probe(struct platform_device *pdev)
> +{
> + struct uart_8250_port uart = {};
> + struct pxa8250_data *data;
> + struct resource *mmres, *irqres;
> + int ret;
> +
> + mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> + irqres = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
> + if (!mmres || !irqres)
> + return -ENODEV;
> +
> + data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
> + if (!data)
> + return -ENOMEM;
> +
> + data->clk = devm_clk_get(&pdev->dev, NULL);
> + if (IS_ERR(data->clk))
> + return PTR_ERR(data->clk);
> +
> + ret = clk_prepare(data->clk);
> + if (ret)
> + return ret;
> +
> + uart.port.type = PORT_XSCALE;
> + uart.port.iotype = UPIO_MEM32;
> + uart.port.mapbase = mmres->start;
> + uart.port.regshift = 2;
> + uart.port.irq = irqres->start;
> + uart.port.fifosize = 64;
> + uart.port.flags = UPF_IOREMAP | UPF_SKIP_TEST;
Since you set the type PORT_XSCALE, don's you want to use
UPF_FIXED_TYPE flag instead of the UPF_SKIP_TEST here? Otherwise the
type will just get overridden and autoconfig() will be executed.
I'm guessing you also want to prevent things like the irq and the
uartclk from being changed by anybody by using the flag
UPF_FIXED_PORT, right?
> + uart.port.dev = &pdev->dev;
> + uart.port.uartclk = clk_get_rate(data->clk);
> + uart.port.pm = serial_pxa_pm;
> + uart.port.private_data = data;
> + uart.dl_write = serial_pxa_dl_write;
> +
> + ret = serial8250_register_8250_port(&uart);
> + if (ret < 0)
> + goto err_clk;
> +
> + data->line = ret;
> +
> + platform_set_drvdata(pdev, data);
> +
> + return 0;
> +
> + err_clk:
> + clk_unprepare(data->clk);
> + return ret;
> +}
--
heikki
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH v3 01/21 resend] serial: rewrite pxa2xx-uart to use 8250_core
2013-12-19 8:51 ` Heikki Krogerus
@ 2013-12-19 9:35 ` Sergei Ianovich
2013-12-19 10:01 ` Sergei Ianovich
0 siblings, 1 reply; 148+ messages in thread
From: Sergei Ianovich @ 2013-12-19 9:35 UTC (permalink / raw)
To: Heikki Krogerus
Cc: linux-kernel, linux-arm-kernel, Greg Kroah-Hartman, Russell King,
Jiri Slaby, Grant Likely, Rob Herring, James Cameron, Zhou Zhu,
Haojian Zhuang, Arnd Bergmann, open list:SERIAL DRIVERS,
open list:OPEN FIRMWARE AND...
Hi Heikki,
On Thu, 2013-12-19 at 10:51 +0200, Heikki Krogerus wrote:
> I noticed one more thing. I'm sorry about commenting this late.
>
> Since you set the type PORT_XSCALE, don's you want to use
> UPF_FIXED_TYPE flag instead of the UPF_SKIP_TEST here? Otherwise the
> type will just get overridden and autoconfig() will be executed.
UPF_FIXED_PORT was my first guess. However, it didn't work.
I've also tried to do ioremap in serial_pxa_probe instead of using
UPF_IOREMAP. This didn't work as well.
I've left this
uart.port.type = PORT_XSCALE;
as an indicator that 8250_pxa depends on this port type, and anyone
changing its specific code paths should test with 8250_pxa. This line
could be safely removed or commented out, if you feel strongly about
that.
> I'm guessing you also want to prevent things like the irq and the
> uartclk from being changed by anybody by using the flag
> UPF_FIXED_PORT, right?
IIRC, autoprobing doesn't change irq or uartclk.
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH v3 01/21 resend] serial: rewrite pxa2xx-uart to use 8250_core
2013-12-19 9:35 ` Sergei Ianovich
@ 2013-12-19 10:01 ` Sergei Ianovich
2013-12-19 11:05 ` Heikki Krogerus
0 siblings, 1 reply; 148+ messages in thread
From: Sergei Ianovich @ 2013-12-19 10:01 UTC (permalink / raw)
To: Heikki Krogerus
Cc: linux-kernel, linux-arm-kernel, Greg Kroah-Hartman, Russell King,
Jiri Slaby, Grant Likely, Rob Herring, James Cameron, Zhou Zhu,
Haojian Zhuang, Arnd Bergmann, open list:SERIAL DRIVERS,
open list:OPEN FIRMWARE AND...
On Thu, 2013-12-19 at 13:35 +0400, Sergei Ianovich wrote:
> Hi Heikki,
>
> On Thu, 2013-12-19 at 10:51 +0200, Heikki Krogerus wrote:
> > I noticed one more thing. I'm sorry about commenting this late.
> >
> > Since you set the type PORT_XSCALE, don's you want to use
> > UPF_FIXED_TYPE flag instead of the UPF_SKIP_TEST here? Otherwise the
> > type will just get overridden and autoconfig() will be executed.
>
> UPF_FIXED_PORT was my first guess. However, it didn't work.
>
> I've also tried to do ioremap in serial_pxa_probe instead of using
> UPF_IOREMAP. This didn't work as well.
I didn't clarify properly.
UPF_SKIP_TEST skips only the loopback test. This test could work on PXA,
but requires PXA-specific pre-initialization. There are more test after
the loopback one, which will fail if we are not on PXA. So I decided
that skipping it is easier than tricky rewriting of autoconfig().
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH v3 01/21 resend] serial: rewrite pxa2xx-uart to use 8250_core
2013-12-19 10:01 ` Sergei Ianovich
@ 2013-12-19 11:05 ` Heikki Krogerus
0 siblings, 0 replies; 148+ messages in thread
From: Heikki Krogerus @ 2013-12-19 11:05 UTC (permalink / raw)
To: Sergei Ianovich
Cc: linux-kernel, linux-arm-kernel, Greg Kroah-Hartman, Russell King,
Jiri Slaby, Grant Likely, Rob Herring, James Cameron, Zhou Zhu,
Haojian Zhuang, Arnd Bergmann, open list:SERIAL DRIVERS,
open list:OPEN FIRMWARE AND...
On Thu, Dec 19, 2013 at 02:01:36PM +0400, Sergei Ianovich wrote:
> On Thu, 2013-12-19 at 13:35 +0400, Sergei Ianovich wrote:
> > On Thu, 2013-12-19 at 10:51 +0200, Heikki Krogerus wrote:
> > > I noticed one more thing. I'm sorry about commenting this late.
> > >
> > > Since you set the type PORT_XSCALE, don's you want to use
> > > UPF_FIXED_TYPE flag instead of the UPF_SKIP_TEST here? Otherwise the
> > > type will just get overridden and autoconfig() will be executed.
> >
> > UPF_FIXED_PORT was my first guess. However, it didn't work.
> >
> > I've also tried to do ioremap in serial_pxa_probe instead of using
> > UPF_IOREMAP. This didn't work as well.
>
> I didn't clarify properly.
>
> UPF_SKIP_TEST skips only the loopback test. This test could work on PXA,
> but requires PXA-specific pre-initialization. There are more test after
> the loopback one, which will fail if we are not on PXA. So I decided
> that skipping it is easier than tricky rewriting of autoconfig().
OK. So there is no problem here. Sorry about the noise.
Thanks,
--
heikki
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH v3 12/21] serial: support for 16550A serial ports on LP-8x4x
2013-12-17 19:37 ` [PATCH v3 12/21] serial: support for 16550A serial ports on LP-8x4x Sergei Ianovich
@ 2013-12-19 11:18 ` Heikki Krogerus
0 siblings, 0 replies; 148+ messages in thread
From: Heikki Krogerus @ 2013-12-19 11:18 UTC (permalink / raw)
To: Sergei Ianovich
Cc: linux-kernel, linux-arm-kernel, Rob Herring, Pawel Moll,
Mark Rutland, Ian Campbell, Kumar Gala, Rob Landley, Russell King,
Greg Kroah-Hartman, Jiri Slaby, Grant Likely, Randy Dunlap,
Arnd Bergmann, James Cameron, open list:OPEN FIRMWARE AND...,
open list:DOCUMENTATION, open list:SERIAL DRIVERS
Hi,
On Tue, Dec 17, 2013 at 11:37:42PM +0400, Sergei Ianovich wrote:
> The patch adds support for 3 additional LP-8x4x built-in serial
> ports.
>
> The device can also host up to 8 extension cards with 4 serial ports
> on each card for a total of 35 ports. However, I don't have
> the hardware to test extension cards, so they are not supported, yet.
>
> Signed-off-by: Sergei Ianovich <ynvich@gmail.com>
> CC: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Looks OK to me, though normally I would prefer the arch code and the
driver to be handled in separate patches. FWIW...
Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Thanks,
--
heikki
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH v3 11/21] ARM: pxa: support ICP DAS LP-8x4x FPGA irq
2013-12-17 19:37 ` [PATCH v3 11/21] ARM: pxa: support ICP DAS LP-8x4x FPGA irq Sergei Ianovich
@ 2014-01-02 12:32 ` Linus Walleij
2014-01-08 19:01 ` Sergei Ianovich
[not found] ` <1387309071-22382-12-git-send-email-ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
1 sibling, 1 reply; 148+ messages in thread
From: Linus Walleij @ 2014-01-02 12:32 UTC (permalink / raw)
To: Sergei Ianovich
Cc: linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, Arnd Bergmann, Rob Herring,
Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala, Rob Landley,
Russell King, Thomas Gleixner, Grant Likely,
open list:OPEN FIRMWARE AND..., open list:DOCUMENTATION
On Tue, Dec 17, 2013 at 8:37 PM, Sergei Ianovich <ynvich@gmail.com> wrote:
> ICP DAS LP-8x4x contains FPGA chip. The chip functions as a interrupt
> source providing 16 additional interrupts among other things. The
> interrupt lines are muxed to a GPIO pin. GPIO pins are in turn muxed
> to a CPU interrupt line.
>
> Until pxa is completely converted to device tree, it is impossible
> to use IRQCHIP_DECLARE() and the irqdomain needs to added manually.
>
> Signed-off-by: Sergei Ianovich <ynvich@gmail.com>
> CC: Arnd Bergmann <arnd@arndb.de>
> CC: Linus Walleij <linus.walleij@linaro.org>
(...)
> +++ b/drivers/irqchip/irq-lp8x4x.c
Usually combined GPIO+IRQ controllers are put into drivers/gpio but
this is a bit special as it seems to handle also non-GPIO-related IRQs
so let's get some input on this.
> +static unsigned char irq_sys_enabled;
> +static unsigned char irq_high_enabled;
> +static void *base;
> +static int irq_base;
> +static int num_irq = 16;
Please use the state container design pattern and get rid of these
global variables.
This documentation patch describes this pattern and has been
merged for v3.14, so please read this:
http://marc.info/?l=linux-kernel&m=138615980524966&w=2
> +static void lp8x4x_mask_irq(struct irq_data *d)
> +{
> + unsigned mask;
> + int irq = d->irq - irq_base;
Don't calculate hardware IRQ numbers from offsets. Use
irqdomain, which is done for exactly this purpose.
> + if (irq < 8) {
> + irq_high_enabled &= ~(1 << irq);
I usually use the BIT() macro for this, like:
#include <linux/bitops.h>
irq_high_enabled &= ~BIT(irq);
> +static struct irq_chip lp8x4x_irq_chip = {
> + .name = "FPGA",
> + .irq_ack = lp8x4x_mask_irq,
> + .irq_mask = lp8x4x_mask_irq,
> + .irq_mask_ack = lp8x4x_mask_irq,
> + .irq_unmask = lp8x4x_unmask_irq,
> +};
After you have added your state container you will have
a handle to your struct gpio_chip in the cookie passed to
as irqdata.
Then you need to mark the GPIO lines used for IRQs by
doing something similar to this patch in your startup()
and shutdown() callbacks:
http://marc.info/?l=linux-gpio&m=138547223832167&w=2
> +static void lp8x4x_irq_handler(unsigned int irq, struct irq_desc *desc)
> +{> +static void lp8x4x_unmask_irq(struct irq_data *d)
> +{
> + unsigned mask;
> + int irq = d->irq - irq_base;
Use the irqdomain.
> + int loop, n;
> + unsigned long mask;
> + struct irq_chip *chip = irq_desc_get_chip(desc);
> +
> + chained_irq_enter(chip, desc);
> +
> + do {
> + loop = 0;
> + mask = ioread8(base + CLRHILVINT) & 0xff;
> + mask |= (ioread8(base + SECOINT) & 0x1f) << 8;
> + mask |= (ioread8(base + PRIMINT) & 0xe0) << 8;
#define these magic constants so we know what they mean.
0x1f, 0xe0...
> + mask &= (irq_high_enabled | (irq_sys_enabled << 8));
> + for_each_set_bit(n, &mask, BITS_PER_LONG) {
> + loop = 1;
> +
> + generic_handle_irq(irq_base + n);
> + }
> + } while (loop);
If you're going to do it like this then have "loop" be a bool variable.
However I don't quite like this construction, an eternal for() loop
with a break; statement works too, but try to just use the mask and
get rid of the "loop" helper variable.
> + iowrite8(0, base + EOI);
This looks dangerous, what are you doing here?
> +static int lp8x4x_irq_probe(struct platform_device *pdev)
> +{
> + struct resource *rm, *ri;
Explain these names. Usually we call them "res" or something
simple like this.
> + irq_base = irq_alloc_descs(-1, 0, num_irq, 0);
> + if (irq_base < 0) {
> + dev_err(&pdev->dev, "Failed to allocate IRQ numbers\n");
> + return irq_base;
> + }
Instead of doing this, create the descriptors by calling
irq_create_mapping() on all the hardware lines after adding
the irq domain.
> + domain = irq_domain_add_legacy(np, num_irq, irq_base, 0,
> + &lp8x4x_irq_domain_ops, NULL);
> + if (!domain) {
> + dev_err(&pdev->dev, "Failed to add IRQ domain\n");
> + return -ENOMEM;
> + }
Why are you using a legacy irqdomain? You're not dependent
on any specific base so use a linear domain.
> + iowrite8(0, base + CLRRISEINT);
> + iowrite8(0, base + ENRISEINT);
> + iowrite8(0, base + CLRFALLINT);
> + iowrite8(0, base + ENFALLINT);
> + iowrite8(0, base + CLRHILVINT);
> + iowrite8(0, base + ENHILVINT);
> + iowrite8(0, base + ENSYSINT);
> + iowrite8(0, base + SECOINT);
Add a comment explaining what you're doing here.
> +static int __init lp8x4x_irq_init(void)
> +{
> + return platform_driver_register(&lp8x4x_irq_driver);
> +}
> +postcore_initcall(lp8x4x_irq_init);
Do you *have* to do it this early? I guess if it's used for
the UARTs then yes, but make a case for it...
Yours,
Linus Walleij
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH v3 11/21] ARM: pxa: support ICP DAS LP-8x4x FPGA irq
2014-01-02 12:32 ` Linus Walleij
@ 2014-01-08 19:01 ` Sergei Ianovich
2014-01-15 7:39 ` Linus Walleij
0 siblings, 1 reply; 148+ messages in thread
From: Sergei Ianovich @ 2014-01-08 19:01 UTC (permalink / raw)
To: Linus Walleij
Cc: linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, Arnd Bergmann, Rob Herring,
Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala, Rob Landley,
Russell King, Thomas Gleixner, Grant Likely,
open list:OPEN FIRMWARE AND..., open list:DOCUMENTATION
On Thu, 2014-01-02 at 13:32 +0100, Linus Walleij wrote:
> On Tue, Dec 17, 2013 at 8:37 PM, Sergei Ianovich <ynvich@gmail.com> wrote:
> Usually combined GPIO+IRQ controllers are put into drivers/gpio but
> this is a bit special as it seems to handle also non-GPIO-related IRQs
> so let's get some input on this.
This one is a plain IRQ controller. It has simple input lines, not GPIO
pins. The chip reports its status to upper level interrupt controller.
The upper level controller is PXA GPIO in this case.
(...)
> > +static struct irq_chip lp8x4x_irq_chip = {
> > + .name = "FPGA",
> > + .irq_ack = lp8x4x_mask_irq,
> > + .irq_mask = lp8x4x_mask_irq,
> > + .irq_mask_ack = lp8x4x_mask_irq,
> > + .irq_unmask = lp8x4x_unmask_irq,
> > +};
>
> After you have added your state container you will have
> a handle to your struct gpio_chip in the cookie passed to
> as irqdata.
>
> Then you need to mark the GPIO lines used for IRQs by
> doing something similar to this patch in your startup()
> and shutdown() callbacks:
> http://marc.info/?l=linux-gpio&m=138547223832167&w=2
The chip requires no GPIO initialization.
(...)
> > + iowrite8(0, base + EOI);
>
> This looks dangerous, what are you doing here?
This is done in kernel source which comes with the device. The
controller won't work without this line.
I cannot know for sure, as I don't have board datasheets or drawings. I
suspect, this clears GPIO line which reports interrupts to the upper
level controller.
(...)
> > +static int __init lp8x4x_irq_init(void)
> > +{
> > + return platform_driver_register(&lp8x4x_irq_driver);
> > +}
> > +postcore_initcall(lp8x4x_irq_init);
>
> Do you *have* to do it this early? I guess if it's used for
> the UARTs then yes, but make a case for it...
PXA isn't DT-only at the moment. As a result, it is impossible
to use IRQCHIP_DECLARE(). So drivers for the on-CPU IRQs and GPIO-IRQs
are loaded using postcore_initcall(). We need to have all irq domain
drivers loaded prior to DT parsing in order to allow normal
initialization of IRQ resources with DT. I'll update the commit message.
The rest of review comment are implemented. The changes don't affect any
other patches in the series. Should I repost the whole series?
Or only this patch?
Thanks.
^ permalink raw reply [flat|nested] 148+ messages in thread
* [PATCH v3.1 11/21] ARM: pxa: support ICP DAS LP-8x4x FPGA irq
[not found] ` <1387309071-22382-12-git-send-email-ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2014-01-09 23:07 ` Sergei Ianovich
2014-01-15 7:46 ` Linus Walleij
2014-01-15 13:12 ` [PATCH v3.2 " Sergei Ianovich
0 siblings, 2 replies; 148+ messages in thread
From: Sergei Ianovich @ 2014-01-09 23:07 UTC (permalink / raw)
To: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
Cc: Sergei Ianovich, Arnd Bergmann, Linus Walleij, Rob Herring,
Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala, Rob Landley,
Russell King, Thomas Gleixner, Grant Likely,
open list:OPEN FIRMWARE AND..., open list:DOCUMENTATION
ICP DAS LP-8x4x contains FPGA chip. The chip functions as an interrupt
source providing 16 additional interrupts among other things. The
interrupt lines are muxed to a GPIO pin of a 2nd level PXA-GPIO
interrupt controller. GPIO pins of the 2nd level controller are in turn
muxed to a CPU interrupt line.
Until pxa is completely converted to device tree, it is impossible
to use IRQCHIP_DECLARE() and the irqdomain needs to added manually.
Drivers for the on-CPU IRQs and GPIO-IRQs are loaded using
postcore_initcall(). We need to have all irq domain drivers loaded prior
to DT parsing in order to allow normal initialization of IRQ resources
with DT.
Signed-off-by: Sergei Ianovich <ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
CC: Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org>
CC: Linus Walleij <linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
---
v3..v3.1
fixes according to Linus Walleij review comments:
* update commit message
* use state container instead of global variables
* get hardware irq nums from irq_data, don't calculate them
* use BIT() macro
* add defines for system irq register masks
* replace cycle control variable with break
* use better names for resource variables
* add a linear domain instead of a legacy one
* use irq_create_mapping() instead of irq_alloc_desc()
v2..v3
* no changes (except number 09/16 -> 11/21)
v0..v2
* extract irqchip and move to drivers/irqchip/
* use device tree
* use devm helpers where possible
.../bindings/interrupt-controller/irq-lp8x4x.txt | 49 +++++
arch/arm/boot/dts/pxa27x-lp8x4x.dts | 10 +
drivers/irqchip/Kconfig | 5 +
drivers/irqchip/Makefile | 1 +
drivers/irqchip/irq-lp8x4x.c | 238 +++++++++++++++++++++
5 files changed, 303 insertions(+)
create mode 100644 Documentation/devicetree/bindings/interrupt-controller/irq-lp8x4x.txt
create mode 100644 drivers/irqchip/irq-lp8x4x.c
diff --git a/Documentation/devicetree/bindings/interrupt-controller/irq-lp8x4x.txt b/Documentation/devicetree/bindings/interrupt-controller/irq-lp8x4x.txt
new file mode 100644
index 0000000..c8940d2
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/irq-lp8x4x.txt
@@ -0,0 +1,49 @@
+ICP DAS LP-8x4x FPGA Interrupt Controller
+
+ICP DAS LP-8x4x contains FPGA chip. The chip functions as a interrupt
+source providing 16 additional interrupts among other things.
+
+Required properties:
+- compatible : should be "icpdas,irq-lp8x4x"
+
+- reg: physical base address of the controller and length of memory mapped
+ region.
+
+- interrupt-controller : identifies the node as an interrupt controller
+
+- #interrupt-cells : should be 1
+
+- interrupts : should provide interrupt
+
+- interrupt-parent : should provide a link to interrupt controller either
+ explicitly and implicitly from a parent node
+
+Example:
+
+ fpga: fpga@17000006 {
+ compatible = "icpdas,irq-lp8x4x";
+ reg = <0x17000006 0x16>;
+ interrupt-parent = <&gpio>;
+ interrupts = <3 IRQ_TYPE_EDGE_RISING>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ status = "okay";
+ };
+
+ uart@17009050 {
+ compatible = "icpdas,uart-lp8x4x";
+ reg = <0x17009050 0x10
+ 0x17009030 0x02>;
+ interrupt-parent = <&fpga>;
+ interrupts = <13>;
+ status = "okay";
+ };
+
+ uart@17009060 {
+ compatible = "icpdas,uart-lp8x4x";
+ reg = <0x17009060 0x10
+ 0x17009032 0x02>;
+ interrupt-parent = <&fpga>;
+ interrupts = <14>;
+ status = "okay";
+ };
diff --git a/arch/arm/boot/dts/pxa27x-lp8x4x.dts b/arch/arm/boot/dts/pxa27x-lp8x4x.dts
index 07856e0..78dfd2e 100644
--- a/arch/arm/boot/dts/pxa27x-lp8x4x.dts
+++ b/arch/arm/boot/dts/pxa27x-lp8x4x.dts
@@ -167,6 +167,16 @@
reg = <0xa000 0x1000
0x901e 0x1>;
};
+
+ fpgairq: irq@9006 {
+ compatible = "icpdas,irq-lp8x4x";
+ reg = <0x9006 0x16>;
+ interrupt-parent = <&gpio>;
+ interrupts = <3 IRQ_TYPE_EDGE_FALLING>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ status = "okay";
+ };
};
};
};
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 3792a1a..7e22729 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -35,6 +35,11 @@ config IMGPDC_IRQ
select GENERIC_IRQ_CHIP
select IRQ_DOMAIN
+config LP8X4X_IRQ
+ bool
+ depends on OF
+ select IRQ_DOMAIN
+
config ORION_IRQCHIP
bool
select IRQ_DOMAIN
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index c60b901..8a28927 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -22,3 +22,4 @@ obj-$(CONFIG_RENESAS_IRQC) += irq-renesas-irqc.o
obj-$(CONFIG_VERSATILE_FPGA_IRQ) += irq-versatile-fpga.o
obj-$(CONFIG_ARCH_VT8500) += irq-vt8500.o
obj-$(CONFIG_TB10X_IRQC) += irq-tb10x.o
+obj-$(CONFIG_LP8X4X_IRQ) += irq-lp8x4x.o
diff --git a/drivers/irqchip/irq-lp8x4x.c b/drivers/irqchip/irq-lp8x4x.c
new file mode 100644
index 0000000..61dfbed
--- /dev/null
+++ b/drivers/irqchip/irq-lp8x4x.c
@@ -0,0 +1,238 @@
+/*
+ * linux/drivers/irqchip/irq-lp8x4x.c
+ *
+ * Support for ICP DAS LP-8x4x FPGA irq
+ * Copyright (C) 2013 Sergei Ianovich <ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation or any later version.
+ */
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+
+#define EOI 0x00000000
+#define INSINT 0x00000002
+#define ENSYSINT 0x00000004
+#define PRIMINT 0x00000006
+#define PRIMINT_MASK 0xe0
+#define SECOINT 0x00000008
+#define SECOINT_MASK 0x1f
+#define ENRISEINT 0x0000000A
+#define CLRRISEINT 0x0000000C
+#define ENHILVINT 0x0000000E
+#define CLRHILVINT 0x00000010
+#define ENFALLINT 0x00000012
+#define CLRFALLINT 0x00000014
+#define IRQ_MEM_SIZE 0x00000016
+#define LP8X4X_NUM_IRQ_DEFAULT 16
+
+struct lp8x4x_irq_data {
+ void *base;
+ struct irq_domain *domain;
+ unsigned long num_irq;
+ unsigned char irq_sys_enabled;
+ unsigned char irq_high_enabled;
+};
+
+static void lp8x4x_mask_irq(struct irq_data *d)
+{
+ unsigned mask;
+ unsigned long irq = d->hwirq;
+ struct lp8x4x_irq_data *host = irq_data_get_irq_chip_data(d);
+
+ if (!host) {
+ pr_err("lp8x4x: missing host data for irq %i\n", d->irq);
+ return;
+ }
+
+ if (irq >= host->num_irq) {
+ pr_err("lp8x4x: wrong irq handler for irq %i\n", d->irq);
+ return;
+ }
+
+ if (irq < 8) {
+ host->irq_high_enabled &= ~BIT(irq);
+
+ mask = ioread8(host->base + ENHILVINT);
+ mask &= ~BIT(irq);
+ iowrite8(mask, host->base + ENHILVINT);
+ } else {
+ irq -= 8;
+ host->irq_sys_enabled &= ~BIT(irq);
+
+ mask = ioread8(host->base + ENSYSINT);
+ mask &= ~BIT(irq);
+ iowrite8(mask, host->base + ENSYSINT);
+ }
+}
+
+static void lp8x4x_unmask_irq(struct irq_data *d)
+{
+ unsigned mask;
+ unsigned long irq = d->hwirq;
+ struct lp8x4x_irq_data *host = irq_data_get_irq_chip_data(d);
+
+ if (!host) {
+ pr_err("lp8x4x: missing host data for irq %i\n", d->irq);
+ return;
+ }
+
+ if (irq >= host->num_irq) {
+ pr_err("lp8x4x: wrong irq handler for irq %i\n", d->irq);
+ return;
+ }
+
+ if (irq < 8) {
+ host->irq_high_enabled |= BIT(irq);
+ mask = ioread8(host->base + CLRHILVINT);
+ mask |= BIT(irq);
+ iowrite8(mask, host->base + CLRHILVINT);
+
+ mask = ioread8(host->base + ENHILVINT);
+ mask |= BIT(irq);
+ iowrite8(mask, host->base + ENHILVINT);
+ } else {
+ irq -= 8;
+ host->irq_sys_enabled |= BIT(irq);
+
+ mask = ioread8(host->base + SECOINT);
+ mask |= BIT(irq);
+ iowrite8(mask, host->base + SECOINT);
+
+ mask = ioread8(host->base + ENSYSINT);
+ mask |= BIT(irq);
+ iowrite8(mask, host->base + ENSYSINT);
+ }
+}
+
+static struct irq_chip lp8x4x_irq_chip = {
+ .name = "FPGA",
+ .irq_ack = lp8x4x_mask_irq,
+ .irq_mask = lp8x4x_mask_irq,
+ .irq_mask_ack = lp8x4x_mask_irq,
+ .irq_unmask = lp8x4x_unmask_irq,
+};
+
+static void lp8x4x_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+ int n;
+ unsigned long mask;
+ struct irq_chip *chip = irq_desc_get_chip(desc);
+ struct lp8x4x_irq_data *host = irq_desc_get_handler_data(desc);
+
+ if (!host)
+ return;
+
+ chained_irq_enter(chip, desc);
+
+ for (;;) {
+ mask = ioread8(host->base + CLRHILVINT) & 0xff;
+ mask |= (ioread8(host->base + SECOINT) & SECOINT_MASK) << 8;
+ mask |= (ioread8(host->base + PRIMINT) & PRIMINT_MASK) << 8;
+ mask &= host->irq_high_enabled | (host->irq_sys_enabled << 8);
+ if (mask == 0)
+ break;
+ for_each_set_bit(n, &mask, BITS_PER_LONG)
+ generic_handle_irq(irq_find_mapping(host->domain, n));
+ }
+
+ iowrite8(0, host->base + EOI);
+ chained_irq_exit(chip, desc);
+}
+
+static int lp8x4x_irq_domain_map(struct irq_domain *d, unsigned int irq,
+ irq_hw_number_t hw)
+{
+ struct lp8x4x_irq_data *host = d->host_data;
+ int err;
+
+ err = irq_set_chip_data(irq, host);
+ if (err < 0)
+ return err;
+
+ irq_set_chip_and_handler(irq, &lp8x4x_irq_chip, handle_level_irq);
+ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+ return 0;
+}
+
+const struct irq_domain_ops lp8x4x_irq_domain_ops = {
+ .map = lp8x4x_irq_domain_map,
+ .xlate = irq_domain_xlate_onecell,
+};
+
+static struct of_device_id lp8x4x_irq_dt_ids[] = {
+ { .compatible = "icpdas,irq-lp8x4x", },
+ {}
+};
+
+static int lp8x4x_irq_probe(struct platform_device *pdev)
+{
+ struct resource *res_mem, *res_irq;
+ struct device_node *np = pdev->dev.of_node;
+ struct lp8x4x_irq_data *host;
+ int i, err;
+
+ res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (!res_mem || !res_irq || resource_size(res_mem) < IRQ_MEM_SIZE)
+ return -ENODEV;
+
+ host = devm_kzalloc(&pdev->dev, sizeof(*host), GFP_KERNEL);
+ if (!host)
+ return -ENODEV;
+
+ host->num_irq = LP8X4X_NUM_IRQ_DEFAULT;
+ host->base = devm_ioremap_resource(&pdev->dev, res_mem);
+ if (!host->base) {
+ dev_err(&pdev->dev, "Failed to ioremap %p\n", host->base);
+ return -EFAULT;
+ }
+
+ host->domain = irq_domain_add_linear(np, host->num_irq,
+ &lp8x4x_irq_domain_ops, host);
+ if (!host->domain) {
+ dev_err(&pdev->dev, "Failed to add IRQ domain\n");
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < host->num_irq; i++) {
+ err = irq_create_mapping(host->domain, i);
+ if (err < 0)
+ dev_err(&pdev->dev, "Failed to map IRQ %i\n", i);
+ }
+
+ /* Initialize chip registers */
+ iowrite8(0, host->base + CLRRISEINT);
+ iowrite8(0, host->base + ENRISEINT);
+ iowrite8(0, host->base + CLRFALLINT);
+ iowrite8(0, host->base + ENFALLINT);
+ iowrite8(0, host->base + CLRHILVINT);
+ iowrite8(0, host->base + ENHILVINT);
+ iowrite8(0, host->base + ENSYSINT);
+ iowrite8(0, host->base + SECOINT);
+
+ irq_set_handler_data(res_irq->start, host);
+ irq_set_chained_handler(res_irq->start, lp8x4x_irq_handler);
+
+ return 0;
+}
+
+static struct platform_driver lp8x4x_irq_driver = {
+ .probe = lp8x4x_irq_probe,
+ .driver = {
+ .name = "irq-lp8x4x",
+ .of_match_table = lp8x4x_irq_dt_ids,
+ },
+};
+
+static int __init lp8x4x_irq_init(void)
+{
+ return platform_driver_register(&lp8x4x_irq_driver);
+}
+postcore_initcall(lp8x4x_irq_init);
--
1.8.4.2
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 148+ messages in thread
* Re: [PATCH v3 11/21] ARM: pxa: support ICP DAS LP-8x4x FPGA irq
2014-01-08 19:01 ` Sergei Ianovich
@ 2014-01-15 7:39 ` Linus Walleij
2014-01-15 13:17 ` Sergei Ianovich
0 siblings, 1 reply; 148+ messages in thread
From: Linus Walleij @ 2014-01-15 7:39 UTC (permalink / raw)
To: Sergei Ianovich
Cc: linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, Arnd Bergmann, Rob Herring,
Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala, Rob Landley,
Russell King, Thomas Gleixner, Grant Likely,
open list:OPEN FIRMWARE AND..., open list:DOCUMENTATION
On Wed, Jan 8, 2014 at 8:01 PM, Sergei Ianovich <ynvich@gmail.com> wrote:
> On Thu, 2014-01-02 at 13:32 +0100, Linus Walleij wrote:
>> On Tue, Dec 17, 2013 at 8:37 PM, Sergei Ianovich <ynvich@gmail.com> wrote:
>> Usually combined GPIO+IRQ controllers are put into drivers/gpio but
>> this is a bit special as it seems to handle also non-GPIO-related IRQs
>> so let's get some input on this.
>
> This one is a plain IRQ controller. It has simple input lines, not GPIO
> pins. The chip reports its status to upper level interrupt controller.
> The upper level controller is PXA GPIO in this case.
Hm I don't know why I was deluded into thinking this had something to
do with GPIO. I must have been soft in the head. Sorry about all those
comments ...
I'll re-read the irqchip driver v3.1.
Yours,
Linus Walleij
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH v3.1 11/21] ARM: pxa: support ICP DAS LP-8x4x FPGA irq
2014-01-09 23:07 ` [PATCH v3.1 " Sergei Ianovich
@ 2014-01-15 7:46 ` Linus Walleij
2014-01-15 13:12 ` [PATCH v3.2 " Sergei Ianovich
1 sibling, 0 replies; 148+ messages in thread
From: Linus Walleij @ 2014-01-15 7:46 UTC (permalink / raw)
To: Sergei Ianovich
Cc: linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, Arnd Bergmann, Rob Herring,
Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala, Rob Landley,
Russell King, Thomas Gleixner, Grant Likely,
open list:OPEN FIRMWARE AND..., open list:DOCUMENTATION
This is looking much better!
On Fri, Jan 10, 2014 at 12:07 AM, Sergei Ianovich <ynvich@gmail.com> wrote:
> +++ b/drivers/irqchip/irq-lp8x4x.c
(...)
You could add some kerneldoc to this following struct (OK nitpick, but
still nice, especially for the last two variables).
> +struct lp8x4x_irq_data {
> + void *base;
> + struct irq_domain *domain;
> + unsigned long num_irq;
> + unsigned char irq_sys_enabled;
> + unsigned char irq_high_enabled;
> +};
> +
> +static void lp8x4x_mask_irq(struct irq_data *d)
> +{
> + unsigned mask;
> + unsigned long irq = d->hwirq;
Name the local variable hwirq too so we know what it is.
> + struct lp8x4x_irq_data *host = irq_data_get_irq_chip_data(d);
> +
> + if (!host) {
> + pr_err("lp8x4x: missing host data for irq %i\n", d->irq);
> + return;
> + }
> +
> + if (irq >= host->num_irq) {
> + pr_err("lp8x4x: wrong irq handler for irq %i\n", d->irq);
> + return;
> + }
This is on the hotpath. Do you *really* need these two checks?
(...)
> +static void lp8x4x_unmask_irq(struct irq_data *d)
> +{
> + unsigned mask;
> + unsigned long irq = d->hwirq;
Name the variable "hwirq".
> + struct lp8x4x_irq_data *host = irq_data_get_irq_chip_data(d);
> +
> + if (!host) {
> + pr_err("lp8x4x: missing host data for irq %i\n", d->irq);
> + return;
> + }
> +
> + if (irq >= host->num_irq) {
> + pr_err("lp8x4x: wrong irq handler for irq %i\n", d->irq);
> + return;
> + }
Again overzealous error checks.
(...)
> +static void lp8x4x_irq_handler(unsigned int irq, struct irq_desc *desc)
> +{
> + int n;
> + unsigned long mask;
> + struct irq_chip *chip = irq_desc_get_chip(desc);
> + struct lp8x4x_irq_data *host = irq_desc_get_handler_data(desc);
> +
> + if (!host)
> + return;
I don't think this happens either?
> + chained_irq_enter(chip, desc);
> +
> + for (;;) {
> + mask = ioread8(host->base + CLRHILVINT) & 0xff;
> + mask |= (ioread8(host->base + SECOINT) & SECOINT_MASK) << 8;
> + mask |= (ioread8(host->base + PRIMINT) & PRIMINT_MASK) << 8;
> + mask &= host->irq_high_enabled | (host->irq_sys_enabled << 8);
> + if (mask == 0)
> + break;
> + for_each_set_bit(n, &mask, BITS_PER_LONG)
> + generic_handle_irq(irq_find_mapping(host->domain, n));
> + }
I like the looks of this.
If you fix this:
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Yours,
Linus Walleij
^ permalink raw reply [flat|nested] 148+ messages in thread
* [PATCH v3.2 11/21] ARM: pxa: support ICP DAS LP-8x4x FPGA irq
2014-01-09 23:07 ` [PATCH v3.1 " Sergei Ianovich
2014-01-15 7:46 ` Linus Walleij
@ 2014-01-15 13:12 ` Sergei Ianovich
1 sibling, 0 replies; 148+ messages in thread
From: Sergei Ianovich @ 2014-01-15 13:12 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel
Cc: Linus Walleij, Sergei Ianovich, Arnd Bergmann, Rob Herring,
Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala, Rob Landley,
Russell King, Thomas Gleixner, Grant Likely,
open list:OPEN FIRMWARE AND..., open list:DOCUMENTATION
ICP DAS LP-8x4x contains FPGA chip. The chip functions as an interrupt
source providing 16 additional interrupts among other things. The
interrupt lines are muxed to a GPIO pin of a 2nd level PXA-GPIO
interrupt controller. GPIO pins of the 2nd level controller are in turn
muxed to a CPU interrupt line.
Until pxa is completely converted to device tree, it is impossible
to use IRQCHIP_DECLARE() and the irqdomain needs to added manually.
Drivers for the on-CPU IRQs and GPIO-IRQs are loaded using
postcore_initcall(). We need to have all irq domain drivers loaded prior
to DT parsing in order to allow normal initialization of IRQ resources
with DT.
Signed-off-by: Sergei Ianovich <ynvich@gmail.com>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
CC: Arnd Bergmann <arnd@arndb.de>
---
v3.1..v3.2
fixes to apply Linus Walleij's "Reviewed-by":
* add kerneldoc comment for state container struct
* rename irq -> hwirq for clarity
* drop overzealous error checks from the hotpaths
v3..v3.1
fixes according to Linus Walleij review comments:
* update commit message
* use state container instead of global variables
* get hardware irq nums from irq_data, don't calculate them
* use BIT() macro
* add defines for system irq register masks
* replace cycle control variable with break
* use better names for resource variables
* add a linear domain instead of a legacy one
* use irq_create_mapping() instead of irq_alloc_desc()
v2..v3
* no changes (except number 09/16 -> 11/21)
v0..v2
* extract irqchip and move to drivers/irqchip/
* use device tree
* use devm helpers where possible
.../bindings/interrupt-controller/irq-lp8x4x.txt | 49 +++++
arch/arm/boot/dts/pxa27x-lp8x4x.dts | 10 +
drivers/irqchip/Kconfig | 5 +
drivers/irqchip/Makefile | 1 +
drivers/irqchip/irq-lp8x4x.c | 227 +++++++++++++++++++++
5 files changed, 292 insertions(+)
create mode 100644 Documentation/devicetree/bindings/interrupt-controller/irq-lp8x4x.txt
create mode 100644 drivers/irqchip/irq-lp8x4x.c
diff --git a/Documentation/devicetree/bindings/interrupt-controller/irq-lp8x4x.txt b/Documentation/devicetree/bindings/interrupt-controller/irq-lp8x4x.txt
new file mode 100644
index 0000000..c8940d2
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/irq-lp8x4x.txt
@@ -0,0 +1,49 @@
+ICP DAS LP-8x4x FPGA Interrupt Controller
+
+ICP DAS LP-8x4x contains FPGA chip. The chip functions as a interrupt
+source providing 16 additional interrupts among other things.
+
+Required properties:
+- compatible : should be "icpdas,irq-lp8x4x"
+
+- reg: physical base address of the controller and length of memory mapped
+ region.
+
+- interrupt-controller : identifies the node as an interrupt controller
+
+- #interrupt-cells : should be 1
+
+- interrupts : should provide interrupt
+
+- interrupt-parent : should provide a link to interrupt controller either
+ explicitly and implicitly from a parent node
+
+Example:
+
+ fpga: fpga@17000006 {
+ compatible = "icpdas,irq-lp8x4x";
+ reg = <0x17000006 0x16>;
+ interrupt-parent = <&gpio>;
+ interrupts = <3 IRQ_TYPE_EDGE_RISING>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ status = "okay";
+ };
+
+ uart@17009050 {
+ compatible = "icpdas,uart-lp8x4x";
+ reg = <0x17009050 0x10
+ 0x17009030 0x02>;
+ interrupt-parent = <&fpga>;
+ interrupts = <13>;
+ status = "okay";
+ };
+
+ uart@17009060 {
+ compatible = "icpdas,uart-lp8x4x";
+ reg = <0x17009060 0x10
+ 0x17009032 0x02>;
+ interrupt-parent = <&fpga>;
+ interrupts = <14>;
+ status = "okay";
+ };
diff --git a/arch/arm/boot/dts/pxa27x-lp8x4x.dts b/arch/arm/boot/dts/pxa27x-lp8x4x.dts
index 07856e0..78dfd2e 100644
--- a/arch/arm/boot/dts/pxa27x-lp8x4x.dts
+++ b/arch/arm/boot/dts/pxa27x-lp8x4x.dts
@@ -167,6 +167,16 @@
reg = <0xa000 0x1000
0x901e 0x1>;
};
+
+ fpgairq: irq@9006 {
+ compatible = "icpdas,irq-lp8x4x";
+ reg = <0x9006 0x16>;
+ interrupt-parent = <&gpio>;
+ interrupts = <3 IRQ_TYPE_EDGE_FALLING>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ status = "okay";
+ };
};
};
};
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 3792a1a..7e22729 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -35,6 +35,11 @@ config IMGPDC_IRQ
select GENERIC_IRQ_CHIP
select IRQ_DOMAIN
+config LP8X4X_IRQ
+ bool
+ depends on OF
+ select IRQ_DOMAIN
+
config ORION_IRQCHIP
bool
select IRQ_DOMAIN
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index c60b901..8a28927 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -22,3 +22,4 @@ obj-$(CONFIG_RENESAS_IRQC) += irq-renesas-irqc.o
obj-$(CONFIG_VERSATILE_FPGA_IRQ) += irq-versatile-fpga.o
obj-$(CONFIG_ARCH_VT8500) += irq-vt8500.o
obj-$(CONFIG_TB10X_IRQC) += irq-tb10x.o
+obj-$(CONFIG_LP8X4X_IRQ) += irq-lp8x4x.o
diff --git a/drivers/irqchip/irq-lp8x4x.c b/drivers/irqchip/irq-lp8x4x.c
new file mode 100644
index 0000000..12ccbb03
--- /dev/null
+++ b/drivers/irqchip/irq-lp8x4x.c
@@ -0,0 +1,227 @@
+/*
+ * linux/drivers/irqchip/irq-lp8x4x.c
+ *
+ * Support for ICP DAS LP-8x4x FPGA irq
+ * Copyright (C) 2013 Sergei Ianovich <ynvich@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation or any later version.
+ */
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+
+#define EOI 0x00000000
+#define INSINT 0x00000002
+#define ENSYSINT 0x00000004
+#define PRIMINT 0x00000006
+#define PRIMINT_MASK 0xe0
+#define SECOINT 0x00000008
+#define SECOINT_MASK 0x1f
+#define ENRISEINT 0x0000000A
+#define CLRRISEINT 0x0000000C
+#define ENHILVINT 0x0000000E
+#define CLRHILVINT 0x00000010
+#define ENFALLINT 0x00000012
+#define CLRFALLINT 0x00000014
+#define IRQ_MEM_SIZE 0x00000016
+#define LP8X4X_NUM_IRQ_DEFAULT 16
+
+/**
+ * struct lp8x4x_irq_data - LP8X4X custom irq controller state container
+ * @base: base IO memory address
+ * @irq_domain: Interrupt translation domain; responsible for mapping
+ * between hwirq number and linux irq number
+ * @irq_sys_enabled: mask keeping track of interrupts enabled in the
+ * register which vendor calls 'system'
+ * @irq_high_enabled: mask keeping track of interrupts enabled in the
+ * register which vendor calls 'high'
+ *
+ * The structure implements State Container from
+ * Documentation/driver-model/design-patterns.txt
+ */
+
+struct lp8x4x_irq_data {
+ void *base;
+ struct irq_domain *domain;
+ unsigned char irq_sys_enabled;
+ unsigned char irq_high_enabled;
+};
+
+static void lp8x4x_mask_irq(struct irq_data *d)
+{
+ unsigned mask;
+ unsigned long hwirq = d->hwirq;
+ struct lp8x4x_irq_data *host = irq_data_get_irq_chip_data(d);
+
+ if (hwirq < 8) {
+ host->irq_high_enabled &= ~BIT(hwirq);
+
+ mask = ioread8(host->base + ENHILVINT);
+ mask &= ~BIT(hwirq);
+ iowrite8(mask, host->base + ENHILVINT);
+ } else {
+ hwirq -= 8;
+ host->irq_sys_enabled &= ~BIT(hwirq);
+
+ mask = ioread8(host->base + ENSYSINT);
+ mask &= ~BIT(hwirq);
+ iowrite8(mask, host->base + ENSYSINT);
+ }
+}
+
+static void lp8x4x_unmask_irq(struct irq_data *d)
+{
+ unsigned mask;
+ unsigned long hwirq = d->hwirq;
+ struct lp8x4x_irq_data *host = irq_data_get_irq_chip_data(d);
+
+ if (hwirq < 8) {
+ host->irq_high_enabled |= BIT(hwirq);
+ mask = ioread8(host->base + CLRHILVINT);
+ mask |= BIT(hwirq);
+ iowrite8(mask, host->base + CLRHILVINT);
+
+ mask = ioread8(host->base + ENHILVINT);
+ mask |= BIT(hwirq);
+ iowrite8(mask, host->base + ENHILVINT);
+ } else {
+ hwirq -= 8;
+ host->irq_sys_enabled |= BIT(hwirq);
+
+ mask = ioread8(host->base + SECOINT);
+ mask |= BIT(hwirq);
+ iowrite8(mask, host->base + SECOINT);
+
+ mask = ioread8(host->base + ENSYSINT);
+ mask |= BIT(hwirq);
+ iowrite8(mask, host->base + ENSYSINT);
+ }
+}
+
+static struct irq_chip lp8x4x_irq_chip = {
+ .name = "FPGA",
+ .irq_ack = lp8x4x_mask_irq,
+ .irq_mask = lp8x4x_mask_irq,
+ .irq_mask_ack = lp8x4x_mask_irq,
+ .irq_unmask = lp8x4x_unmask_irq,
+};
+
+static void lp8x4x_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+ int n;
+ unsigned long mask;
+ struct irq_chip *chip = irq_desc_get_chip(desc);
+ struct lp8x4x_irq_data *host = irq_desc_get_handler_data(desc);
+
+ chained_irq_enter(chip, desc);
+
+ for (;;) {
+ mask = ioread8(host->base + CLRHILVINT) & 0xff;
+ mask |= (ioread8(host->base + SECOINT) & SECOINT_MASK) << 8;
+ mask |= (ioread8(host->base + PRIMINT) & PRIMINT_MASK) << 8;
+ mask &= host->irq_high_enabled | (host->irq_sys_enabled << 8);
+ if (mask == 0)
+ break;
+ for_each_set_bit(n, &mask, BITS_PER_LONG)
+ generic_handle_irq(irq_find_mapping(host->domain, n));
+ }
+
+ iowrite8(0, host->base + EOI);
+ chained_irq_exit(chip, desc);
+}
+
+static int lp8x4x_irq_domain_map(struct irq_domain *d, unsigned int irq,
+ irq_hw_number_t hw)
+{
+ struct lp8x4x_irq_data *host = d->host_data;
+ int err;
+
+ err = irq_set_chip_data(irq, host);
+ if (err < 0)
+ return err;
+
+ irq_set_chip_and_handler(irq, &lp8x4x_irq_chip, handle_level_irq);
+ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+ return 0;
+}
+
+const struct irq_domain_ops lp8x4x_irq_domain_ops = {
+ .map = lp8x4x_irq_domain_map,
+ .xlate = irq_domain_xlate_onecell,
+};
+
+static struct of_device_id lp8x4x_irq_dt_ids[] = {
+ { .compatible = "icpdas,irq-lp8x4x", },
+ {}
+};
+
+static int lp8x4x_irq_probe(struct platform_device *pdev)
+{
+ struct resource *res_mem, *res_irq;
+ struct device_node *np = pdev->dev.of_node;
+ struct lp8x4x_irq_data *host;
+ int i, err;
+
+ res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (!res_mem || !res_irq || resource_size(res_mem) < IRQ_MEM_SIZE)
+ return -ENODEV;
+
+ host = devm_kzalloc(&pdev->dev, sizeof(*host), GFP_KERNEL);
+ if (!host)
+ return -ENODEV;
+
+ host->base = devm_ioremap_resource(&pdev->dev, res_mem);
+ if (!host->base) {
+ dev_err(&pdev->dev, "Failed to ioremap %p\n", host->base);
+ return -EFAULT;
+ }
+
+ host->domain = irq_domain_add_linear(np, LP8X4X_NUM_IRQ_DEFAULT,
+ &lp8x4x_irq_domain_ops, host);
+ if (!host->domain) {
+ dev_err(&pdev->dev, "Failed to add IRQ domain\n");
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < LP8X4X_NUM_IRQ_DEFAULT; i++) {
+ err = irq_create_mapping(host->domain, i);
+ if (err < 0)
+ dev_err(&pdev->dev, "Failed to map IRQ %i\n", i);
+ }
+
+ /* Initialize chip registers */
+ iowrite8(0, host->base + CLRRISEINT);
+ iowrite8(0, host->base + ENRISEINT);
+ iowrite8(0, host->base + CLRFALLINT);
+ iowrite8(0, host->base + ENFALLINT);
+ iowrite8(0, host->base + CLRHILVINT);
+ iowrite8(0, host->base + ENHILVINT);
+ iowrite8(0, host->base + ENSYSINT);
+ iowrite8(0, host->base + SECOINT);
+
+ irq_set_handler_data(res_irq->start, host);
+ irq_set_chained_handler(res_irq->start, lp8x4x_irq_handler);
+
+ return 0;
+}
+
+static struct platform_driver lp8x4x_irq_driver = {
+ .probe = lp8x4x_irq_probe,
+ .driver = {
+ .name = "irq-lp8x4x",
+ .of_match_table = lp8x4x_irq_dt_ids,
+ },
+};
+
+static int __init lp8x4x_irq_init(void)
+{
+ return platform_driver_register(&lp8x4x_irq_driver);
+}
+postcore_initcall(lp8x4x_irq_init);
--
1.8.4.2
^ permalink raw reply related [flat|nested] 148+ messages in thread
* Re: [PATCH v3 11/21] ARM: pxa: support ICP DAS LP-8x4x FPGA irq
2014-01-15 7:39 ` Linus Walleij
@ 2014-01-15 13:17 ` Sergei Ianovich
0 siblings, 0 replies; 148+ messages in thread
From: Sergei Ianovich @ 2014-01-15 13:17 UTC (permalink / raw)
To: Linus Walleij
Cc: linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, Arnd Bergmann, Rob Herring,
Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala, Rob Landley,
Russell King, Thomas Gleixner, Grant Likely,
open list:OPEN FIRMWARE AND..., open list:DOCUMENTATION
On Wed, 2014-01-15 at 08:39 +0100, Linus Walleij wrote:
> On Wed, Jan 8, 2014 at 8:01 PM, Sergei Ianovich <ynvich@gmail.com> wrote:
> Hm I don't know why I was deluded into thinking this had something to
> do with GPIO. I must have been soft in the head. Sorry about all those
> comments ...
It's not your fault for sure. My commit message wasn't clear enough and
needed clarifications. It is better now.
Thanks for constructive reviewing.
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH v3 10/21] mtd: support BB SRAM on ICP DAS LP-8x4x
2013-12-17 19:37 ` [PATCH v3 10/21] mtd: support BB SRAM " Sergei Ianovich
@ 2014-04-16 5:04 ` Brian Norris
2014-04-16 5:21 ` Sergei Ianovich
0 siblings, 1 reply; 148+ messages in thread
From: Brian Norris @ 2014-04-16 5:04 UTC (permalink / raw)
To: Sergei Ianovich
Cc: linux-kernel, linux-arm-kernel, Rob Herring, Pawel Moll,
Mark Rutland, Ian Campbell, Kumar Gala, Russell King,
David Woodhouse, Grant Likely, Artem Bityutskiy, Robert Jarzmik,
Kees Cook, Randy Dunlap, Philip Avinash,
open list:OPEN FIRMWARE AND..., open list:MEMORY TECHNOLOGY...
Hi Sergei,
On Tue, Dec 17, 2013 at 11:37:40PM +0400, Sergei Ianovich wrote:
> This provides an MTD device driver for 512kB of battery backed up SRAM
> on ICPDAS LP-8X4X programmable automation controllers.
>
> SRAM chip is connected via FPGA and is not accessible without a driver,
> unlike flash memory which is wired to CPU MMU.
>
> This SRAM becomes an excellent persisent storage of volatile process
> data like counter values and sensor statuses. Storing those data in
> flash or mmc card is not a viable solution.
>
> Signed-off-by: Sergei Ianovich <ynvich@gmail.com>
> ---
> v2..v3
> * no changes (except number 08/16 -> 10/21)
>
> v0..v2
> * use device tree
> * use devm helpers where possible
What's the status of this series? Is the rest of this platform support
going in via other trees yet? I have a few trivial comments, but this
driver mostly looks good as-is.
> arch/arm/boot/dts/pxa27x-lp8x4x.dts | 6 +
> arch/arm/configs/lp8x4x_defconfig | 1 +
> drivers/mtd/devices/Kconfig | 14 +++
> drivers/mtd/devices/Makefile | 1 +
> drivers/mtd/devices/sram_lp8x4x.c | 227 ++++++++++++++++++++++++++++++++++++
> 5 files changed, 249 insertions(+)
> create mode 100644 drivers/mtd/devices/sram_lp8x4x.c
>
> diff --git a/arch/arm/boot/dts/pxa27x-lp8x4x.dts b/arch/arm/boot/dts/pxa27x-lp8x4x.dts
> index 872c386..07856e0 100644
> --- a/arch/arm/boot/dts/pxa27x-lp8x4x.dts
> +++ b/arch/arm/boot/dts/pxa27x-lp8x4x.dts
> @@ -161,6 +161,12 @@
> reg = <0x901c 0x1>;
> status = "okay";
> };
> +
> + sram@a000 {
> + compatible = "icpdas,sram-lp8x4x";
> + reg = <0xa000 0x1000
> + 0x901e 0x1>;
> + };
You'll need a (trivial) DT binding doc in
Documentation/devicetree/bindings/ to go with this. You might also need
to split the arch/arm/boot/dts/ stuff out to a separate patch, so the
MTD driver can go in the MTD tree separate from the ARM tree bits.
> };
> };
> };
> diff --git a/arch/arm/configs/lp8x4x_defconfig b/arch/arm/configs/lp8x4x_defconfig
> index d60e37a..17a4e6f 100644
> --- a/arch/arm/configs/lp8x4x_defconfig
> +++ b/arch/arm/configs/lp8x4x_defconfig
> @@ -57,6 +57,7 @@ CONFIG_MTD_CFI_ADV_OPTIONS=y
> CONFIG_MTD_CFI_GEOMETRY=y
> CONFIG_MTD_CFI_INTELEXT=y
> CONFIG_MTD_PHYSMAP_OF=y
> +CONFIG_MTD_SRAM_LP8X4X=y
> CONFIG_PROC_DEVICETREE=y
> CONFIG_BLK_DEV_LOOP=y
> CONFIG_BLK_DEV_LOOP_MIN_COUNT=2
> diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig
> index 0128138..95f2075 100644
> --- a/drivers/mtd/devices/Kconfig
> +++ b/drivers/mtd/devices/Kconfig
> @@ -217,4 +217,18 @@ config BCH_CONST_T
> default 4
> endif
>
> +config MTD_SRAM_LP8X4X
> + tristate "SRAM on ICPDAS LP-8X4X"
> + depends on OF && ARCH_PXA
> + ---help---
> + This provides an MTD device driver for 512kiB of battery backed up SRAM
> + on ICPDAS LP-8X4X programmable automation controllers.
> +
> + SRAM chip is connected via FPGA and is not accessible without a driver,
> + unlike flash memory which is wired to CPU MMU.
> +
> + Say N, unless you plan to run this kernel on LP-8X4X.
> +
> + If you say M, the module will be called sram_lp8x4x.
> +
> endmenu
> diff --git a/drivers/mtd/devices/Makefile b/drivers/mtd/devices/Makefile
> index d83bd73..56a74c9 100644
> --- a/drivers/mtd/devices/Makefile
> +++ b/drivers/mtd/devices/Makefile
> @@ -16,6 +16,7 @@ obj-$(CONFIG_MTD_NAND_OMAP_BCH) += elm.o
> obj-$(CONFIG_MTD_SPEAR_SMI) += spear_smi.o
> obj-$(CONFIG_MTD_SST25L) += sst25l.o
> obj-$(CONFIG_MTD_BCM47XXSFLASH) += bcm47xxsflash.o
> +obj-$(CONFIG_MTD_SRAM_LP8X4X) += sram_lp8x4x.o
>
>
> CFLAGS_docg3.o += -I$(src)
> diff --git a/drivers/mtd/devices/sram_lp8x4x.c b/drivers/mtd/devices/sram_lp8x4x.c
> new file mode 100644
> index 0000000..9dc7149
> --- /dev/null
> +++ b/drivers/mtd/devices/sram_lp8x4x.c
> @@ -0,0 +1,227 @@
> +/*
> + * linux/drivers/mtd/devices/lp8x4x_sram.c
> + *
> + * MTD Driver for SRAM on ICPDAS LP-8x4x
> + * Copyright (C) 2013 Sergei Ianovich <ynvich@gmail.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation or any later version.
> + */
> +
> +#include <linux/init.h>
> +#include <linux/io.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/mtd/map.h>
> +#include <linux/mtd/mtd.h>
> +#include <linux/mtd/partitions.h>
> +#include <linux/platform_device.h>
> +#include <linux/of_device.h>
> +#include <linux/slab.h>
> +#include <linux/string_helpers.h>
> +#include <linux/types.h>
> +
> +#include <asm/mach/flash.h>
Do you need this? It looks unused.
> +
> +struct lp8x4x_sram_info {
> + void __iomem *bank;
> + void __iomem *virt;
> + struct mutex lock;
> + unsigned active_bank;
> + struct mtd_info mtd;
> +};
> +
> +static int
> +lp8x4x_sram_erase(struct mtd_info *mtd, struct erase_info *instr)
> +{
> + struct lp8x4x_sram_info *info = mtd->priv;
> + unsigned bank = instr->addr >> 11;
> + unsigned offset = (instr->addr & 0x7ff) << 1;
> + loff_t i;
> +
> + mutex_lock(&info->lock);
> + if (unlikely(bank != info->active_bank)) {
> + info->active_bank = bank;
> + iowrite8(bank, info->bank);
> + }
> + for (i = 0; i < instr->len; i++) {
> + iowrite8(0xff, info->virt + offset);
> + offset += 2;
> + if (unlikely(offset == 0)) {
> + info->active_bank++;
> + iowrite8(info->active_bank, info->bank);
> + }
> + }
> + mutex_unlock(&info->lock);
> + instr->state = MTD_ERASE_DONE;
> + mtd_erase_callback(instr);
> +
> + return 0;
> +}
> +
> +static int
> +lp8x4x_sram_write(struct mtd_info *mtd, loff_t to, size_t len,
> + size_t *retlen, const u_char *b)
> +{
> + struct lp8x4x_sram_info *info = mtd->priv;
> + unsigned bank = to >> 11;
> + unsigned offset = (to & 0x7ff) << 1;
> + loff_t i;
> +
> + mutex_lock(&info->lock);
> + if (unlikely(bank != info->active_bank)) {
> + info->active_bank = bank;
> + iowrite8(bank, info->bank);
> + }
> + for (i = 0; i < len; i++) {
> + iowrite8(b[i], info->virt + offset);
> + offset += 2;
> + if (unlikely(offset == 0)) {
> + info->active_bank++;
> + iowrite8(info->active_bank, info->bank);
> + }
> + }
> + mutex_unlock(&info->lock);
> + *retlen = len;
> + return 0;
> +}
> +
> +static int
> +lp8x4x_sram_read(struct mtd_info *mtd, loff_t from, size_t len,
> + size_t *retlen, u_char *b)
> +{
> + struct lp8x4x_sram_info *info = mtd->priv;
> + unsigned bank = from >> 11;
> + unsigned offset = (from & 0x7ff) << 1;
> + loff_t i;
> +
> + mutex_lock(&info->lock);
> + if (unlikely(bank != info->active_bank)) {
> + info->active_bank = bank;
> + iowrite8(bank, info->bank);
> + }
> + for (i = 0; i < len; i++) {
> + b[i] = ioread8(info->virt + offset);
> + offset += 2;
> + if (unlikely(offset == 0)) {
> + info->active_bank++;
> + iowrite8(info->active_bank, info->bank);
> + }
> + }
> + mutex_unlock(&info->lock);
> + *retlen = len;
> + return 0;
> +}
> +
> +static void
> +lp8x4x_sram_sync(struct mtd_info *mtd)
> +{
> +}
You don't need the empty call-back. See mtd_sync(), which only calls the
_sync callback if it's filled in.
> +
> +static struct of_device_id of_flash_match[] = {
> + {
> + .compatible = "icpdas,sram-lp8x4x",
> + },
> + { },
> +};
> +MODULE_DEVICE_TABLE(of, of_flash_match);
> +
> +static const char * const probe_types[] = {
> + "cmdlinepart", "RedBoot", "ofpart", "ofoldpart", NULL };
Please drop 'ofoldpart'; it is obsolte. And do you really want
'RedBoot'?
> +
> +static int
> +lp8x4x_sram_probe(struct platform_device *pdev)
> +{
> + const struct of_device_id *match;
> + struct lp8x4x_sram_info *info;
> + struct resource *r1, *r2;
> + char sz_str[16];
> + struct mtd_part_parser_data ppdata;
> + int err = 0;
> +
> + match = of_match_device(of_flash_match, &pdev->dev);
> + if (!match)
> + return -EINVAL;
> +
> + r1 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> + r2 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
> + if (!r1 || !r2)
> + return -ENODEV;
Move these next to the devm_ioremap_resource(), and then remove the
if (!r1 || !r2)
checks, since devm_ioremap_resource() does them for you. (See
lib/devres.c.)
> +
> + info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
> + if (!info)
> + return -ENOMEM;
> +
> + info->virt = devm_ioremap_resource(&pdev->dev, r1);
> + if (!info->virt) {
> + dev_err(&pdev->dev, "Failed to ioremap %p\n",
> + info->virt);
You don't need the print message. devm_ioremap_resource() handles this
for you.
> + return -EFAULT;
> + }
> +
> + info->bank = devm_ioremap_resource(&pdev->dev, r2);
> + if (!info->bank) {
> + dev_err(&pdev->dev, "Failed to ioremap %p\n",
> + info->bank);
Ditto.
> + return -EFAULT;
> + }
> +
> + info->mtd.priv = info;
> + info->mtd.name = "SRAM";
> + info->mtd.type = MTD_RAM;
> + info->mtd.flags = MTD_CAP_RAM;
> + info->mtd.size = resource_size(r1) << 7;
> + info->mtd.erasesize = 512;
> + info->mtd.writesize = 4;
> + info->mtd._erase = lp8x4x_sram_erase;
> + info->mtd._write = lp8x4x_sram_write;
> + info->mtd._read = lp8x4x_sram_read;
> + info->mtd._sync = lp8x4x_sram_sync;
> + info->mtd.owner = THIS_MODULE;
> +
> + mutex_init(&info->lock);
> + iowrite8(info->active_bank, info->bank);
> + platform_set_drvdata(pdev, info);
> +
> + ppdata.of_node = pdev->dev.of_node;
> + err = mtd_device_parse_register(&info->mtd, probe_types, &ppdata,
> + NULL, 0);
If you don't need the other partition types (commented above), then you
can just use the defaults (drivers/mtd/mtdpart.c,
default_mtd_part_types) by dropping your 'probe_types' and making the
second argument NULL.
> +
> + if (err < 0) {
> + dev_err(&pdev->dev, "Failed to register platform device\n");
How about "failed to register MTD"?
> + return err;
> + }
> +
> + string_get_size(info->mtd.size, STRING_UNITS_2, sz_str,
> + sizeof(sz_str));
> + dev_info(&pdev->dev, "using %s SRAM on LP-8X4X as %s\n", sz_str,
> + dev_name(&info->mtd.dev));
> + return 0;
> +}
> +
> +static int
> +lp8x4x_sram_remove(struct platform_device *dev)
> +{
> + struct lp8x4x_sram_info *info = platform_get_drvdata(dev);
> +
> + mtd_device_unregister(&info->mtd);
Please check the return code.
> + platform_set_drvdata(dev, NULL);
I don't think you need to do this any more. The driver core takes care
of this on removal.
> + return 0;
(So just: return mtd_device_unregister(&info->mtd);)
> +}
> +
> +static struct platform_driver lp8x4x_sram_driver = {
> + .driver = {
> + .name = "sram-lp8x4x",
> + .owner = THIS_MODULE,
> + .of_match_table = of_flash_match,
> + },
> + .probe = lp8x4x_sram_probe,
> + .remove = lp8x4x_sram_remove,
> +};
> +
> +module_platform_driver(lp8x4x_sram_driver);
> +
> +MODULE_LICENSE("GPL");
> +MODULE_AUTHOR("Sergei Ianovich <ynvich@gmail.com>");
> +MODULE_DESCRIPTION("MTD driver for SRAM on ICPDAS LP-8x4x");
With that, you have my:
Reviewed-by: Brian Norris <computersforpeace@gmail.com>
and I can merge this to the MTD tree if/when you'd like.
Brian
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH v3 10/21] mtd: support BB SRAM on ICP DAS LP-8x4x
2014-04-16 5:04 ` Brian Norris
@ 2014-04-16 5:21 ` Sergei Ianovich
0 siblings, 0 replies; 148+ messages in thread
From: Sergei Ianovich @ 2014-04-16 5:21 UTC (permalink / raw)
To: Brian Norris
Cc: linux-kernel, linux-arm-kernel, Rob Herring, Pawel Moll,
Mark Rutland, Ian Campbell, Kumar Gala, Russell King,
David Woodhouse, Grant Likely, Artem Bityutskiy, Robert Jarzmik,
Kees Cook, Randy Dunlap, Philip Avinash,
open list:OPEN FIRMWARE AND..., open list:MEMORY TECHNOLOGY...
On Tue, 2014-04-15 at 22:04 -0700, Brian Norris wrote:
> Hi Sergei,
>
> On Tue, Dec 17, 2013 at 11:37:40PM +0400, Sergei Ianovich wrote:
> > This provides an MTD device driver for 512kB of battery backed up SRAM
> > on ICPDAS LP-8X4X programmable automation controllers.
> >
> > SRAM chip is connected via FPGA and is not accessible without a driver,
> > unlike flash memory which is wired to CPU MMU.
> >
> > This SRAM becomes an excellent persisent storage of volatile process
> > data like counter values and sensor statuses. Storing those data in
> > flash or mmc card is not a viable solution.
> >
> > Signed-off-by: Sergei Ianovich <ynvich@gmail.com>
> > ---
> > v2..v3
> > * no changes (except number 08/16 -> 10/21)
> >
> > v0..v2
> > * use device tree
> > * use devm helpers where possible
>
> What's the status of this series? Is the rest of this platform support
> going in via other trees yet? I have a few trivial comments, but this
> driver mostly looks good as-is.
(...)
> You'll need a (trivial) DT binding doc in
> Documentation/devicetree/bindings/ to go with this. You might also need
> to split the arch/arm/boot/dts/ stuff out to a separate patch, so the
> MTD driver can go in the MTD tree separate from the ARM tree bits.
(...)
> With that, you have my:
>
> Reviewed-by: Brian Norris <computersforpeace@gmail.com>
>
> and I can merge this to the MTD tree if/when you'd like.
Thanks for response, the rest of the series is stuck on a DMA driver
with no development activity. I'll fix the comments, separate ARM staff
and refile the patch.
^ permalink raw reply [flat|nested] 148+ messages in thread
* [PATCH v4 01/21] serial: rewrite pxa2xx-uart to use 8250_core
[not found] ` <1397668411-27162-1-git-send-email-ynvich@gmail.com>
@ 2014-04-16 17:13 ` Sergei Ianovich
2015-01-19 18:08 ` Rob Herring
2014-04-16 17:13 ` [PATCH v4 02/21] ARM: dts: pxa2xx fix compatible strings Sergei Ianovich
` (2 subsequent siblings)
3 siblings, 1 reply; 148+ messages in thread
From: Sergei Ianovich @ 2014-04-16 17:13 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel
Cc: Sergei Ianovich, Russell King, Greg Kroah-Hartman, Jiri Slaby,
Grant Likely, Rob Herring, James Cameron, Heikki Krogerus,
Paul Bolle, Arnd Bergmann, Randy Dunlap, Stefan Seyfried,
open list:SERIAL DRIVERS, open list:OPEN FIRMWARE AND...
pxa2xx-uart was a separate uart platform driver. It was declaring
the same device names and numbers as 8250 driver. As a result,
it was impossible to use 8250 driver on PXA SoCs.
Upon closer examination pxa2xx-uart turned out to be a clone of
8250_core driver.
Workaround for Erratum #19 according to Marvel(R) PXA270M Processor
Specification Update (April 19, 2010) is dropped. 8250_core reads
from FIFO immediately after checking DR bit in LSR.
Signed-off-by: Sergei Ianovich <ynvich@gmail.com>
Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Reviewed-by: James Cameron <quozl@laptop.org>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
Resenging together with the rest of the series as the series
breaks without this one at [PATCH 12/21]
no changes v3..v4
changes v2..v3
* remove devm_free/put as suggested by Heikki Krogerus
* use SET_SYSTEM_SLEEP_PM_OPS macro to set pm ops as suggested
by Heikki Krogerus
changes v1..v2
* actually implement workaround for E74 in dl_write as spooted
by James Cameron
* added comment about E19 in commit message
arch/arm/configs/am200epdkit_defconfig | 3 +-
arch/arm/configs/cm_x2xx_defconfig | 3 +-
arch/arm/configs/cm_x300_defconfig | 3 +-
arch/arm/configs/colibri_pxa270_defconfig | 3 +-
arch/arm/configs/colibri_pxa300_defconfig | 3 +-
arch/arm/configs/corgi_defconfig | 4 +-
arch/arm/configs/em_x270_defconfig | 3 +-
arch/arm/configs/ezx_defconfig | 3 +-
arch/arm/configs/h5000_defconfig | 3 +-
arch/arm/configs/imote2_defconfig | 3 +-
arch/arm/configs/lpd270_defconfig | 3 +-
arch/arm/configs/lubbock_defconfig | 3 +-
arch/arm/configs/mainstone_defconfig | 3 +-
arch/arm/configs/mmp2_defconfig | 3 +-
arch/arm/configs/pcm027_defconfig | 3 +-
arch/arm/configs/pxa168_defconfig | 3 +-
arch/arm/configs/pxa255-idp_defconfig | 3 +-
arch/arm/configs/pxa3xx_defconfig | 3 +-
arch/arm/configs/pxa910_defconfig | 3 +-
arch/arm/configs/raumfeld_defconfig | 3 +-
arch/arm/configs/spitz_defconfig | 4 +-
arch/arm/configs/trizeps4_defconfig | 3 +-
arch/arm/configs/viper_defconfig | 4 +-
arch/arm/configs/xcep_defconfig | 3 +-
drivers/tty/serial/8250/8250_pxa.c | 178 ++++++
drivers/tty/serial/8250/Kconfig | 9 +
drivers/tty/serial/8250/Makefile | 1 +
drivers/tty/serial/Kconfig | 23 -
drivers/tty/serial/Makefile | 1 -
drivers/tty/serial/pxa.c | 971 ------------------------------
30 files changed, 236 insertions(+), 1022 deletions(-)
create mode 100644 drivers/tty/serial/8250/8250_pxa.c
delete mode 100644 drivers/tty/serial/pxa.c
diff --git a/arch/arm/configs/am200epdkit_defconfig b/arch/arm/configs/am200epdkit_defconfig
index f0dea52..0cde234 100644
--- a/arch/arm/configs/am200epdkit_defconfig
+++ b/arch/arm/configs/am200epdkit_defconfig
@@ -60,8 +60,9 @@ CONFIG_BLK_DEV_IDECS=m
CONFIG_NETDEVICES=y
CONFIG_NET_ETHERNET=y
CONFIG_SMC91X=m
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_PXA=y
-CONFIG_SERIAL_PXA_CONSOLE=y
# CONFIG_LEGACY_PTYS is not set
# CONFIG_HW_RANDOM is not set
# CONFIG_HWMON is not set
diff --git a/arch/arm/configs/cm_x2xx_defconfig b/arch/arm/configs/cm_x2xx_defconfig
index a93ff8d..b9fbe65 100644
--- a/arch/arm/configs/cm_x2xx_defconfig
+++ b/arch/arm/configs/cm_x2xx_defconfig
@@ -96,8 +96,9 @@ CONFIG_KEYBOARD_PXA27x=m
CONFIG_INPUT_TOUCHSCREEN=y
CONFIG_TOUCHSCREEN_UCB1400=m
# CONFIG_SERIO_SERPORT is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_PXA=y
-CONFIG_SERIAL_PXA_CONSOLE=y
CONFIG_LEGACY_PTY_COUNT=16
# CONFIG_HW_RANDOM is not set
CONFIG_I2C=y
diff --git a/arch/arm/configs/cm_x300_defconfig b/arch/arm/configs/cm_x300_defconfig
index f4b7672..53a82ae 100644
--- a/arch/arm/configs/cm_x300_defconfig
+++ b/arch/arm/configs/cm_x300_defconfig
@@ -80,8 +80,9 @@ CONFIG_TOUCHSCREEN_WM97XX=m
# CONFIG_TOUCHSCREEN_WM9713 is not set
# CONFIG_SERIO is not set
# CONFIG_LEGACY_PTYS is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_PXA=y
-CONFIG_SERIAL_PXA_CONSOLE=y
# CONFIG_HW_RANDOM is not set
CONFIG_I2C=y
CONFIG_I2C_PXA=y
diff --git a/arch/arm/configs/colibri_pxa270_defconfig b/arch/arm/configs/colibri_pxa270_defconfig
index 2ef2c5e..1ce0409 100644
--- a/arch/arm/configs/colibri_pxa270_defconfig
+++ b/arch/arm/configs/colibri_pxa270_defconfig
@@ -103,8 +103,9 @@ CONFIG_INPUT_TOUCHSCREEN=y
CONFIG_INPUT_MISC=y
CONFIG_INPUT_UINPUT=m
CONFIG_SERIO_LIBPS2=y
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_PXA=y
-CONFIG_SERIAL_PXA_CONSOLE=y
CONFIG_HW_RANDOM=y
CONFIG_I2C=y
CONFIG_I2C_CHARDEV=y
diff --git a/arch/arm/configs/colibri_pxa300_defconfig b/arch/arm/configs/colibri_pxa300_defconfig
index b985334..f96bda0 100644
--- a/arch/arm/configs/colibri_pxa300_defconfig
+++ b/arch/arm/configs/colibri_pxa300_defconfig
@@ -31,8 +31,9 @@ CONFIG_INPUT_EVDEV=y
# CONFIG_INPUT_MOUSE is not set
CONFIG_INPUT_MISC=y
CONFIG_INPUT_GPIO_ROTARY_ENCODER=y
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_PXA=y
-CONFIG_SERIAL_PXA_CONSOLE=y
CONFIG_HW_RANDOM=y
CONFIG_DEBUG_GPIO=y
# CONFIG_HWMON is not set
diff --git a/arch/arm/configs/corgi_defconfig b/arch/arm/configs/corgi_defconfig
index 1fd1d1d..bb4842d 100644
--- a/arch/arm/configs/corgi_defconfig
+++ b/arch/arm/configs/corgi_defconfig
@@ -131,10 +131,10 @@ CONFIG_TOUCHSCREEN_ADS7846=y
CONFIG_INPUT_MISC=y
CONFIG_INPUT_UINPUT=m
# CONFIG_SERIO is not set
-CONFIG_SERIAL_8250=m
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_CS=m
CONFIG_SERIAL_PXA=y
-CONFIG_SERIAL_PXA_CONSOLE=y
# CONFIG_LEGACY_PTYS is not set
CONFIG_I2C=y
CONFIG_I2C_PXA=y
diff --git a/arch/arm/configs/em_x270_defconfig b/arch/arm/configs/em_x270_defconfig
index 60a21e0..ec0ec54 100644
--- a/arch/arm/configs/em_x270_defconfig
+++ b/arch/arm/configs/em_x270_defconfig
@@ -90,8 +90,9 @@ CONFIG_TOUCHSCREEN_WM97XX=m
# CONFIG_TOUCHSCREEN_WM9705 is not set
# CONFIG_TOUCHSCREEN_WM9713 is not set
# CONFIG_SERIO_SERPORT is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_PXA=y
-CONFIG_SERIAL_PXA_CONSOLE=y
CONFIG_LEGACY_PTY_COUNT=16
# CONFIG_HW_RANDOM is not set
CONFIG_I2C=y
diff --git a/arch/arm/configs/ezx_defconfig b/arch/arm/configs/ezx_defconfig
index d95763d..631e2ec 100644
--- a/arch/arm/configs/ezx_defconfig
+++ b/arch/arm/configs/ezx_defconfig
@@ -215,8 +215,9 @@ CONFIG_INPUT_MISC=y
CONFIG_INPUT_UINPUT=y
CONFIG_INPUT_PCAP=y
# CONFIG_SERIO is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_PXA=y
-CONFIG_SERIAL_PXA_CONSOLE=y
CONFIG_LEGACY_PTY_COUNT=8
# CONFIG_HW_RANDOM is not set
CONFIG_I2C=y
diff --git a/arch/arm/configs/h5000_defconfig b/arch/arm/configs/h5000_defconfig
index 37903e3..655b735 100644
--- a/arch/arm/configs/h5000_defconfig
+++ b/arch/arm/configs/h5000_defconfig
@@ -47,8 +47,9 @@ CONFIG_MTD_PHYSMAP=y
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not set
# CONFIG_SERIO is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_PXA=y
-CONFIG_SERIAL_PXA_CONSOLE=y
CONFIG_LEGACY_PTY_COUNT=32
# CONFIG_HW_RANDOM is not set
# CONFIG_HWMON is not set
diff --git a/arch/arm/configs/imote2_defconfig b/arch/arm/configs/imote2_defconfig
index fd996bb..49d45e9 100644
--- a/arch/arm/configs/imote2_defconfig
+++ b/arch/arm/configs/imote2_defconfig
@@ -193,8 +193,9 @@ CONFIG_INPUT_TOUCHSCREEN=y
CONFIG_INPUT_MISC=y
CONFIG_INPUT_UINPUT=y
# CONFIG_SERIO is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_PXA=y
-CONFIG_SERIAL_PXA_CONSOLE=y
CONFIG_LEGACY_PTY_COUNT=8
# CONFIG_HW_RANDOM is not set
CONFIG_I2C=y
diff --git a/arch/arm/configs/lpd270_defconfig b/arch/arm/configs/lpd270_defconfig
index 1c8c9ee..c3927b6 100644
--- a/arch/arm/configs/lpd270_defconfig
+++ b/arch/arm/configs/lpd270_defconfig
@@ -38,8 +38,9 @@ CONFIG_SMC91X=y
CONFIG_INPUT_EVDEV=y
# CONFIG_INPUT_MOUSE is not set
# CONFIG_SERIO_SERPORT is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_PXA=y
-CONFIG_SERIAL_PXA_CONSOLE=y
# CONFIG_HW_RANDOM is not set
CONFIG_FB=y
CONFIG_FB_PXA=y
diff --git a/arch/arm/configs/lubbock_defconfig b/arch/arm/configs/lubbock_defconfig
index c4ba274..c8b0436 100644
--- a/arch/arm/configs/lubbock_defconfig
+++ b/arch/arm/configs/lubbock_defconfig
@@ -37,8 +37,9 @@ CONFIG_PCMCIA_PCNET=y
CONFIG_INPUT_EVDEV=y
# CONFIG_SERIO_SERPORT is not set
CONFIG_SERIO_SA1111=y
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_PXA=y
-CONFIG_SERIAL_PXA_CONSOLE=y
# CONFIG_VGA_CONSOLE is not set
CONFIG_USB_GADGET=y
CONFIG_USB_G_SERIAL=m
diff --git a/arch/arm/configs/mainstone_defconfig b/arch/arm/configs/mainstone_defconfig
index 04efa1b..768892c 100644
--- a/arch/arm/configs/mainstone_defconfig
+++ b/arch/arm/configs/mainstone_defconfig
@@ -34,8 +34,9 @@ CONFIG_SMC91X=y
CONFIG_INPUT_EVDEV=y
# CONFIG_INPUT_MOUSE is not set
# CONFIG_SERIO_SERPORT is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_PXA=y
-CONFIG_SERIAL_PXA_CONSOLE=y
CONFIG_FB=y
CONFIG_FB_PXA=y
# CONFIG_VGA_CONSOLE is not set
diff --git a/arch/arm/configs/mmp2_defconfig b/arch/arm/configs/mmp2_defconfig
index f1cb95e..1ced9df 100644
--- a/arch/arm/configs/mmp2_defconfig
+++ b/arch/arm/configs/mmp2_defconfig
@@ -44,8 +44,9 @@ CONFIG_SMC91X=y
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not set
# CONFIG_SERIO is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_PXA=y
-CONFIG_SERIAL_PXA_CONSOLE=y
# CONFIG_LEGACY_PTYS is not set
# CONFIG_HW_RANDOM is not set
CONFIG_I2C=y
diff --git a/arch/arm/configs/pcm027_defconfig b/arch/arm/configs/pcm027_defconfig
index 2f136c3..1280128 100644
--- a/arch/arm/configs/pcm027_defconfig
+++ b/arch/arm/configs/pcm027_defconfig
@@ -60,8 +60,9 @@ CONFIG_SMC91X=y
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not set
# CONFIG_SERIO is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_PXA=y
-CONFIG_SERIAL_PXA_CONSOLE=y
# CONFIG_LEGACY_PTYS is not set
# CONFIG_HW_RANDOM is not set
CONFIG_I2C=y
diff --git a/arch/arm/configs/pxa168_defconfig b/arch/arm/configs/pxa168_defconfig
index 74d7e01..1668dac 100644
--- a/arch/arm/configs/pxa168_defconfig
+++ b/arch/arm/configs/pxa168_defconfig
@@ -40,8 +40,9 @@ CONFIG_SMC91X=y
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not set
# CONFIG_SERIO is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_PXA=y
-CONFIG_SERIAL_PXA_CONSOLE=y
# CONFIG_LEGACY_PTYS is not set
# CONFIG_HW_RANDOM is not set
# CONFIG_HWMON is not set
diff --git a/arch/arm/configs/pxa255-idp_defconfig b/arch/arm/configs/pxa255-idp_defconfig
index 917a070..399a706 100644
--- a/arch/arm/configs/pxa255-idp_defconfig
+++ b/arch/arm/configs/pxa255-idp_defconfig
@@ -35,8 +35,9 @@ CONFIG_SMC91X=y
CONFIG_INPUT_EVDEV=y
# CONFIG_INPUT_MOUSE is not set
# CONFIG_SERIO_SERPORT is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_PXA=y
-CONFIG_SERIAL_PXA_CONSOLE=y
CONFIG_FB=y
CONFIG_FB_PXA=y
# CONFIG_VGA_CONSOLE is not set
diff --git a/arch/arm/configs/pxa3xx_defconfig b/arch/arm/configs/pxa3xx_defconfig
index 60e3138..7c3e052 100644
--- a/arch/arm/configs/pxa3xx_defconfig
+++ b/arch/arm/configs/pxa3xx_defconfig
@@ -56,8 +56,9 @@ CONFIG_KEYBOARD_PXA27x=y
CONFIG_KEYBOARD_PXA930_ROTARY=y
CONFIG_MOUSE_PXA930_TRKBALL=y
CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_PXA=y
-CONFIG_SERIAL_PXA_CONSOLE=y
# CONFIG_LEGACY_PTYS is not set
# CONFIG_HW_RANDOM is not set
CONFIG_I2C=y
diff --git a/arch/arm/configs/pxa910_defconfig b/arch/arm/configs/pxa910_defconfig
index 3bb7771..cdacfcb 100644
--- a/arch/arm/configs/pxa910_defconfig
+++ b/arch/arm/configs/pxa910_defconfig
@@ -40,8 +40,9 @@ CONFIG_SMC91X=y
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not set
# CONFIG_SERIO is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_PXA=y
-CONFIG_SERIAL_PXA_CONSOLE=y
CONFIG_SPI=y
CONFIG_FB=y
CONFIG_MMP_DISP=y
diff --git a/arch/arm/configs/raumfeld_defconfig b/arch/arm/configs/raumfeld_defconfig
index f7caa90..f1e16f2 100644
--- a/arch/arm/configs/raumfeld_defconfig
+++ b/arch/arm/configs/raumfeld_defconfig
@@ -67,8 +67,9 @@ CONFIG_INPUT_TOUCHSCREEN=y
CONFIG_TOUCHSCREEN_EETI=m
CONFIG_INPUT_MISC=y
CONFIG_INPUT_GPIO_ROTARY_ENCODER=y
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_PXA=y
-CONFIG_SERIAL_PXA_CONSOLE=y
CONFIG_HW_RANDOM=y
CONFIG_I2C=y
CONFIG_I2C_CHARDEV=y
diff --git a/arch/arm/configs/spitz_defconfig b/arch/arm/configs/spitz_defconfig
index 2e0419d..b6efcf5 100644
--- a/arch/arm/configs/spitz_defconfig
+++ b/arch/arm/configs/spitz_defconfig
@@ -128,10 +128,10 @@ CONFIG_TOUCHSCREEN_ADS7846=y
CONFIG_INPUT_MISC=y
CONFIG_INPUT_UINPUT=m
# CONFIG_SERIO is not set
-CONFIG_SERIAL_8250=m
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_CS=m
CONFIG_SERIAL_PXA=y
-CONFIG_SERIAL_PXA_CONSOLE=y
# CONFIG_LEGACY_PTYS is not set
CONFIG_SPI=y
CONFIG_SPI_PXA2XX=y
diff --git a/arch/arm/configs/trizeps4_defconfig b/arch/arm/configs/trizeps4_defconfig
index 3162173..453c79c 100644
--- a/arch/arm/configs/trizeps4_defconfig
+++ b/arch/arm/configs/trizeps4_defconfig
@@ -132,8 +132,9 @@ CONFIG_INPUT_TOUCHSCREEN=y
CONFIG_INPUT_MISC=y
CONFIG_INPUT_UINPUT=m
CONFIG_SERIO_LIBPS2=y
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_PXA=y
-CONFIG_SERIAL_PXA_CONSOLE=y
CONFIG_HW_RANDOM=y
CONFIG_I2C=y
CONFIG_I2C_CHARDEV=y
diff --git a/arch/arm/configs/viper_defconfig b/arch/arm/configs/viper_defconfig
index d36e0d3..4efac06 100644
--- a/arch/arm/configs/viper_defconfig
+++ b/arch/arm/configs/viper_defconfig
@@ -101,11 +101,11 @@ CONFIG_INPUT_MISC=y
CONFIG_INPUT_UINPUT=m
# CONFIG_CONSOLE_TRANSLATIONS is not set
# CONFIG_VT_CONSOLE is not set
-CONFIG_SERIAL_8250=m
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_NR_UARTS=5
CONFIG_SERIAL_8250_RUNTIME_UARTS=5
CONFIG_SERIAL_PXA=y
-CONFIG_SERIAL_PXA_CONSOLE=y
# CONFIG_LEGACY_PTYS is not set
CONFIG_I2C=y
CONFIG_I2C_CHARDEV=y
diff --git a/arch/arm/configs/xcep_defconfig b/arch/arm/configs/xcep_defconfig
index 721832f..b67aeaf 100644
--- a/arch/arm/configs/xcep_defconfig
+++ b/arch/arm/configs/xcep_defconfig
@@ -60,8 +60,9 @@ CONFIG_NET_ETHERNET=y
# CONFIG_INPUT_MOUSE is not set
# CONFIG_SERIO is not set
# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_PXA=y
-CONFIG_SERIAL_PXA_CONSOLE=y
# CONFIG_LEGACY_PTYS is not set
# CONFIG_HW_RANDOM is not set
CONFIG_I2C=m
diff --git a/drivers/tty/serial/8250/8250_pxa.c b/drivers/tty/serial/8250/8250_pxa.c
new file mode 100644
index 0000000..0da0d40
--- /dev/null
+++ b/drivers/tty/serial/8250/8250_pxa.c
@@ -0,0 +1,178 @@
+/*
+ * drivers/tty/serial/8250/8250_pxa.c -- driver for PXA on-board UARTS
+ * Copyright: (C) 2013 Sergei Ianovich <ynvich@gmail.com>
+ *
+ * replaces drivers/serial/pxa.c by Nicolas Pitre
+ * Created: Feb 20, 2003
+ * Copyright: (C) 2003 Monta Vista Software, Inc.
+ *
+ * Based on drivers/serial/8250.c by Russell King.
+ *
+ * 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 <linux/device.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/serial_8250.h>
+#include <linux/serial_core.h>
+#include <linux/serial_reg.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/clk.h>
+#include <linux/pm_runtime.h>
+
+#include "8250.h"
+
+struct pxa8250_data {
+ int line;
+ struct clk *clk;
+};
+
+#ifdef CONFIG_PM
+static int serial_pxa_suspend(struct device *dev)
+{
+ struct pxa8250_data *data = dev_get_drvdata(dev);
+
+ serial8250_suspend_port(data->line);
+
+ return 0;
+}
+
+static int serial_pxa_resume(struct device *dev)
+{
+ struct pxa8250_data *data = dev_get_drvdata(dev);
+
+ serial8250_resume_port(data->line);
+
+ return 0;
+}
+#endif
+
+static const struct dev_pm_ops serial_pxa_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(serial_pxa_suspend, serial_pxa_resume)
+};
+
+static struct of_device_id serial_pxa_dt_ids[] = {
+ { .compatible = "mrvl,pxa-uart", },
+ { .compatible = "mrvl,mmp-uart", },
+ {}
+};
+MODULE_DEVICE_TABLE(of, serial_pxa_dt_ids);
+
+/* Uart divisor latch write */
+static void serial_pxa_dl_write(struct uart_8250_port *up, int value)
+{
+ unsigned int dll;
+
+ serial_out(up, UART_DLL, value & 0xff);
+ /*
+ * work around Erratum #74 according to Marvel(R) PXA270M Processor
+ * Specification Update (April 19, 2010)
+ */
+ dll = serial_in(up, UART_DLL);
+ WARN_ON(dll != (value & 0xff));
+
+ serial_out(up, UART_DLM, value >> 8 & 0xff);
+}
+
+
+static void serial_pxa_pm(struct uart_port *port, unsigned int state,
+ unsigned int oldstate)
+{
+ struct pxa8250_data *data = port->private_data;
+
+ if (!state)
+ clk_prepare_enable(data->clk);
+ else
+ clk_disable_unprepare(data->clk);
+}
+
+static int serial_pxa_probe(struct platform_device *pdev)
+{
+ struct uart_8250_port uart = {};
+ struct pxa8250_data *data;
+ struct resource *mmres, *irqres;
+ int ret;
+
+ mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ irqres = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (!mmres || !irqres)
+ return -ENODEV;
+
+ data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ data->clk = devm_clk_get(&pdev->dev, NULL);
+ if (IS_ERR(data->clk))
+ return PTR_ERR(data->clk);
+
+ ret = clk_prepare(data->clk);
+ if (ret)
+ return ret;
+
+ uart.port.type = PORT_XSCALE;
+ uart.port.iotype = UPIO_MEM32;
+ uart.port.mapbase = mmres->start;
+ uart.port.regshift = 2;
+ uart.port.irq = irqres->start;
+ uart.port.fifosize = 64;
+ uart.port.flags = UPF_IOREMAP | UPF_SKIP_TEST;
+ uart.port.dev = &pdev->dev;
+ uart.port.uartclk = clk_get_rate(data->clk);
+ uart.port.pm = serial_pxa_pm;
+ uart.port.private_data = data;
+ uart.dl_write = serial_pxa_dl_write;
+
+ ret = serial8250_register_8250_port(&uart);
+ if (ret < 0)
+ goto err_clk;
+
+ data->line = ret;
+
+ platform_set_drvdata(pdev, data);
+
+ return 0;
+
+ err_clk:
+ clk_unprepare(data->clk);
+ return ret;
+}
+
+static int serial_pxa_remove(struct platform_device *pdev)
+{
+ struct pxa8250_data *data = platform_get_drvdata(pdev);
+
+ serial8250_unregister_port(data->line);
+
+ clk_unprepare(data->clk);
+
+ return 0;
+}
+
+static struct platform_driver serial_pxa_driver = {
+ .probe = serial_pxa_probe,
+ .remove = serial_pxa_remove,
+
+ .driver = {
+ .name = "pxa2xx-uart",
+ .owner = THIS_MODULE,
+ .pm = &serial_pxa_pm_ops,
+ .of_match_table = serial_pxa_dt_ids,
+ },
+};
+
+module_platform_driver(serial_pxa_driver);
+
+MODULE_AUTHOR("Sergei Ianovich");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:pxa2xx-uart");
diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig
index 2332991..81bd7c9 100644
--- a/drivers/tty/serial/8250/Kconfig
+++ b/drivers/tty/serial/8250/Kconfig
@@ -302,3 +302,12 @@ config SERIAL_8250_RT288X
If you have a Ralink RT288x/RT305x SoC based board and want to use the
serial port, say Y to this option. The driver can handle up to 2 serial
ports. If unsure, say N.
+
+config SERIAL_PXA
+ tristate "PXA serial port support"
+ depends on SERIAL_8250 && (ARCH_PXA || ARCH_MMP)
+ help
+ If you have a machine based on an Intel XScale PXA2xx CPU you
+ can enable its onboard serial ports by enabling this option.
+
+ If you choose M here, the module name will be 8250_pxa.
diff --git a/drivers/tty/serial/8250/Makefile b/drivers/tty/serial/8250/Makefile
index 36d68d0..b7d1b61 100644
--- a/drivers/tty/serial/8250/Makefile
+++ b/drivers/tty/serial/8250/Makefile
@@ -20,3 +20,4 @@ obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o
obj-$(CONFIG_SERIAL_8250_FSL) += 8250_fsl.o
obj-$(CONFIG_SERIAL_8250_DW) += 8250_dw.o
obj-$(CONFIG_SERIAL_8250_EM) += 8250_em.o
+obj-$(CONFIG_SERIAL_PXA) += 8250_pxa.o
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index 2e6d8dd..da46e31 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -395,29 +395,6 @@ config SERIAL_MPSC_CONSOLE
help
Say Y here if you want to support a serial console on a Marvell MPSC.
-config SERIAL_PXA
- bool "PXA serial port support"
- depends on ARCH_PXA || ARCH_MMP
- select SERIAL_CORE
- help
- If you have a machine based on an Intel XScale PXA2xx CPU you
- can enable its onboard serial ports by enabling this option.
-
-config SERIAL_PXA_CONSOLE
- bool "Console on PXA serial port"
- depends on SERIAL_PXA
- select SERIAL_CORE_CONSOLE
- help
- If you have enabled the serial port on the Intel XScale PXA
- CPU you can make it the console by answering Y to this option.
-
- Even if you say Y here, the currently visible virtual console
- (/dev/tty0) will still be used as the system console by default, but
- you can alter that using a kernel command line option such as
- "console=ttySA0". (Try "man bootparam" or see the documentation of
- your boot loader (lilo or loadlin) about how to pass options to the
- kernel at boot time.)
-
config SERIAL_SA1100
bool "SA1100 serial port support"
depends on ARCH_SA1100
diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile
index 3680854..fd71d3f 100644
--- a/drivers/tty/serial/Makefile
+++ b/drivers/tty/serial/Makefile
@@ -20,7 +20,6 @@ obj-$(CONFIG_SERIAL_8250) += 8250/
obj-$(CONFIG_SERIAL_AMBA_PL010) += amba-pl010.o
obj-$(CONFIG_SERIAL_AMBA_PL011) += amba-pl011.o
obj-$(CONFIG_SERIAL_CLPS711X) += clps711x.o
-obj-$(CONFIG_SERIAL_PXA) += pxa.o
obj-$(CONFIG_SERIAL_PNX8XXX) += pnx8xxx_uart.o
obj-$(CONFIG_SERIAL_SA1100) += sa1100.o
obj-$(CONFIG_SERIAL_BCM63XX) += bcm63xx_uart.o
diff --git a/drivers/tty/serial/pxa.c b/drivers/tty/serial/pxa.c
deleted file mode 100644
index f9f20f3..0000000
--- a/drivers/tty/serial/pxa.c
+++ /dev/null
@@ -1,971 +0,0 @@
-/*
- * Based on drivers/serial/8250.c by Russell King.
- *
- * Author: Nicolas Pitre
- * Created: Feb 20, 2003
- * Copyright: (C) 2003 Monta Vista Software, Inc.
- *
- * 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.
- *
- * Note 1: This driver is made separate from the already too overloaded
- * 8250.c because it needs some kirks of its own and that'll make it
- * easier to add DMA support.
- *
- * Note 2: I'm too sick of device allocation policies for serial ports.
- * If someone else wants to request an "official" allocation of major/minor
- * for this driver please be my guest. And don't forget that new hardware
- * to come from Intel might have more than 3 or 4 of those UARTs. Let's
- * hope for a better port registration and dynamic device allocation scheme
- * with the serial core maintainer satisfaction to appear soon.
- */
-
-
-#if defined(CONFIG_SERIAL_PXA_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
-#define SUPPORT_SYSRQ
-#endif
-
-#include <linux/module.h>
-#include <linux/ioport.h>
-#include <linux/init.h>
-#include <linux/console.h>
-#include <linux/sysrq.h>
-#include <linux/serial_reg.h>
-#include <linux/circ_buf.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/of.h>
-#include <linux/platform_device.h>
-#include <linux/tty.h>
-#include <linux/tty_flip.h>
-#include <linux/serial_core.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/slab.h>
-
-#define PXA_NAME_LEN 8
-
-struct uart_pxa_port {
- struct uart_port port;
- unsigned char ier;
- unsigned char lcr;
- unsigned char mcr;
- unsigned int lsr_break_flag;
- struct clk *clk;
- char name[PXA_NAME_LEN];
-};
-
-static inline unsigned int serial_in(struct uart_pxa_port *up, int offset)
-{
- offset <<= 2;
- return readl(up->port.membase + offset);
-}
-
-static inline void serial_out(struct uart_pxa_port *up, int offset, int value)
-{
- offset <<= 2;
- writel(value, up->port.membase + offset);
-}
-
-static void serial_pxa_enable_ms(struct uart_port *port)
-{
- struct uart_pxa_port *up = (struct uart_pxa_port *)port;
-
- up->ier |= UART_IER_MSI;
- serial_out(up, UART_IER, up->ier);
-}
-
-static void serial_pxa_stop_tx(struct uart_port *port)
-{
- struct uart_pxa_port *up = (struct uart_pxa_port *)port;
-
- if (up->ier & UART_IER_THRI) {
- up->ier &= ~UART_IER_THRI;
- serial_out(up, UART_IER, up->ier);
- }
-}
-
-static void serial_pxa_stop_rx(struct uart_port *port)
-{
- struct uart_pxa_port *up = (struct uart_pxa_port *)port;
-
- up->ier &= ~UART_IER_RLSI;
- up->port.read_status_mask &= ~UART_LSR_DR;
- serial_out(up, UART_IER, up->ier);
-}
-
-static inline void receive_chars(struct uart_pxa_port *up, int *status)
-{
- unsigned int ch, flag;
- int max_count = 256;
-
- do {
- /* work around Errata #20 according to
- * Intel(R) PXA27x Processor Family
- * Specification Update (May 2005)
- *
- * Step 2
- * Disable the Reciever Time Out Interrupt via IER[RTOEI]
- */
- up->ier &= ~UART_IER_RTOIE;
- serial_out(up, UART_IER, up->ier);
-
- ch = serial_in(up, UART_RX);
- flag = TTY_NORMAL;
- up->port.icount.rx++;
-
- if (unlikely(*status & (UART_LSR_BI | UART_LSR_PE |
- UART_LSR_FE | UART_LSR_OE))) {
- /*
- * For statistics only
- */
- if (*status & UART_LSR_BI) {
- *status &= ~(UART_LSR_FE | UART_LSR_PE);
- up->port.icount.brk++;
- /*
- * We do the SysRQ and SAK checking
- * here because otherwise the break
- * may get masked by ignore_status_mask
- * or read_status_mask.
- */
- if (uart_handle_break(&up->port))
- goto ignore_char;
- } else if (*status & UART_LSR_PE)
- up->port.icount.parity++;
- else if (*status & UART_LSR_FE)
- up->port.icount.frame++;
- if (*status & UART_LSR_OE)
- up->port.icount.overrun++;
-
- /*
- * Mask off conditions which should be ignored.
- */
- *status &= up->port.read_status_mask;
-
-#ifdef CONFIG_SERIAL_PXA_CONSOLE
- if (up->port.line == up->port.cons->index) {
- /* Recover the break flag from console xmit */
- *status |= up->lsr_break_flag;
- up->lsr_break_flag = 0;
- }
-#endif
- if (*status & UART_LSR_BI) {
- flag = TTY_BREAK;
- } else if (*status & UART_LSR_PE)
- flag = TTY_PARITY;
- else if (*status & UART_LSR_FE)
- flag = TTY_FRAME;
- }
-
- if (uart_handle_sysrq_char(&up->port, ch))
- goto ignore_char;
-
- uart_insert_char(&up->port, *status, UART_LSR_OE, ch, flag);
-
- ignore_char:
- *status = serial_in(up, UART_LSR);
- } while ((*status & UART_LSR_DR) && (max_count-- > 0));
- tty_flip_buffer_push(&up->port.state->port);
-
- /* work around Errata #20 according to
- * Intel(R) PXA27x Processor Family
- * Specification Update (May 2005)
- *
- * Step 6:
- * No more data in FIFO: Re-enable RTO interrupt via IER[RTOIE]
- */
- up->ier |= UART_IER_RTOIE;
- serial_out(up, UART_IER, up->ier);
-}
-
-static void transmit_chars(struct uart_pxa_port *up)
-{
- struct circ_buf *xmit = &up->port.state->xmit;
- int count;
-
- if (up->port.x_char) {
- serial_out(up, UART_TX, up->port.x_char);
- up->port.icount.tx++;
- up->port.x_char = 0;
- return;
- }
- if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) {
- serial_pxa_stop_tx(&up->port);
- return;
- }
-
- count = up->port.fifosize / 2;
- do {
- serial_out(up, UART_TX, xmit->buf[xmit->tail]);
- xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
- up->port.icount.tx++;
- if (uart_circ_empty(xmit))
- break;
- } while (--count > 0);
-
- if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
- uart_write_wakeup(&up->port);
-
-
- if (uart_circ_empty(xmit))
- serial_pxa_stop_tx(&up->port);
-}
-
-static void serial_pxa_start_tx(struct uart_port *port)
-{
- struct uart_pxa_port *up = (struct uart_pxa_port *)port;
-
- if (!(up->ier & UART_IER_THRI)) {
- up->ier |= UART_IER_THRI;
- serial_out(up, UART_IER, up->ier);
- }
-}
-
-static inline void check_modem_status(struct uart_pxa_port *up)
-{
- int status;
-
- status = serial_in(up, UART_MSR);
-
- if ((status & UART_MSR_ANY_DELTA) == 0)
- return;
-
- if (status & UART_MSR_TERI)
- up->port.icount.rng++;
- if (status & UART_MSR_DDSR)
- up->port.icount.dsr++;
- if (status & UART_MSR_DDCD)
- uart_handle_dcd_change(&up->port, status & UART_MSR_DCD);
- if (status & UART_MSR_DCTS)
- uart_handle_cts_change(&up->port, status & UART_MSR_CTS);
-
- wake_up_interruptible(&up->port.state->port.delta_msr_wait);
-}
-
-/*
- * This handles the interrupt from one port.
- */
-static inline irqreturn_t serial_pxa_irq(int irq, void *dev_id)
-{
- struct uart_pxa_port *up = dev_id;
- unsigned int iir, lsr;
-
- iir = serial_in(up, UART_IIR);
- if (iir & UART_IIR_NO_INT)
- return IRQ_NONE;
- lsr = serial_in(up, UART_LSR);
- if (lsr & UART_LSR_DR)
- receive_chars(up, &lsr);
- check_modem_status(up);
- if (lsr & UART_LSR_THRE)
- transmit_chars(up);
- return IRQ_HANDLED;
-}
-
-static unsigned int serial_pxa_tx_empty(struct uart_port *port)
-{
- struct uart_pxa_port *up = (struct uart_pxa_port *)port;
- unsigned long flags;
- unsigned int ret;
-
- spin_lock_irqsave(&up->port.lock, flags);
- ret = serial_in(up, UART_LSR) & UART_LSR_TEMT ? TIOCSER_TEMT : 0;
- spin_unlock_irqrestore(&up->port.lock, flags);
-
- return ret;
-}
-
-static unsigned int serial_pxa_get_mctrl(struct uart_port *port)
-{
- struct uart_pxa_port *up = (struct uart_pxa_port *)port;
- unsigned char status;
- unsigned int ret;
-
- status = serial_in(up, UART_MSR);
-
- ret = 0;
- if (status & UART_MSR_DCD)
- ret |= TIOCM_CAR;
- if (status & UART_MSR_RI)
- ret |= TIOCM_RNG;
- if (status & UART_MSR_DSR)
- ret |= TIOCM_DSR;
- if (status & UART_MSR_CTS)
- ret |= TIOCM_CTS;
- return ret;
-}
-
-static void serial_pxa_set_mctrl(struct uart_port *port, unsigned int mctrl)
-{
- struct uart_pxa_port *up = (struct uart_pxa_port *)port;
- unsigned char mcr = 0;
-
- if (mctrl & TIOCM_RTS)
- mcr |= UART_MCR_RTS;
- if (mctrl & TIOCM_DTR)
- mcr |= UART_MCR_DTR;
- if (mctrl & TIOCM_OUT1)
- mcr |= UART_MCR_OUT1;
- if (mctrl & TIOCM_OUT2)
- mcr |= UART_MCR_OUT2;
- if (mctrl & TIOCM_LOOP)
- mcr |= UART_MCR_LOOP;
-
- mcr |= up->mcr;
-
- serial_out(up, UART_MCR, mcr);
-}
-
-static void serial_pxa_break_ctl(struct uart_port *port, int break_state)
-{
- struct uart_pxa_port *up = (struct uart_pxa_port *)port;
- unsigned long flags;
-
- spin_lock_irqsave(&up->port.lock, flags);
- if (break_state == -1)
- up->lcr |= UART_LCR_SBC;
- else
- up->lcr &= ~UART_LCR_SBC;
- serial_out(up, UART_LCR, up->lcr);
- spin_unlock_irqrestore(&up->port.lock, flags);
-}
-
-static int serial_pxa_startup(struct uart_port *port)
-{
- struct uart_pxa_port *up = (struct uart_pxa_port *)port;
- unsigned long flags;
- int retval;
-
- if (port->line == 3) /* HWUART */
- up->mcr |= UART_MCR_AFE;
- else
- up->mcr = 0;
-
- up->port.uartclk = clk_get_rate(up->clk);
-
- /*
- * Allocate the IRQ
- */
- retval = request_irq(up->port.irq, serial_pxa_irq, 0, up->name, up);
- if (retval)
- return retval;
-
- /*
- * Clear the FIFO buffers and disable them.
- * (they will be reenabled in set_termios())
- */
- serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO);
- serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO |
- UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
- serial_out(up, UART_FCR, 0);
-
- /*
- * Clear the interrupt registers.
- */
- (void) serial_in(up, UART_LSR);
- (void) serial_in(up, UART_RX);
- (void) serial_in(up, UART_IIR);
- (void) serial_in(up, UART_MSR);
-
- /*
- * Now, initialize the UART
- */
- serial_out(up, UART_LCR, UART_LCR_WLEN8);
-
- spin_lock_irqsave(&up->port.lock, flags);
- up->port.mctrl |= TIOCM_OUT2;
- serial_pxa_set_mctrl(&up->port, up->port.mctrl);
- spin_unlock_irqrestore(&up->port.lock, flags);
-
- /*
- * Finally, enable interrupts. Note: Modem status interrupts
- * are set via set_termios(), which will be occurring imminently
- * anyway, so we don't enable them here.
- */
- up->ier = UART_IER_RLSI | UART_IER_RDI | UART_IER_RTOIE | UART_IER_UUE;
- serial_out(up, UART_IER, up->ier);
-
- /*
- * And clear the interrupt registers again for luck.
- */
- (void) serial_in(up, UART_LSR);
- (void) serial_in(up, UART_RX);
- (void) serial_in(up, UART_IIR);
- (void) serial_in(up, UART_MSR);
-
- return 0;
-}
-
-static void serial_pxa_shutdown(struct uart_port *port)
-{
- struct uart_pxa_port *up = (struct uart_pxa_port *)port;
- unsigned long flags;
-
- free_irq(up->port.irq, up);
-
- /*
- * Disable interrupts from this port
- */
- up->ier = 0;
- serial_out(up, UART_IER, 0);
-
- spin_lock_irqsave(&up->port.lock, flags);
- up->port.mctrl &= ~TIOCM_OUT2;
- serial_pxa_set_mctrl(&up->port, up->port.mctrl);
- spin_unlock_irqrestore(&up->port.lock, flags);
-
- /*
- * Disable break condition and FIFOs
- */
- serial_out(up, UART_LCR, serial_in(up, UART_LCR) & ~UART_LCR_SBC);
- serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO |
- UART_FCR_CLEAR_RCVR |
- UART_FCR_CLEAR_XMIT);
- serial_out(up, UART_FCR, 0);
-}
-
-static void
-serial_pxa_set_termios(struct uart_port *port, struct ktermios *termios,
- struct ktermios *old)
-{
- struct uart_pxa_port *up = (struct uart_pxa_port *)port;
- unsigned char cval, fcr = 0;
- unsigned long flags;
- unsigned int baud, quot;
- unsigned int dll;
-
- switch (termios->c_cflag & CSIZE) {
- case CS5:
- cval = UART_LCR_WLEN5;
- break;
- case CS6:
- cval = UART_LCR_WLEN6;
- break;
- case CS7:
- cval = UART_LCR_WLEN7;
- break;
- default:
- case CS8:
- cval = UART_LCR_WLEN8;
- break;
- }
-
- if (termios->c_cflag & CSTOPB)
- cval |= UART_LCR_STOP;
- if (termios->c_cflag & PARENB)
- cval |= UART_LCR_PARITY;
- if (!(termios->c_cflag & PARODD))
- cval |= UART_LCR_EPAR;
-
- /*
- * Ask the core to calculate the divisor for us.
- */
- baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
- quot = uart_get_divisor(port, baud);
-
- if ((up->port.uartclk / quot) < (2400 * 16))
- fcr = UART_FCR_ENABLE_FIFO | UART_FCR_PXAR1;
- else if ((up->port.uartclk / quot) < (230400 * 16))
- fcr = UART_FCR_ENABLE_FIFO | UART_FCR_PXAR8;
- else
- fcr = UART_FCR_ENABLE_FIFO | UART_FCR_PXAR32;
-
- /*
- * Ok, we're now changing the port state. Do it with
- * interrupts disabled.
- */
- spin_lock_irqsave(&up->port.lock, flags);
-
- /*
- * Ensure the port will be enabled.
- * This is required especially for serial console.
- */
- up->ier |= UART_IER_UUE;
-
- /*
- * Update the per-port timeout.
- */
- uart_update_timeout(port, termios->c_cflag, baud);
-
- up->port.read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR;
- if (termios->c_iflag & INPCK)
- up->port.read_status_mask |= UART_LSR_FE | UART_LSR_PE;
- if (termios->c_iflag & (BRKINT | PARMRK))
- up->port.read_status_mask |= UART_LSR_BI;
-
- /*
- * Characters to ignore
- */
- up->port.ignore_status_mask = 0;
- if (termios->c_iflag & IGNPAR)
- up->port.ignore_status_mask |= UART_LSR_PE | UART_LSR_FE;
- if (termios->c_iflag & IGNBRK) {
- up->port.ignore_status_mask |= UART_LSR_BI;
- /*
- * If we're ignoring parity and break indicators,
- * ignore overruns too (for real raw support).
- */
- if (termios->c_iflag & IGNPAR)
- up->port.ignore_status_mask |= UART_LSR_OE;
- }
-
- /*
- * ignore all characters if CREAD is not set
- */
- if ((termios->c_cflag & CREAD) == 0)
- up->port.ignore_status_mask |= UART_LSR_DR;
-
- /*
- * CTS flow control flag and modem status interrupts
- */
- up->ier &= ~UART_IER_MSI;
- if (UART_ENABLE_MS(&up->port, termios->c_cflag))
- up->ier |= UART_IER_MSI;
-
- serial_out(up, UART_IER, up->ier);
-
- if (termios->c_cflag & CRTSCTS)
- up->mcr |= UART_MCR_AFE;
- else
- up->mcr &= ~UART_MCR_AFE;
-
- serial_out(up, UART_LCR, cval | UART_LCR_DLAB); /* set DLAB */
- serial_out(up, UART_DLL, quot & 0xff); /* LS of divisor */
-
- /*
- * work around Errata #75 according to Intel(R) PXA27x Processor Family
- * Specification Update (Nov 2005)
- */
- dll = serial_in(up, UART_DLL);
- WARN_ON(dll != (quot & 0xff));
-
- serial_out(up, UART_DLM, quot >> 8); /* MS of divisor */
- serial_out(up, UART_LCR, cval); /* reset DLAB */
- up->lcr = cval; /* Save LCR */
- serial_pxa_set_mctrl(&up->port, up->port.mctrl);
- serial_out(up, UART_FCR, fcr);
- spin_unlock_irqrestore(&up->port.lock, flags);
-}
-
-static void
-serial_pxa_pm(struct uart_port *port, unsigned int state,
- unsigned int oldstate)
-{
- struct uart_pxa_port *up = (struct uart_pxa_port *)port;
-
- if (!state)
- clk_prepare_enable(up->clk);
- else
- clk_disable_unprepare(up->clk);
-}
-
-static void serial_pxa_release_port(struct uart_port *port)
-{
-}
-
-static int serial_pxa_request_port(struct uart_port *port)
-{
- return 0;
-}
-
-static void serial_pxa_config_port(struct uart_port *port, int flags)
-{
- struct uart_pxa_port *up = (struct uart_pxa_port *)port;
- up->port.type = PORT_PXA;
-}
-
-static int
-serial_pxa_verify_port(struct uart_port *port, struct serial_struct *ser)
-{
- /* we don't want the core code to modify any port params */
- return -EINVAL;
-}
-
-static const char *
-serial_pxa_type(struct uart_port *port)
-{
- struct uart_pxa_port *up = (struct uart_pxa_port *)port;
- return up->name;
-}
-
-static struct uart_pxa_port *serial_pxa_ports[4];
-static struct uart_driver serial_pxa_reg;
-
-#ifdef CONFIG_SERIAL_PXA_CONSOLE
-
-#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
-
-/*
- * Wait for transmitter & holding register to empty
- */
-static inline void wait_for_xmitr(struct uart_pxa_port *up)
-{
- unsigned int status, tmout = 10000;
-
- /* Wait up to 10ms for the character(s) to be sent. */
- do {
- status = serial_in(up, UART_LSR);
-
- if (status & UART_LSR_BI)
- up->lsr_break_flag = UART_LSR_BI;
-
- if (--tmout == 0)
- break;
- udelay(1);
- } while ((status & BOTH_EMPTY) != BOTH_EMPTY);
-
- /* Wait up to 1s for flow control if necessary */
- if (up->port.flags & UPF_CONS_FLOW) {
- tmout = 1000000;
- while (--tmout &&
- ((serial_in(up, UART_MSR) & UART_MSR_CTS) == 0))
- udelay(1);
- }
-}
-
-static void serial_pxa_console_putchar(struct uart_port *port, int ch)
-{
- struct uart_pxa_port *up = (struct uart_pxa_port *)port;
-
- wait_for_xmitr(up);
- serial_out(up, UART_TX, ch);
-}
-
-/*
- * Print a string to the serial port trying not to disturb
- * any possible real use of the port...
- *
- * The console_lock must be held when we get here.
- */
-static void
-serial_pxa_console_write(struct console *co, const char *s, unsigned int count)
-{
- struct uart_pxa_port *up = serial_pxa_ports[co->index];
- unsigned int ier;
- unsigned long flags;
- int locked = 1;
-
- clk_enable(up->clk);
- local_irq_save(flags);
- if (up->port.sysrq)
- locked = 0;
- else if (oops_in_progress)
- locked = spin_trylock(&up->port.lock);
- else
- spin_lock(&up->port.lock);
-
- /*
- * First save the IER then disable the interrupts
- */
- ier = serial_in(up, UART_IER);
- serial_out(up, UART_IER, UART_IER_UUE);
-
- uart_console_write(&up->port, s, count, serial_pxa_console_putchar);
-
- /*
- * Finally, wait for transmitter to become empty
- * and restore the IER
- */
- wait_for_xmitr(up);
- serial_out(up, UART_IER, ier);
-
- if (locked)
- spin_unlock(&up->port.lock);
- local_irq_restore(flags);
- clk_disable(up->clk);
-
-}
-
-#ifdef CONFIG_CONSOLE_POLL
-/*
- * Console polling routines for writing and reading from the uart while
- * in an interrupt or debug context.
- */
-
-static int serial_pxa_get_poll_char(struct uart_port *port)
-{
- struct uart_pxa_port *up = (struct uart_pxa_port *)port;
- unsigned char lsr = serial_in(up, UART_LSR);
-
- while (!(lsr & UART_LSR_DR))
- lsr = serial_in(up, UART_LSR);
-
- return serial_in(up, UART_RX);
-}
-
-
-static void serial_pxa_put_poll_char(struct uart_port *port,
- unsigned char c)
-{
- unsigned int ier;
- struct uart_pxa_port *up = (struct uart_pxa_port *)port;
-
- /*
- * First save the IER then disable the interrupts
- */
- ier = serial_in(up, UART_IER);
- serial_out(up, UART_IER, UART_IER_UUE);
-
- wait_for_xmitr(up);
- /*
- * Send the character out.
- * If a LF, also do CR...
- */
- serial_out(up, UART_TX, c);
- if (c == 10) {
- wait_for_xmitr(up);
- serial_out(up, UART_TX, 13);
- }
-
- /*
- * Finally, wait for transmitter to become empty
- * and restore the IER
- */
- wait_for_xmitr(up);
- serial_out(up, UART_IER, ier);
-}
-
-#endif /* CONFIG_CONSOLE_POLL */
-
-static int __init
-serial_pxa_console_setup(struct console *co, char *options)
-{
- struct uart_pxa_port *up;
- int baud = 9600;
- int bits = 8;
- int parity = 'n';
- int flow = 'n';
-
- if (co->index == -1 || co->index >= serial_pxa_reg.nr)
- co->index = 0;
- up = serial_pxa_ports[co->index];
- if (!up)
- return -ENODEV;
-
- if (options)
- uart_parse_options(options, &baud, &parity, &bits, &flow);
-
- return uart_set_options(&up->port, co, baud, parity, bits, flow);
-}
-
-static struct console serial_pxa_console = {
- .name = "ttyS",
- .write = serial_pxa_console_write,
- .device = uart_console_device,
- .setup = serial_pxa_console_setup,
- .flags = CON_PRINTBUFFER,
- .index = -1,
- .data = &serial_pxa_reg,
-};
-
-#define PXA_CONSOLE &serial_pxa_console
-#else
-#define PXA_CONSOLE NULL
-#endif
-
-static struct uart_ops serial_pxa_pops = {
- .tx_empty = serial_pxa_tx_empty,
- .set_mctrl = serial_pxa_set_mctrl,
- .get_mctrl = serial_pxa_get_mctrl,
- .stop_tx = serial_pxa_stop_tx,
- .start_tx = serial_pxa_start_tx,
- .stop_rx = serial_pxa_stop_rx,
- .enable_ms = serial_pxa_enable_ms,
- .break_ctl = serial_pxa_break_ctl,
- .startup = serial_pxa_startup,
- .shutdown = serial_pxa_shutdown,
- .set_termios = serial_pxa_set_termios,
- .pm = serial_pxa_pm,
- .type = serial_pxa_type,
- .release_port = serial_pxa_release_port,
- .request_port = serial_pxa_request_port,
- .config_port = serial_pxa_config_port,
- .verify_port = serial_pxa_verify_port,
-#ifdef CONFIG_CONSOLE_POLL
- .poll_get_char = serial_pxa_get_poll_char,
- .poll_put_char = serial_pxa_put_poll_char,
-#endif
-};
-
-static struct uart_driver serial_pxa_reg = {
- .owner = THIS_MODULE,
- .driver_name = "PXA serial",
- .dev_name = "ttyS",
- .major = TTY_MAJOR,
- .minor = 64,
- .nr = 4,
- .cons = PXA_CONSOLE,
-};
-
-#ifdef CONFIG_PM
-static int serial_pxa_suspend(struct device *dev)
-{
- struct uart_pxa_port *sport = dev_get_drvdata(dev);
-
- if (sport)
- uart_suspend_port(&serial_pxa_reg, &sport->port);
-
- return 0;
-}
-
-static int serial_pxa_resume(struct device *dev)
-{
- struct uart_pxa_port *sport = dev_get_drvdata(dev);
-
- if (sport)
- uart_resume_port(&serial_pxa_reg, &sport->port);
-
- return 0;
-}
-
-static const struct dev_pm_ops serial_pxa_pm_ops = {
- .suspend = serial_pxa_suspend,
- .resume = serial_pxa_resume,
-};
-#endif
-
-static struct of_device_id serial_pxa_dt_ids[] = {
- { .compatible = "mrvl,pxa-uart", },
- { .compatible = "mrvl,mmp-uart", },
- {}
-};
-MODULE_DEVICE_TABLE(of, serial_pxa_dt_ids);
-
-static int serial_pxa_probe_dt(struct platform_device *pdev,
- struct uart_pxa_port *sport)
-{
- struct device_node *np = pdev->dev.of_node;
- int ret;
-
- if (!np)
- return 1;
-
- ret = of_alias_get_id(np, "serial");
- if (ret < 0) {
- dev_err(&pdev->dev, "failed to get alias id, errno %d\n", ret);
- return ret;
- }
- sport->port.line = ret;
- return 0;
-}
-
-static int serial_pxa_probe(struct platform_device *dev)
-{
- struct uart_pxa_port *sport;
- struct resource *mmres, *irqres;
- int ret;
-
- mmres = platform_get_resource(dev, IORESOURCE_MEM, 0);
- irqres = platform_get_resource(dev, IORESOURCE_IRQ, 0);
- if (!mmres || !irqres)
- return -ENODEV;
-
- sport = kzalloc(sizeof(struct uart_pxa_port), GFP_KERNEL);
- if (!sport)
- return -ENOMEM;
-
- sport->clk = clk_get(&dev->dev, NULL);
- if (IS_ERR(sport->clk)) {
- ret = PTR_ERR(sport->clk);
- goto err_free;
- }
-
- ret = clk_prepare(sport->clk);
- if (ret) {
- clk_put(sport->clk);
- goto err_free;
- }
-
- sport->port.type = PORT_PXA;
- sport->port.iotype = UPIO_MEM;
- sport->port.mapbase = mmres->start;
- sport->port.irq = irqres->start;
- sport->port.fifosize = 64;
- sport->port.ops = &serial_pxa_pops;
- sport->port.dev = &dev->dev;
- sport->port.flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF;
- sport->port.uartclk = clk_get_rate(sport->clk);
-
- ret = serial_pxa_probe_dt(dev, sport);
- if (ret > 0)
- sport->port.line = dev->id;
- else if (ret < 0)
- goto err_clk;
- snprintf(sport->name, PXA_NAME_LEN - 1, "UART%d", sport->port.line + 1);
-
- sport->port.membase = ioremap(mmres->start, resource_size(mmres));
- if (!sport->port.membase) {
- ret = -ENOMEM;
- goto err_clk;
- }
-
- serial_pxa_ports[sport->port.line] = sport;
-
- uart_add_one_port(&serial_pxa_reg, &sport->port);
- platform_set_drvdata(dev, sport);
-
- return 0;
-
- err_clk:
- clk_unprepare(sport->clk);
- clk_put(sport->clk);
- err_free:
- kfree(sport);
- return ret;
-}
-
-static int serial_pxa_remove(struct platform_device *dev)
-{
- struct uart_pxa_port *sport = platform_get_drvdata(dev);
-
- uart_remove_one_port(&serial_pxa_reg, &sport->port);
-
- clk_unprepare(sport->clk);
- clk_put(sport->clk);
- kfree(sport);
-
- return 0;
-}
-
-static struct platform_driver serial_pxa_driver = {
- .probe = serial_pxa_probe,
- .remove = serial_pxa_remove,
-
- .driver = {
- .name = "pxa2xx-uart",
- .owner = THIS_MODULE,
-#ifdef CONFIG_PM
- .pm = &serial_pxa_pm_ops,
-#endif
- .of_match_table = serial_pxa_dt_ids,
- },
-};
-
-static int __init serial_pxa_init(void)
-{
- int ret;
-
- ret = uart_register_driver(&serial_pxa_reg);
- if (ret != 0)
- return ret;
-
- ret = platform_driver_register(&serial_pxa_driver);
- if (ret != 0)
- uart_unregister_driver(&serial_pxa_reg);
-
- return ret;
-}
-
-static void __exit serial_pxa_exit(void)
-{
- platform_driver_unregister(&serial_pxa_driver);
- uart_unregister_driver(&serial_pxa_reg);
-}
-
-module_init(serial_pxa_init);
-module_exit(serial_pxa_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:pxa2xx-uart");
--
1.8.4.2
^ permalink raw reply related [flat|nested] 148+ messages in thread
* [PATCH v4 02/21] ARM: dts: pxa2xx fix compatible strings
[not found] ` <1397668411-27162-1-git-send-email-ynvich@gmail.com>
2014-04-16 17:13 ` [PATCH v4 01/21] serial: rewrite pxa2xx-uart to use 8250_core Sergei Ianovich
@ 2014-04-16 17:13 ` Sergei Ianovich
2014-04-16 17:13 ` [PATCH v4 03/21] ARM: dts: fix pxa27x-gpio interrupts Sergei Ianovich
2014-04-16 17:13 ` [PATCH v4 06/21] ARM: dts: provide DMA config to pxamci on PXA27x Sergei Ianovich
3 siblings, 0 replies; 148+ messages in thread
From: Sergei Ianovich @ 2014-04-16 17:13 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel
Cc: Mark Rutland, open list:OPEN FIRMWARE AND..., Russell King,
Arnd Bergmann, Pawel Moll, Ian Campbell, Haojian Zhuang,
Daniel Mack, Sergei Ianovich, Rob Herring, Kumar Gala
Signed-off-by: Sergei Ianovich <ynvich@gmail.com>
CC: Daniel Mack <zonque@gmail.com>
CC: Haojian Zhuang <haojian.zhuang@gmail.com>
CC: Arnd Bergmann <arnd@arndb.de>
---
v3..v4
v2..v3
v1..v2
* no changes
arch/arm/boot/dts/pxa2xx.dtsi | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/arch/arm/boot/dts/pxa2xx.dtsi b/arch/arm/boot/dts/pxa2xx.dtsi
index a5e90f0..3419f87 100644
--- a/arch/arm/boot/dts/pxa2xx.dtsi
+++ b/arch/arm/boot/dts/pxa2xx.dtsi
@@ -18,7 +18,6 @@
serial1 = &btuart;
serial2 = &stuart;
serial3 = &hwuart;
- i2c0 = &pwri2c;
i2c1 = &pxai2c1;
};
@@ -113,14 +112,14 @@
};
usb0: ohci@4c000000 {
- compatible = "mrvl,pxa-ohci";
+ compatible = "marvell,pxa-ohci";
reg = <0x4c000000 0x10000>;
interrupts = <3>;
status = "disabled";
};
mmc0: mmc@41100000 {
- compatible = "mrvl,pxa-mmc";
+ compatible = "marvell,pxa-mmc";
reg = <0x41100000 0x1000>;
interrupts = <23>;
status = "disabled";
--
1.8.4.2
^ permalink raw reply related [flat|nested] 148+ messages in thread
* [PATCH v4 03/21] ARM: dts: fix pxa27x-gpio interrupts
[not found] ` <1397668411-27162-1-git-send-email-ynvich@gmail.com>
2014-04-16 17:13 ` [PATCH v4 01/21] serial: rewrite pxa2xx-uart to use 8250_core Sergei Ianovich
2014-04-16 17:13 ` [PATCH v4 02/21] ARM: dts: pxa2xx fix compatible strings Sergei Ianovich
@ 2014-04-16 17:13 ` Sergei Ianovich
2014-04-16 17:13 ` [PATCH v4 06/21] ARM: dts: provide DMA config to pxamci on PXA27x Sergei Ianovich
3 siblings, 0 replies; 148+ messages in thread
From: Sergei Ianovich @ 2014-04-16 17:13 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel
Cc: Sergei Ianovich, Daniel Mack, Haojian Zhuang, Arnd Bergmann,
Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
Russell King, open list:OPEN FIRMWARE AND...
Signed-off-by: Sergei Ianovich <ynvich@gmail.com>
CC: Daniel Mack <zonque@gmail.com>
CC: Haojian Zhuang <haojian.zhuang@gmail.com>
CC: Arnd Bergmann <arnd@arndb.de>
---
v3..v4
v2..v3
v1..v2
* no changes
arch/arm/boot/dts/pxa27x.dtsi | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/arch/arm/boot/dts/pxa27x.dtsi b/arch/arm/boot/dts/pxa27x.dtsi
index a705469..39bed5e 100644
--- a/arch/arm/boot/dts/pxa27x.dtsi
+++ b/arch/arm/boot/dts/pxa27x.dtsi
@@ -34,5 +34,11 @@
reg = <0x40c00010 0x10>;
#pwm-cells = <1>;
};
+
+ gpio: gpio@40e00000 {
+ compatible = "intel,pxa27x-gpio";
+ interrupts = <8>, <9>, <10>;
+ interrupt-names = "gpio0", "gpio1", "gpio_mux";
+ };
};
};
--
1.8.4.2
^ permalink raw reply related [flat|nested] 148+ messages in thread
* [PATCH v4 06/21] ARM: dts: provide DMA config to pxamci on PXA27x
[not found] ` <1397668411-27162-1-git-send-email-ynvich@gmail.com>
` (2 preceding siblings ...)
2014-04-16 17:13 ` [PATCH v4 03/21] ARM: dts: fix pxa27x-gpio interrupts Sergei Ianovich
@ 2014-04-16 17:13 ` Sergei Ianovich
[not found] ` <1397668667-27328-1-git-send-email-ynvich@gmail.com>
3 siblings, 1 reply; 148+ messages in thread
From: Sergei Ianovich @ 2014-04-16 17:13 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel
Cc: Sergei Ianovich, Daniel Mack, Haojian Zhuang, Arnd Bergmann,
Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
Randy Dunlap, Russell King, open list:OPEN FIRMWARE AND...,
open list:DOCUMENTATION
Non-dts implementation supply required DMA channel numbers as
IORESOURCE_DMA. We can also get them from the device tree, if it
is present.
This patch updates device tree with the proper dmaengine-based
"marvell,pdma-1.0" DMA.
There is no actual data handling in this patch, because the existing
driver cannot get DMA channel number from dmaengine API. The patch
in the series will provide temporary workaround by manually parsing
node attributes, until Daniel's series is ready to be merged.
Signed-off-by: Sergei Ianovich <ynvich@gmail.com>
CC: Daniel Mack <zonque@gmail.com>
CC: Haojian Zhuang <haojian.zhuang@gmail.com>
CC: Arnd Bergmann <arnd@arndb.de>
---
v3..v4
* no changes
v2..v3
* split into good (this one) and temporary (PATCH 07/21) parts
v1..v2
* add binding for next-gen dma controller
* use correct dma declararion
* number changed from 5 to 3
Documentation/devicetree/bindings/mmc/pxa-mmc.txt | 5 +++++
arch/arm/boot/dts/pxa27x.dtsi | 14 ++++++++++++++
2 files changed, 19 insertions(+)
diff --git a/Documentation/devicetree/bindings/mmc/pxa-mmc.txt b/Documentation/devicetree/bindings/mmc/pxa-mmc.txt
index b7025de..9f54c69 100644
--- a/Documentation/devicetree/bindings/mmc/pxa-mmc.txt
+++ b/Documentation/devicetree/bindings/mmc/pxa-mmc.txt
@@ -5,6 +5,8 @@ Driver bindings for the PXA MCI (MMC/SDIO) interfaces
Required properties:
- compatible: Should be "marvell,pxa-mmc".
- vmmc-supply: A regulator for VMMC
+- dmas: Should be DMA specifiers for RX and TX
+- dma-names: Should be "rx" and "tx"
Optional properties:
- marvell,detect-delay-ms: sets the detection delay timeout in ms.
@@ -21,5 +23,8 @@ mmc0: mmc@41100000 {
interrupts = <23>;
cd-gpios = <&gpio 23 0>;
wp-gpios = <&gpio 24 0>;
+ dmas = <&dma 21
+ &dma 22>;
+ dma-names = "rx", "tx";
};
diff --git a/arch/arm/boot/dts/pxa27x.dtsi b/arch/arm/boot/dts/pxa27x.dtsi
index 39bed5e..0150531 100644
--- a/arch/arm/boot/dts/pxa27x.dtsi
+++ b/arch/arm/boot/dts/pxa27x.dtsi
@@ -35,10 +35,24 @@
#pwm-cells = <1>;
};
+ dma: dma-controller@40000000 {
+ compatible = "marvell,pdma-1.0";
+ reg = <0x40000000 0x10000>;
+ interrupts = <25>;
+ #dma-cells = <1>;
+ dma-channels = <32>;
+ };
+
gpio: gpio@40e00000 {
compatible = "intel,pxa27x-gpio";
interrupts = <8>, <9>, <10>;
interrupt-names = "gpio0", "gpio1", "gpio_mux";
};
+
+ mmc@41100000 {
+ dmas = <&dma 21
+ &dma 22>;
+ dma-names = "rx", "tx";
+ };
};
};
--
1.8.4.2
^ permalink raw reply related [flat|nested] 148+ messages in thread
* [PATCH v4 08/21] ARM: pxa27x: device tree support ICP DAS LP-8x4x
[not found] ` <1397668667-27328-1-git-send-email-ynvich@gmail.com>
@ 2014-04-16 17:17 ` Sergei Ianovich
2014-04-17 10:54 ` Daniel Mack
2014-04-16 17:17 ` [PATCH v4 09/21] rtc: support DS1302 RTC on " Sergei Ianovich
` (10 subsequent siblings)
11 siblings, 1 reply; 148+ messages in thread
From: Sergei Ianovich @ 2014-04-16 17:17 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel
Cc: Sergei Ianovich, Daniel Mack, Arnd Bergmann, Rob Herring,
Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala, Randy Dunlap,
Russell King, Eric Miao, Haojian Zhuang, Thierry Reding,
Florian Vaussard, Jonathan Cameron, Shawn Guo, Andrew Lunn,
Silvio F, Heikki Krogerus, open list:OPEN FIRMWARE AND...,
open list:DOCUMENTATION
ICP DAS calls LP-8x4x 'programmable automation controller'. It is
an industrial computer based on PXA270 SoC. They ship it with a 2.6.19
kernel and proprietary kernel module and userspace library to access
its industrial IO.
This patch allows to boot the device with a modern kernel with device
tree. It adds support for:
* MMC card interface on PXA270
* USB 1.1 port on PXA270
* 2 NOR flash devices
* 2 onboard ethernet Davicom DM9000 devices
* 3 serial UART ports on PXA270
* front panel red LED
* 64bit 1-wire system ID chip
* 16 kiB EEPROM (reading)
Support for these devices will be added in separate patches, since
they are not currently supported by the kernel:
* DS1302 RTC
* 512kiB SRAM
* FPGA irq chip
* 3 built-in 16550A serial UART ports
* industrial IO parallel bus
* 10 position rotary switch
* 8 pin DIP switch
* 16 kiB EEPROM (writing)
* serial interface for digital and analog industrial IO modules on
parallel bus (all I-87... modules)
* digital and analog industrial IO modules for parallel bus:
** I-8024 4 port analog output
** I-8041 32 port digital output
** I-8042 16 port digital output/16 port digital input
Not supported for now:
* VGA interface on PXA270 for lack of dts binding
* the rest of parallel bus (I-8...) modules for lack of hardware
* GPIO reset for lack of relevance (watchdog reset is working)
Newer devices have twice as much flash and a different partition
structure otherwise being the same. When each device is provided
with a correct device tree, all of them can be booted using the
same kernel.
Signed-off-by: Sergei Ianovich <ynvich@gmail.com>
CC: Daniel Mack <zonque@gmail.com>
CC: Arnd Bergmann <arnd@arndb.de>
---
v3..v4
* move all declarations to one commit so the first DTB file can be
used to boot any later kernel as suggested by Arnd Bergmann,
Heikki Krogerus and Brian Norris
* support new flavor of device (i105 suffix)
v2..v3
* added extbus which maps synchronous, static, and variable-latency
I/O (VLIO) interfaces of PXA27x SoC as suggested by Arnd Bergmann
* map is placed into platform include
* configured existing kernel drivers to support:
- front panel LED using gpio-leds
- 64bit 1-wire system ID chip using w1-gpio
- 16 kiB EEPROM using at24 over i2c-gpio
* number change (06/16 -> 08/21)
v1..v2
* drop left-over extern declaration
* use of_have_populated_dt() instead of a static variable
* drop wildcards in compatible
* drop machine-special machine description
* number changed from 9 to 6 (dropped patches)
.../devicetree/bindings/vendor-prefixes.txt | 1 +
arch/arm/boot/dts/Makefile | 2 +
arch/arm/boot/dts/pxa27x-lp8x4x-i105.dts | 43 ++++
arch/arm/boot/dts/pxa27x-lp8x4x.dts | 228 +++++++++++++++++++++
arch/arm/boot/dts/pxa27x.dtsi | 17 ++
arch/arm/configs/lp8x4x_defconfig | 168 +++++++++++++++
arch/arm/mach-pxa/Kconfig | 15 ++
arch/arm/mach-pxa/Makefile | 1 +
arch/arm/mach-pxa/pxa27x-dt.c | 64 ++++++
9 files changed, 539 insertions(+)
create mode 100644 arch/arm/boot/dts/pxa27x-lp8x4x-i105.dts
create mode 100644 arch/arm/boot/dts/pxa27x-lp8x4x.dts
create mode 100644 arch/arm/configs/lp8x4x_defconfig
create mode 100644 arch/arm/mach-pxa/pxa27x-dt.c
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index 0f01c9b..1155c6c 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -54,6 +54,7 @@ hisilicon Hisilicon Limited.
honeywell Honeywell
hp Hewlett Packard
ibm International Business Machines (IBM)
+icpdas ICP DAS CO., LTD.
idt Integrated Device Technologies, Inc.
img Imagination Technologies Ltd.
intel Intel Corporation
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 35c146f..28175d7 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -408,6 +408,8 @@ dtb-$(CONFIG_MACH_DOVE) += dove-cm-a510.dtb \
dove-d2plug.dtb \
dove-d3plug.dtb \
dove-dove-db.dtb
+dtb-$(CONFIG_MACH_PXA27X_DT) += pxa27x-lp8x4x.dtb \
+ pxa27x-lp8x4x-i105.dtb
targets += dtbs dtbs_install
targets += $(dtb-y)
diff --git a/arch/arm/boot/dts/pxa27x-lp8x4x-i105.dts b/arch/arm/boot/dts/pxa27x-lp8x4x-i105.dts
new file mode 100644
index 0000000..8ddc9f5
--- /dev/null
+++ b/arch/arm/boot/dts/pxa27x-lp8x4x-i105.dts
@@ -0,0 +1,43 @@
+/* Device tree for ICP DAS LP-8x4x i105 flavor */
+
+#include "pxa27x-lp8x4x.dts"
+
+/ {
+ extbus {
+ flash@0 {
+ compatible = "cfi-flash";
+ reg = <0 0 0x04000000>;
+ bank-width = <4>;
+ device-width = <2>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ fs@0 {
+ label = "u-boot";
+ reg = <0 0x40000>;
+ };
+ fs@40000 {
+ label = "settings";
+ reg = <0x40000 0x40000>;
+ };
+ fs@80000 {
+ label = "device_tree";
+ reg = <0x80000 0x40000>;
+ };
+ fs@c0000 {
+ label = "kernel";
+ reg = <0xc0000 0x2c0000>;
+ };
+ fs@300000 {
+ label = "root_fs";
+ reg = <0x380000 0x3c80000>;
+ };
+ };
+
+ flash@1 {
+ compatible = "cfi-flash";
+ reg = <1 0x0 0x02000000>;
+ bank-width = <2>;
+ device-width = <1>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/pxa27x-lp8x4x.dts b/arch/arm/boot/dts/pxa27x-lp8x4x.dts
new file mode 100644
index 0000000..38a3e46
--- /dev/null
+++ b/arch/arm/boot/dts/pxa27x-lp8x4x.dts
@@ -0,0 +1,228 @@
+/* Device tree for ICP DAS LP-8x4x */
+/dts-v1/;
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include "pxa27x.dtsi"
+
+/ {
+ model = "ICP DAS LP-8x4x programmable automation controller";
+ compatible = "marvell,pxa270";
+
+ aliases {
+ ethernet0 = ð0;
+ ethernet1 = ð1;
+ };
+
+ memory {
+ reg = <0xa0000000 0x08000000>;
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ vmmc: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "vmmc";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ };
+
+ pxabus {
+ pxairq: interrupt-controller@40d00000 {
+ marvell,intc-priority;
+ marvell,intc-nr-irqs = <34>;
+ };
+
+ uart@40100000 {
+ status = "okay";
+ };
+
+ uart@40200000 {
+ status = "okay";
+ };
+
+ uart@40700000 {
+ status = "okay";
+ };
+
+ mmc@41100000 {
+ status = "okay";
+ vmmc-supply = <&vmmc>;
+ };
+
+ ohci@4c000000 {
+ status = "okay";
+ marvell,port-mode = <3>;
+ marvell,oc-mode-perport;
+ marvell,enable-port1;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ status {
+ gpios = <&gpio 84 1>;
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
+ i2c: i2c-gpio {
+ compatible = "i2c-gpio";
+ gpios = <&gpio 22 0 /* sda */
+ &gpio 12 0 /* scl */>;
+ i2c-gpio,delay-us = <1>;
+ i2c-gpio,timeout-ms = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ eeprom@50 {
+ compatible = "atmel,24c128";
+ reg = <0x50>;
+ pagesize = <64>;
+ };
+ };
+
+ w1: w1-gpio {
+ compatible = "w1-gpio";
+ gpios = <&gpio 83 0>;
+ };
+ };
+
+ extbus {
+ flash@0 {
+ compatible = "cfi-flash";
+ reg = <0 0 0x02000000>;
+ bank-width = <4>;
+ device-width = <2>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ fs@0 {
+ label = "u-boot";
+ reg = <0 0x40000>;
+ };
+ fs@40000 {
+ label = "settings";
+ reg = <0x40000 0x40000>;
+ };
+ fs@80000 {
+ label = "device_tree";
+ reg = <0x80000 0x40000>;
+ };
+ fs@c0000 {
+ label = "kernel";
+ reg = <0xc0000 0x240000>;
+ };
+ fs@300000 {
+ label = "root_fs";
+ reg = <0x300000 0x1d00000>;
+ };
+ };
+
+ flash@1 {
+ compatible = "cfi-flash";
+ reg = <1 0x0 0x01000000>;
+ bank-width = <2>;
+ device-width = <1>;
+ };
+
+ netio@3 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 3 0 0x02000000>;
+ interrupt-parent = <&gpio>;
+
+ eth0: eth@0 {
+ compatible = "davicom,dm9000";
+ reg = <0x0 0x2
+ 0x4000 0x2>;
+ interrupts = <9 IRQ_TYPE_EDGE_RISING>;
+ status = "okay";
+ };
+
+ eth1: eth@1000000 {
+ compatible = "davicom,dm9000";
+ reg = <0x1000000 0x2
+ 0x1004000 0x2>;
+ interrupts = <82 IRQ_TYPE_EDGE_RISING>;
+ status = "okay";
+ };
+ };
+
+ fpga@5 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 5 0x3000000 0x10000>;
+ interrupt-parent = <&fpgairq>;
+
+ rtc@901c {
+ compatible = "dallas,rtc-ds1302";
+ reg = <0x901c 0x1>;
+ status = "okay";
+ };
+
+ sram@a000 {
+ compatible = "icpdas,sram-lp8x4x";
+ reg = <0xa000 0x1000
+ 0x901e 0x1>;
+ };
+
+ fpgairq: irq@9006 {
+ compatible = "icpdas,irq-lp8x4x";
+ reg = <0x9006 0x16>;
+ interrupt-parent = <&gpio>;
+ interrupts = <3 IRQ_TYPE_EDGE_FALLING>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ status = "okay";
+ };
+
+ uart@9050 {
+ compatible = "icpdas,uart-lp8x4x";
+ reg = <0x9050 0x10
+ 0x9030 0x02>;
+ interrupts = <13>;
+ status = "okay";
+ };
+
+ uart@9060 {
+ compatible = "icpdas,uart-lp8x4x";
+ reg = <0x9060 0x10
+ 0x9032 0x02>;
+ interrupts = <14>;
+ status = "okay";
+ };
+
+ uart@9070 {
+ compatible = "icpdas,uart-lp8x4x";
+ reg = <0x9070 0x10
+ 0x9034 0x02>;
+ interrupts = <15>;
+ status = "okay";
+ };
+
+ backplane {
+ compatible = "icpdas,backplane-lp8x4x";
+ reg = <0x0 0x2
+ 0x1000 0x10
+ 0x2000 0x10
+ 0x3000 0x10
+ 0x4000 0x10
+ 0x5000 0x10
+ 0x6000 0x10
+ 0x7000 0x10
+ 0x8000 0x10
+ 0x9002 0x2
+ 0x9004 0x2
+ 0x9046 0x2>;
+ eeprom-gpios = <&gpio 4 0>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/pxa27x.dtsi b/arch/arm/boot/dts/pxa27x.dtsi
index 0150531..1e1c98c 100644
--- a/arch/arm/boot/dts/pxa27x.dtsi
+++ b/arch/arm/boot/dts/pxa27x.dtsi
@@ -55,4 +55,21 @@
dma-names = "rx", "tx";
};
};
+
+ extbus {
+ /*
+ * PXA27x synchrous, static and
+ * variable-latency IO interfaces
+ */
+ compatible = "simple-bus";
+
+ #address-cells = <2>; /* first cell is nCS, second is address */
+ #size-cells = <1>;
+ ranges = <0 0 0 0x04000000
+ 1 0 0x04000000 0x04000000
+ 2 0 0x08000000 0x04000000
+ 3 0 0x0c000000 0x04000000
+ 4 0 0x10000000 0x04000000
+ 5 0 0x14000000 0x04000000>;
+ };
};
diff --git a/arch/arm/configs/lp8x4x_defconfig b/arch/arm/configs/lp8x4x_defconfig
new file mode 100644
index 0000000..9f1efb6
--- /dev/null
+++ b/arch/arm/configs/lp8x4x_defconfig
@@ -0,0 +1,168 @@
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_RCU_BOOST=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+# CONFIG_UID16 is not set
+# CONFIG_SHMEM is not set
+CONFIG_EMBEDDED=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLOB=y
+CONFIG_JUMP_LABEL=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+# CONFIG_LBDAF is not set
+CONFIG_BLK_CMDLINE_PARSER=y
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+CONFIG_ARCH_PXA=y
+CONFIG_MACH_PXA27X_DT=y
+# CONFIG_ARM_THUMB is not set
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+# CONFIG_COMPACTION is not set
+# CONFIG_CROSS_MEMORY_ATTACH is not set
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="init=/sbin/init root=/dev/mmcblk0p1 rw rootfstype=ext4 console=ttyS0,115200 mem=128M rootwait"
+# CONFIG_SUSPEND is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_BRIDGE=m
+CONFIG_BRIDGE_VLAN_FILTERING=y
+CONFIG_VLAN_8021Q=m
+CONFIG_VLAN_8021Q_GVRP=y
+CONFIG_VLAN_8021Q_MVRP=y
+# CONFIG_WIRELESS is not set
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_FW_LOADER is not set
+CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_GEOMETRY=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_PHYSMAP_OF=y
+CONFIG_PROC_DEVICETREE=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_LOOP_MIN_COUNT=2
+CONFIG_EEPROM_AT24=m
+CONFIG_SCSI=y
+# CONFIG_SCSI_PROC_FS is not set
+CONFIG_BLK_DEV_SD=y
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_NETDEVICES=y
+CONFIG_BONDING=m
+CONFIG_MACVLAN=m
+CONFIG_MACVTAP=m
+CONFIG_TUN=m
+# CONFIG_NET_VENDOR_ARC is not set
+# CONFIG_NET_CADENCE is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CIRRUS is not set
+CONFIG_DM9000=y
+CONFIG_DM9000_FORCE_SIMPLE_PHY_POLL=y
+# CONFIG_NET_VENDOR_FARADAY 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_SEEQ is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_VIA is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
+CONFIG_PPP=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPPOE=m
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+# CONFIG_WLAN is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=800
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=600
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_8250=y
+# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=40
+CONFIG_SERIAL_8250_RUNTIME_UARTS=40
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_MANY_PORTS=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_PXA=y
+CONFIG_HW_RANDOM=y
+CONFIG_I2C=m
+# CONFIG_I2C_COMPAT is not set
+CONFIG_I2C_GPIO=m
+CONFIG_W1=m
+CONFIG_W1_MASTER_GPIO=m
+CONFIG_W1_SLAVE_SMEM=m
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_SA1100_WATCHDOG=m
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_FB=y
+CONFIG_FB_PXA=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_LOGO=y
+CONFIG_USB=m
+CONFIG_USB_OHCI_HCD=m
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+CONFIG_USB_STORAGE=m
+CONFIG_USB_SERIAL=m
+CONFIG_MMC=y
+CONFIG_MMC_PXA=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_PXA=m
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_EXT2_FS=m
+CONFIG_EXT3_FS=y
+CONFIG_EXT4_FS=y
+CONFIG_REISERFS_FS=m
+CONFIG_ISO9660_FS=m
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_NTFS_FS=m
+CONFIG_NTFS_RW=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+CONFIG_CIFS=m
+CONFIG_CIFS_STATS=y
+CONFIG_CODA_FS=m
+CONFIG_NLS_DEFAULT="cp855"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_855=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_UTF8=y
+CONFIG_PRINTK_TIME=y
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
index e6690a4..fc2e634 100644
--- a/arch/arm/mach-pxa/Kconfig
+++ b/arch/arm/mach-pxa/Kconfig
@@ -4,6 +4,21 @@ menu "Intel PXA2xx/PXA3xx Implementations"
comment "Intel/Marvell Dev Platforms (sorted by hardware release time)"
+config MACH_PXA27X_DT
+ bool "Support PXA27x platforms from device tree"
+ select PXA27x
+ select USE_OF
+ help
+ Include support for Marvell PXA27x based platforms using
+ the device tree.
+
+ While MACH_PXA27X_DT when enabled should boot any PXA27x
+ compatible machine, it still makes sense to select specific
+ machines. Those options will select required features and
+ provide per-machine errata workarounds.
+
+ If unsure, say Y.
+
config MACH_PXA3XX_DT
bool "Support PXA3xx platforms from device tree"
select CPU_PXA300
diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile
index 648867a..adaa72a 100644
--- a/arch/arm/mach-pxa/Makefile
+++ b/arch/arm/mach-pxa/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_CPU_PXA930) += pxa930.o
# NOTE: keep the order of boards in accordance to their order in Kconfig
# Device Tree support
+obj-$(CONFIG_MACH_PXA27X_DT) += pxa27x-dt.o
obj-$(CONFIG_MACH_PXA3XX_DT) += pxa-dt.o
# Intel/Marvell Dev Platforms
diff --git a/arch/arm/mach-pxa/pxa27x-dt.c b/arch/arm/mach-pxa/pxa27x-dt.c
new file mode 100644
index 0000000..865cf46
--- /dev/null
+++ b/arch/arm/mach-pxa/pxa27x-dt.c
@@ -0,0 +1,64 @@
+/*
+ * linux/arch/arm/mach-pxa/pxa27x-dt.c
+ *
+ * Copyright (C) 2013 Sergei Ianovich
+ *
+ * based mostly on linux/arch/arm/mach-pxa/pxa-dt.c by Daniel Mack
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <asm/io.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <mach/irqs.h>
+#include <mach/pxa27x.h>
+
+#include "generic.h"
+
+#ifdef CONFIG_PXA27x
+static const struct of_dev_auxdata pxa27x_auxdata_lookup[] __initconst = {
+ OF_DEV_AUXDATA("mrvl,pxa-uart", 0x40100000, "pxa2xx-uart.0", NULL),
+ OF_DEV_AUXDATA("mrvl,pxa-uart", 0x40200000, "pxa2xx-uart.1", NULL),
+ OF_DEV_AUXDATA("mrvl,pxa-uart", 0x40700000, "pxa2xx-uart.2", NULL),
+ OF_DEV_AUXDATA("mrvl,pxa-uart", 0x41600000, "pxa2xx-uart.3", NULL),
+ OF_DEV_AUXDATA("marvell,pxa-mmc", 0x41100000, "pxa2xx-mci.0", NULL),
+ OF_DEV_AUXDATA("intel,pxa27x-gpio", 0x40e00000, "pxa27x-gpio", NULL),
+ OF_DEV_AUXDATA("marvell,pxa-ohci", 0x4c000000, "pxa27x-ohci", NULL),
+ OF_DEV_AUXDATA("mrvl,pxa-i2c", 0x40301680, "pxa2xx-i2c.0", NULL),
+ {}
+};
+
+static void __init pxa27x_dt_init(void)
+{
+ of_platform_populate(NULL, of_default_bus_match_table,
+ pxa27x_auxdata_lookup, NULL);
+}
+
+static const char * const pxa27x_dt_board_compat[] __initconst = {
+ "marvell,pxa270",
+ "marvell,pxa271",
+ "marvell,pxa272",
+ NULL,
+};
+
+#endif
+
+#ifdef CONFIG_PXA27x
+DT_MACHINE_START(PXA27X_DT, "Marvell PXA27x (Device Tree Support)")
+ .map_io = pxa27x_map_io,
+ .init_irq = pxa27x_dt_init_irq,
+ .handle_irq = pxa27x_handle_irq,
+ .init_time = pxa_timer_init,
+ .restart = pxa_restart,
+ .init_machine = pxa27x_dt_init,
+ .dt_compat = pxa27x_dt_board_compat,
+MACHINE_END
+
+#endif
--
1.8.4.2
^ permalink raw reply related [flat|nested] 148+ messages in thread
* [PATCH v4 09/21] rtc: support DS1302 RTC on ICP DAS LP-8x4x
[not found] ` <1397668667-27328-1-git-send-email-ynvich@gmail.com>
2014-04-16 17:17 ` [PATCH v4 08/21] ARM: pxa27x: device tree support ICP DAS LP-8x4x Sergei Ianovich
@ 2014-04-16 17:17 ` Sergei Ianovich
2015-06-08 12:07 ` [v4,09/21] " Alexandre Belloni
2014-04-16 17:17 ` [PATCH v4 10/21] mtd: support BB SRAM " Sergei Ianovich
` (9 subsequent siblings)
11 siblings, 1 reply; 148+ messages in thread
From: Sergei Ianovich @ 2014-04-16 17:17 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel
Cc: Sergei Ianovich, Rob Herring, Pawel Moll, Mark Rutland,
Ian Campbell, Kumar Gala, Randy Dunlap, Russell King,
Alessandro Zummo, Grant Likely, Heikki Krogerus,
open list:OPEN FIRMWARE AND..., open list:DOCUMENTATION,
rtc-linux
Signed-off-by: Sergei Ianovich <ynvich@gmail.com>
---
v3..v4
* move DTS bindings to a different patch (8/21)
v2..v3
* use usleep_range instead of custom nsleep
* number change (07/16 -> 09/21)
v0..v2
* use device tree
* use devm helpers where possible
.../devicetree/bindings/rtc/rtc-ds1302.txt | 14 +++
arch/arm/configs/lp8x4x_defconfig | 1 +
drivers/rtc/Kconfig | 2 +-
drivers/rtc/rtc-ds1302.c | 100 ++++++++++++++++++++-
4 files changed, 114 insertions(+), 3 deletions(-)
create mode 100644 Documentation/devicetree/bindings/rtc/rtc-ds1302.txt
diff --git a/Documentation/devicetree/bindings/rtc/rtc-ds1302.txt b/Documentation/devicetree/bindings/rtc/rtc-ds1302.txt
new file mode 100644
index 0000000..810613b
--- /dev/null
+++ b/Documentation/devicetree/bindings/rtc/rtc-ds1302.txt
@@ -0,0 +1,14 @@
+* Dallas Semiconductor DS-1302 RTC
+
+Simple device which could be used to store date/time between reboots.
+
+Required properties:
+- compatible : Should be "dallas,rtc-ds1302"
+- reg : Should be address and size of IO memory region
+
+Examples:
+
+rtc@40900000 {
+ compatible = "dallas,rtc-ds1302";
+ reg = <0x1700901c 0x1>;
+};
diff --git a/arch/arm/configs/lp8x4x_defconfig b/arch/arm/configs/lp8x4x_defconfig
index 9f1efb6..d60e37a 100644
--- a/arch/arm/configs/lp8x4x_defconfig
+++ b/arch/arm/configs/lp8x4x_defconfig
@@ -141,6 +141,7 @@ CONFIG_LEDS_GPIO=y
CONFIG_LEDS_TRIGGERS=y
CONFIG_LEDS_TRIGGER_HEARTBEAT=y
CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_DS1302=y
CONFIG_RTC_DRV_PXA=m
# CONFIG_IOMMU_SUPPORT is not set
CONFIG_EXT2_FS=m
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 2e565f8..80aaaa1 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -710,7 +710,7 @@ config RTC_DRV_DS1286
config RTC_DRV_DS1302
tristate "Dallas DS1302"
- depends on SH_SECUREEDGE5410
+ depends on SH_SECUREEDGE5410 || (ARCH_PXA && HIGH_RES_TIMERS)
help
If you say yes here you get support for the Dallas DS1302 RTC chips.
diff --git a/drivers/rtc/rtc-ds1302.c b/drivers/rtc/rtc-ds1302.c
index 07e8d79..3c49023 100644
--- a/drivers/rtc/rtc-ds1302.c
+++ b/drivers/rtc/rtc-ds1302.c
@@ -50,7 +50,7 @@
#define ds1302_set_tx()
#define ds1302_set_rx()
-static inline int ds1302_hw_init(void)
+static inline int ds1302_hw_init(struct platform_device *pdev)
{
return 0;
}
@@ -86,6 +86,101 @@ static inline int ds1302_rxbit(void)
return !!(get_dp() & RTC_IODATA);
}
+#elif defined(CONFIG_ARCH_PXA) && defined(CONFIG_HIGH_RES_TIMERS)
+
+#include <linux/delay.h>
+#include <linux/of.h>
+
+#define RTC_CE 0x01
+#define RTC_CLK 0x02
+#define RTC_nWE 0x04
+#define RTC_IODATA 0x08
+
+static unsigned long ds1302_state;
+
+static void *mem;
+
+static inline int ds1302_hw_init(struct platform_device *pdev)
+{
+ struct resource *r;
+
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!r)
+ return -ENODEV;
+
+ mem = devm_ioremap_resource(&pdev->dev, r);
+ if (!mem)
+ return -EFAULT;
+
+ return 0;
+}
+
+static inline void ds1302_reset(void)
+{
+ ds1302_state = 0;
+ iowrite8(ds1302_state, mem);
+ usleep_range(4, 5);
+}
+
+static inline void ds1302_clock(void)
+{
+ usleep_range(1, 2);
+ ds1302_state |= RTC_CLK;
+ iowrite8(ds1302_state, mem);
+ usleep_range(1, 2);
+ ds1302_state &= ~RTC_CLK;
+ iowrite8(ds1302_state, mem);
+}
+
+static inline void ds1302_start(void)
+{
+ ds1302_state &= ~RTC_CLK;
+ ds1302_state |= RTC_CE;
+ iowrite8(ds1302_state, mem);
+ usleep_range(3, 4);
+}
+
+static inline void ds1302_stop(void)
+{
+ ds1302_state &= ~RTC_CE;
+ iowrite8(ds1302_state, mem);
+}
+
+static inline void ds1302_set_tx(void)
+{
+ ds1302_state &= ~RTC_nWE;
+ iowrite8(ds1302_state, mem);
+}
+
+static inline void ds1302_set_rx(void)
+{
+ ds1302_state |= RTC_nWE;
+ iowrite8(ds1302_state, mem);
+}
+
+static inline void ds1302_txbit(int bit)
+{
+ if (bit)
+ ds1302_state |= RTC_IODATA;
+ else
+ ds1302_state &= ~RTC_IODATA;
+ iowrite8(ds1302_state, mem);
+}
+
+static inline int ds1302_rxbit(void)
+{
+ return ioread8(mem) & 0x1;
+}
+
+#ifdef CONFIG_OF
+static const struct of_device_id ds1302_dt_ids[] = {
+ { .compatible = "dallas,rtc-ds1302" },
+ { }
+};
+
+MODULE_DEVICE_TABLE(of, ds1302_dt_ids);
+#endif
+
#else
#error "Add support for your platform"
#endif
@@ -216,7 +311,7 @@ static int __init ds1302_rtc_probe(struct platform_device *pdev)
{
struct rtc_device *rtc;
- if (ds1302_hw_init()) {
+ if (ds1302_hw_init(pdev)) {
dev_err(&pdev->dev, "Failed to init communication channel");
return -EINVAL;
}
@@ -245,6 +340,7 @@ static struct platform_driver ds1302_platform_driver = {
.driver = {
.name = DRV_NAME,
.owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(ds1302_dt_ids),
},
};
--
1.8.4.2
^ permalink raw reply related [flat|nested] 148+ messages in thread
* [PATCH v4 10/21] mtd: support BB SRAM on ICP DAS LP-8x4x
[not found] ` <1397668667-27328-1-git-send-email-ynvich@gmail.com>
2014-04-16 17:17 ` [PATCH v4 08/21] ARM: pxa27x: device tree support ICP DAS LP-8x4x Sergei Ianovich
2014-04-16 17:17 ` [PATCH v4 09/21] rtc: support DS1302 RTC on " Sergei Ianovich
@ 2014-04-16 17:17 ` Sergei Ianovich
2014-04-30 17:21 ` Brian Norris
[not found] ` <1397668667-27328-4-git-send-email-ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2014-04-16 17:17 ` [PATCH v4 11/21] ARM: pxa: support ICP DAS LP-8x4x FPGA irq Sergei Ianovich
` (8 subsequent siblings)
11 siblings, 2 replies; 148+ messages in thread
From: Sergei Ianovich @ 2014-04-16 17:17 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel
Cc: Sergei Ianovich, Rob Herring, Pawel Moll, Mark Rutland,
Ian Campbell, Kumar Gala, Randy Dunlap, Russell King,
David Woodhouse, Brian Norris, Grant Likely, Heikki Krogerus,
Lee Jones, Artem Bityutskiy, Robert Jarzmik, Michael Opdenacker,
open list:OPEN FIRMWARE AND..., open list:DOCUMENTATION,
open list:MEMORY TECHNOLOGY...
This provides an MTD device driver for 512kB of battery backed up SRAM
on ICPDAS LP-8X4X programmable automation controllers.
SRAM chip is connected via FPGA and is not accessible without a driver,
unlike flash memory which is wired to CPU MMU.
This SRAM becomes an excellent persisent storage of volatile process
data like counter values and sensor statuses. Storing those data in
flash or mmc card is not a viable solution.
Signed-off-by: Sergei Ianovich <ynvich@gmail.com>
Reviewed-by: Brian Norris <computersforpeace@gmail.com>
---
v3..v4 for Brian Norris 'Reviewed-by'
* add doc file for DT binding
* move DTS binding to a different patch (8/21)
* drop unused include directive
* drop safely unused callback
* drop non-default partion probe types
* drop duplicate error checks
* drop duplicate error reporting
* fixed error message on MTD registeration
* fixed module removal routine
v2..v3
* no changes (except number 08/16 -> 10/21)
v0..v2
* use device tree
* use devm helpers where possible
.../devicetree/bindings/mtd/sram-lp8x4x.txt | 22 +++
arch/arm/configs/lp8x4x_defconfig | 1 +
drivers/mtd/devices/Kconfig | 14 ++
drivers/mtd/devices/Makefile | 1 +
drivers/mtd/devices/sram_lp8x4x.c | 204 +++++++++++++++++++++
5 files changed, 242 insertions(+)
create mode 100644 Documentation/devicetree/bindings/mtd/sram-lp8x4x.txt
create mode 100644 drivers/mtd/devices/sram_lp8x4x.c
diff --git a/Documentation/devicetree/bindings/mtd/sram-lp8x4x.txt b/Documentation/devicetree/bindings/mtd/sram-lp8x4x.txt
new file mode 100644
index 0000000..8b1e864
--- /dev/null
+++ b/Documentation/devicetree/bindings/mtd/sram-lp8x4x.txt
@@ -0,0 +1,22 @@
+512kB battery backed up SRAM on LP-8x4x industrial computers
+
+Required properties:
+- compatible : should be "icpdas,sram-lp8x4x"
+
+- reg: physical base addresses and region lengths of
+ * IO memory range
+ * SRAM page selector
+
+- eeprom-gpios : should point to active-low write enable GPIO
+
+SRAM chip is connected via FPGA and is not accessible without a driver,
+unlike flash memory which is wired to CPU MMU. Driver is essentially
+an address translation routine.
+
+Example:
+
+ sram@a000 {
+ compatible = "icpdas,sram-lp8x4x";
+ reg = <0xa000 0x1000
+ 0x901e 0x1>;
+ };
diff --git a/arch/arm/configs/lp8x4x_defconfig b/arch/arm/configs/lp8x4x_defconfig
index d60e37a..17a4e6f 100644
--- a/arch/arm/configs/lp8x4x_defconfig
+++ b/arch/arm/configs/lp8x4x_defconfig
@@ -57,6 +57,7 @@ CONFIG_MTD_CFI_ADV_OPTIONS=y
CONFIG_MTD_CFI_GEOMETRY=y
CONFIG_MTD_CFI_INTELEXT=y
CONFIG_MTD_PHYSMAP_OF=y
+CONFIG_MTD_SRAM_LP8X4X=y
CONFIG_PROC_DEVICETREE=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_LOOP_MIN_COUNT=2
diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig
index 1210bc2..fc8552b 100644
--- a/drivers/mtd/devices/Kconfig
+++ b/drivers/mtd/devices/Kconfig
@@ -225,4 +225,18 @@ config BCH_CONST_T
default 4
endif
+config MTD_SRAM_LP8X4X
+ tristate "SRAM on ICPDAS LP-8X4X"
+ depends on OF && ARCH_PXA
+ ---help---
+ This provides an MTD device driver for 512kiB of battery backed up SRAM
+ on ICPDAS LP-8X4X programmable automation controllers.
+
+ SRAM chip is connected via FPGA and is not accessible without a driver,
+ unlike flash memory which is wired to CPU MMU.
+
+ Say N, unless you plan to run this kernel on LP-8X4X.
+
+ If you say M, the module will be called sram_lp8x4x.
+
endmenu
diff --git a/drivers/mtd/devices/Makefile b/drivers/mtd/devices/Makefile
index c68868f..a7d86e2 100644
--- a/drivers/mtd/devices/Makefile
+++ b/drivers/mtd/devices/Makefile
@@ -17,6 +17,7 @@ obj-$(CONFIG_MTD_SPEAR_SMI) += spear_smi.o
obj-$(CONFIG_MTD_SST25L) += sst25l.o
obj-$(CONFIG_MTD_BCM47XXSFLASH) += bcm47xxsflash.o
obj-$(CONFIG_MTD_ST_SPI_FSM) += st_spi_fsm.o
+obj-$(CONFIG_MTD_SRAM_LP8X4X) += sram_lp8x4x.o
CFLAGS_docg3.o += -I$(src)
diff --git a/drivers/mtd/devices/sram_lp8x4x.c b/drivers/mtd/devices/sram_lp8x4x.c
new file mode 100644
index 0000000..4cfa70b
--- /dev/null
+++ b/drivers/mtd/devices/sram_lp8x4x.c
@@ -0,0 +1,204 @@
+/*
+ * linux/drivers/mtd/devices/lp8x4x_sram.c
+ *
+ * MTD Driver for SRAM on ICPDAS LP-8x4x
+ * Copyright (C) 2013 Sergei Ianovich <ynvich@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation or any later version.
+ */
+
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/platform_device.h>
+#include <linux/of_device.h>
+#include <linux/slab.h>
+#include <linux/string_helpers.h>
+#include <linux/types.h>
+
+struct lp8x4x_sram_info {
+ void __iomem *bank;
+ void __iomem *virt;
+ struct mutex lock;
+ unsigned active_bank;
+ struct mtd_info mtd;
+};
+
+static int
+lp8x4x_sram_erase(struct mtd_info *mtd, struct erase_info *instr)
+{
+ struct lp8x4x_sram_info *info = mtd->priv;
+ unsigned bank = instr->addr >> 11;
+ unsigned offset = (instr->addr & 0x7ff) << 1;
+ loff_t i;
+
+ mutex_lock(&info->lock);
+ if (unlikely(bank != info->active_bank)) {
+ info->active_bank = bank;
+ iowrite8(bank, info->bank);
+ }
+ for (i = 0; i < instr->len; i++) {
+ iowrite8(0xff, info->virt + offset);
+ offset += 2;
+ if (unlikely(offset == 0)) {
+ info->active_bank++;
+ iowrite8(info->active_bank, info->bank);
+ }
+ }
+ mutex_unlock(&info->lock);
+ instr->state = MTD_ERASE_DONE;
+ mtd_erase_callback(instr);
+
+ return 0;
+}
+
+static int
+lp8x4x_sram_write(struct mtd_info *mtd, loff_t to, size_t len,
+ size_t *retlen, const u_char *b)
+{
+ struct lp8x4x_sram_info *info = mtd->priv;
+ unsigned bank = to >> 11;
+ unsigned offset = (to & 0x7ff) << 1;
+ loff_t i;
+
+ mutex_lock(&info->lock);
+ if (unlikely(bank != info->active_bank)) {
+ info->active_bank = bank;
+ iowrite8(bank, info->bank);
+ }
+ for (i = 0; i < len; i++) {
+ iowrite8(b[i], info->virt + offset);
+ offset += 2;
+ if (unlikely(offset == 0)) {
+ info->active_bank++;
+ iowrite8(info->active_bank, info->bank);
+ }
+ }
+ mutex_unlock(&info->lock);
+ *retlen = len;
+ return 0;
+}
+
+static int
+lp8x4x_sram_read(struct mtd_info *mtd, loff_t from, size_t len,
+ size_t *retlen, u_char *b)
+{
+ struct lp8x4x_sram_info *info = mtd->priv;
+ unsigned bank = from >> 11;
+ unsigned offset = (from & 0x7ff) << 1;
+ loff_t i;
+
+ mutex_lock(&info->lock);
+ if (unlikely(bank != info->active_bank)) {
+ info->active_bank = bank;
+ iowrite8(bank, info->bank);
+ }
+ for (i = 0; i < len; i++) {
+ b[i] = ioread8(info->virt + offset);
+ offset += 2;
+ if (unlikely(offset == 0)) {
+ info->active_bank++;
+ iowrite8(info->active_bank, info->bank);
+ }
+ }
+ mutex_unlock(&info->lock);
+ *retlen = len;
+ return 0;
+}
+
+static struct of_device_id of_flash_match[] = {
+ {
+ .compatible = "icpdas,sram-lp8x4x",
+ },
+ { },
+};
+MODULE_DEVICE_TABLE(of, of_flash_match);
+
+static int
+lp8x4x_sram_probe(struct platform_device *pdev)
+{
+ const struct of_device_id *match;
+ struct lp8x4x_sram_info *info;
+ struct resource *res_virt, *res_bank;
+ char sz_str[16];
+ struct mtd_part_parser_data ppdata;
+ int err = 0;
+
+ match = of_match_device(of_flash_match, &pdev->dev);
+ if (!match)
+ return -EINVAL;
+
+ info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
+ if (!info)
+ return -ENOMEM;
+
+ res_virt = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ info->virt = devm_ioremap_resource(&pdev->dev, res_virt);
+ if (IS_ERR(info->virt))
+ return PTR_ERR(info->virt);
+
+ res_bank = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ info->bank = devm_ioremap_resource(&pdev->dev, res_bank);
+ if (IS_ERR(info->bank))
+ return PTR_ERR(info->bank);
+
+ info->mtd.priv = info;
+ info->mtd.name = "SRAM";
+ info->mtd.type = MTD_RAM;
+ info->mtd.flags = MTD_CAP_RAM;
+ info->mtd.size = resource_size(res_virt) << 7;
+ info->mtd.erasesize = 512;
+ info->mtd.writesize = 4;
+ info->mtd._erase = lp8x4x_sram_erase;
+ info->mtd._write = lp8x4x_sram_write;
+ info->mtd._read = lp8x4x_sram_read;
+ info->mtd.owner = THIS_MODULE;
+
+ mutex_init(&info->lock);
+ iowrite8(info->active_bank, info->bank);
+ platform_set_drvdata(pdev, info);
+
+ ppdata.of_node = pdev->dev.of_node;
+ err = mtd_device_parse_register(&info->mtd, NULL, &ppdata,
+ NULL, 0);
+
+ if (err < 0) {
+ dev_err(&pdev->dev, "failed to register MTD\n");
+ return err;
+ }
+
+ string_get_size(info->mtd.size, STRING_UNITS_2, sz_str,
+ sizeof(sz_str));
+ dev_info(&pdev->dev, "using %s SRAM on LP-8X4X as %s\n", sz_str,
+ dev_name(&info->mtd.dev));
+ return 0;
+}
+
+static int
+lp8x4x_sram_remove(struct platform_device *dev)
+{
+ struct lp8x4x_sram_info *info = platform_get_drvdata(dev);
+ return mtd_device_unregister(&info->mtd);
+}
+
+static struct platform_driver lp8x4x_sram_driver = {
+ .driver = {
+ .name = "sram-lp8x4x",
+ .owner = THIS_MODULE,
+ .of_match_table = of_flash_match,
+ },
+ .probe = lp8x4x_sram_probe,
+ .remove = lp8x4x_sram_remove,
+};
+
+module_platform_driver(lp8x4x_sram_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Sergei Ianovich <ynvich@gmail.com>");
+MODULE_DESCRIPTION("MTD driver for SRAM on ICPDAS LP-8x4x");
--
1.8.4.2
^ permalink raw reply related [flat|nested] 148+ messages in thread
* [PATCH v4 11/21] ARM: pxa: support ICP DAS LP-8x4x FPGA irq
[not found] ` <1397668667-27328-1-git-send-email-ynvich@gmail.com>
` (2 preceding siblings ...)
2014-04-16 17:17 ` [PATCH v4 10/21] mtd: support BB SRAM " Sergei Ianovich
@ 2014-04-16 17:17 ` Sergei Ianovich
[not found] ` <1397668667-27328-5-git-send-email-ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2014-04-16 17:17 ` [PATCH v4 12/21] serial: support for 16550A serial ports on LP-8x4x Sergei Ianovich
` (7 subsequent siblings)
11 siblings, 1 reply; 148+ messages in thread
From: Sergei Ianovich @ 2014-04-16 17:17 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel
Cc: Sergei Ianovich, Arnd Bergmann, Rob Herring, Pawel Moll,
Mark Rutland, Ian Campbell, Kumar Gala, Randy Dunlap,
Thomas Gleixner, Grant Likely, Linus Walleij,
open list:OPEN FIRMWARE AND..., open list:DOCUMENTATION
ICP DAS LP-8x4x contains FPGA chip. The chip functions as an interrupt
source providing 16 additional interrupts among other things. The
interrupt lines are muxed to a GPIO pin of a 2nd level PXA-GPIO
interrupt controller. GPIO pins of the 2nd level controller are in turn
muxed to a CPU interrupt line.
Until pxa is completely converted to device tree, it is impossible
to use IRQCHIP_DECLARE() and the irqdomain needs to added manually.
Drivers for the on-CPU IRQs and GPIO-IRQs are loaded using
postcore_initcall(). We need to have all irq domain drivers loaded prior
to DT parsing in order to allow normal initialization of IRQ resources
with DT.
Signed-off-by: Sergei Ianovich <ynvich@gmail.com>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
CC: Arnd Bergmann <arnd@arndb.de>
---
v3.2..v4
* move DTS binding to a different patch (8/21)
v3.1..v3.2
fixes to apply Linus Walleij's "Reviewed-by":
* add kerneldoc comment for state container struct
* rename irq -> hwirq for clarity
* drop overzealous error checks from the hotpaths
v3..v3.1
fixes according to Linus Walleij review comments:
* update commit message
* use state container instead of global variables
* get hardware irq nums from irq_data, don't calculate them
* use BIT() macro
* add defines for system irq register masks
* replace cycle control variable with break
* use better names for resource variables
* add a linear domain instead of a legacy one
* use irq_create_mapping() instead of irq_alloc_desc()
v2..v3
* no changes (except number 09/16 -> 11/21)
v0..v2
* extract irqchip and move to drivers/irqchip/
* use device tree
* use devm helpers where possible
.../bindings/interrupt-controller/irq-lp8x4x.txt | 49 +++++
drivers/irqchip/Kconfig | 5 +
drivers/irqchip/Makefile | 1 +
drivers/irqchip/irq-lp8x4x.c | 227 +++++++++++++++++++++
4 files changed, 282 insertions(+)
create mode 100644 Documentation/devicetree/bindings/interrupt-controller/irq-lp8x4x.txt
create mode 100644 drivers/irqchip/irq-lp8x4x.c
diff --git a/Documentation/devicetree/bindings/interrupt-controller/irq-lp8x4x.txt b/Documentation/devicetree/bindings/interrupt-controller/irq-lp8x4x.txt
new file mode 100644
index 0000000..c8940d2
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/irq-lp8x4x.txt
@@ -0,0 +1,49 @@
+ICP DAS LP-8x4x FPGA Interrupt Controller
+
+ICP DAS LP-8x4x contains FPGA chip. The chip functions as a interrupt
+source providing 16 additional interrupts among other things.
+
+Required properties:
+- compatible : should be "icpdas,irq-lp8x4x"
+
+- reg: physical base address of the controller and length of memory mapped
+ region.
+
+- interrupt-controller : identifies the node as an interrupt controller
+
+- #interrupt-cells : should be 1
+
+- interrupts : should provide interrupt
+
+- interrupt-parent : should provide a link to interrupt controller either
+ explicitly and implicitly from a parent node
+
+Example:
+
+ fpga: fpga@17000006 {
+ compatible = "icpdas,irq-lp8x4x";
+ reg = <0x17000006 0x16>;
+ interrupt-parent = <&gpio>;
+ interrupts = <3 IRQ_TYPE_EDGE_RISING>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ status = "okay";
+ };
+
+ uart@17009050 {
+ compatible = "icpdas,uart-lp8x4x";
+ reg = <0x17009050 0x10
+ 0x17009030 0x02>;
+ interrupt-parent = <&fpga>;
+ interrupts = <13>;
+ status = "okay";
+ };
+
+ uart@17009060 {
+ compatible = "icpdas,uart-lp8x4x";
+ reg = <0x17009060 0x10
+ 0x17009032 0x02>;
+ interrupt-parent = <&fpga>;
+ interrupts = <14>;
+ status = "okay";
+ };
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index d770f74..ede3237 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -47,6 +47,11 @@ config CLPS711X_IRQCHIP
select SPARSE_IRQ
default y
+config LP8X4X_IRQ
+ bool
+ depends on OF && ARCH_PXA
+ select IRQ_DOMAIN
+
config ORION_IRQCHIP
bool
select IRQ_DOMAIN
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index f180f8d..94f82c7 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -29,3 +29,4 @@ obj-$(CONFIG_TB10X_IRQC) += irq-tb10x.o
obj-$(CONFIG_XTENSA) += irq-xtensa-pic.o
obj-$(CONFIG_XTENSA_MX) += irq-xtensa-mx.o
obj-$(CONFIG_IRQ_CROSSBAR) += irq-crossbar.o
+obj-$(CONFIG_LP8X4X_IRQ) += irq-lp8x4x.o
diff --git a/drivers/irqchip/irq-lp8x4x.c b/drivers/irqchip/irq-lp8x4x.c
new file mode 100644
index 0000000..12ccbb03
--- /dev/null
+++ b/drivers/irqchip/irq-lp8x4x.c
@@ -0,0 +1,227 @@
+/*
+ * linux/drivers/irqchip/irq-lp8x4x.c
+ *
+ * Support for ICP DAS LP-8x4x FPGA irq
+ * Copyright (C) 2013 Sergei Ianovich <ynvich@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation or any later version.
+ */
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+
+#define EOI 0x00000000
+#define INSINT 0x00000002
+#define ENSYSINT 0x00000004
+#define PRIMINT 0x00000006
+#define PRIMINT_MASK 0xe0
+#define SECOINT 0x00000008
+#define SECOINT_MASK 0x1f
+#define ENRISEINT 0x0000000A
+#define CLRRISEINT 0x0000000C
+#define ENHILVINT 0x0000000E
+#define CLRHILVINT 0x00000010
+#define ENFALLINT 0x00000012
+#define CLRFALLINT 0x00000014
+#define IRQ_MEM_SIZE 0x00000016
+#define LP8X4X_NUM_IRQ_DEFAULT 16
+
+/**
+ * struct lp8x4x_irq_data - LP8X4X custom irq controller state container
+ * @base: base IO memory address
+ * @irq_domain: Interrupt translation domain; responsible for mapping
+ * between hwirq number and linux irq number
+ * @irq_sys_enabled: mask keeping track of interrupts enabled in the
+ * register which vendor calls 'system'
+ * @irq_high_enabled: mask keeping track of interrupts enabled in the
+ * register which vendor calls 'high'
+ *
+ * The structure implements State Container from
+ * Documentation/driver-model/design-patterns.txt
+ */
+
+struct lp8x4x_irq_data {
+ void *base;
+ struct irq_domain *domain;
+ unsigned char irq_sys_enabled;
+ unsigned char irq_high_enabled;
+};
+
+static void lp8x4x_mask_irq(struct irq_data *d)
+{
+ unsigned mask;
+ unsigned long hwirq = d->hwirq;
+ struct lp8x4x_irq_data *host = irq_data_get_irq_chip_data(d);
+
+ if (hwirq < 8) {
+ host->irq_high_enabled &= ~BIT(hwirq);
+
+ mask = ioread8(host->base + ENHILVINT);
+ mask &= ~BIT(hwirq);
+ iowrite8(mask, host->base + ENHILVINT);
+ } else {
+ hwirq -= 8;
+ host->irq_sys_enabled &= ~BIT(hwirq);
+
+ mask = ioread8(host->base + ENSYSINT);
+ mask &= ~BIT(hwirq);
+ iowrite8(mask, host->base + ENSYSINT);
+ }
+}
+
+static void lp8x4x_unmask_irq(struct irq_data *d)
+{
+ unsigned mask;
+ unsigned long hwirq = d->hwirq;
+ struct lp8x4x_irq_data *host = irq_data_get_irq_chip_data(d);
+
+ if (hwirq < 8) {
+ host->irq_high_enabled |= BIT(hwirq);
+ mask = ioread8(host->base + CLRHILVINT);
+ mask |= BIT(hwirq);
+ iowrite8(mask, host->base + CLRHILVINT);
+
+ mask = ioread8(host->base + ENHILVINT);
+ mask |= BIT(hwirq);
+ iowrite8(mask, host->base + ENHILVINT);
+ } else {
+ hwirq -= 8;
+ host->irq_sys_enabled |= BIT(hwirq);
+
+ mask = ioread8(host->base + SECOINT);
+ mask |= BIT(hwirq);
+ iowrite8(mask, host->base + SECOINT);
+
+ mask = ioread8(host->base + ENSYSINT);
+ mask |= BIT(hwirq);
+ iowrite8(mask, host->base + ENSYSINT);
+ }
+}
+
+static struct irq_chip lp8x4x_irq_chip = {
+ .name = "FPGA",
+ .irq_ack = lp8x4x_mask_irq,
+ .irq_mask = lp8x4x_mask_irq,
+ .irq_mask_ack = lp8x4x_mask_irq,
+ .irq_unmask = lp8x4x_unmask_irq,
+};
+
+static void lp8x4x_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+ int n;
+ unsigned long mask;
+ struct irq_chip *chip = irq_desc_get_chip(desc);
+ struct lp8x4x_irq_data *host = irq_desc_get_handler_data(desc);
+
+ chained_irq_enter(chip, desc);
+
+ for (;;) {
+ mask = ioread8(host->base + CLRHILVINT) & 0xff;
+ mask |= (ioread8(host->base + SECOINT) & SECOINT_MASK) << 8;
+ mask |= (ioread8(host->base + PRIMINT) & PRIMINT_MASK) << 8;
+ mask &= host->irq_high_enabled | (host->irq_sys_enabled << 8);
+ if (mask == 0)
+ break;
+ for_each_set_bit(n, &mask, BITS_PER_LONG)
+ generic_handle_irq(irq_find_mapping(host->domain, n));
+ }
+
+ iowrite8(0, host->base + EOI);
+ chained_irq_exit(chip, desc);
+}
+
+static int lp8x4x_irq_domain_map(struct irq_domain *d, unsigned int irq,
+ irq_hw_number_t hw)
+{
+ struct lp8x4x_irq_data *host = d->host_data;
+ int err;
+
+ err = irq_set_chip_data(irq, host);
+ if (err < 0)
+ return err;
+
+ irq_set_chip_and_handler(irq, &lp8x4x_irq_chip, handle_level_irq);
+ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+ return 0;
+}
+
+const struct irq_domain_ops lp8x4x_irq_domain_ops = {
+ .map = lp8x4x_irq_domain_map,
+ .xlate = irq_domain_xlate_onecell,
+};
+
+static struct of_device_id lp8x4x_irq_dt_ids[] = {
+ { .compatible = "icpdas,irq-lp8x4x", },
+ {}
+};
+
+static int lp8x4x_irq_probe(struct platform_device *pdev)
+{
+ struct resource *res_mem, *res_irq;
+ struct device_node *np = pdev->dev.of_node;
+ struct lp8x4x_irq_data *host;
+ int i, err;
+
+ res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (!res_mem || !res_irq || resource_size(res_mem) < IRQ_MEM_SIZE)
+ return -ENODEV;
+
+ host = devm_kzalloc(&pdev->dev, sizeof(*host), GFP_KERNEL);
+ if (!host)
+ return -ENODEV;
+
+ host->base = devm_ioremap_resource(&pdev->dev, res_mem);
+ if (!host->base) {
+ dev_err(&pdev->dev, "Failed to ioremap %p\n", host->base);
+ return -EFAULT;
+ }
+
+ host->domain = irq_domain_add_linear(np, LP8X4X_NUM_IRQ_DEFAULT,
+ &lp8x4x_irq_domain_ops, host);
+ if (!host->domain) {
+ dev_err(&pdev->dev, "Failed to add IRQ domain\n");
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < LP8X4X_NUM_IRQ_DEFAULT; i++) {
+ err = irq_create_mapping(host->domain, i);
+ if (err < 0)
+ dev_err(&pdev->dev, "Failed to map IRQ %i\n", i);
+ }
+
+ /* Initialize chip registers */
+ iowrite8(0, host->base + CLRRISEINT);
+ iowrite8(0, host->base + ENRISEINT);
+ iowrite8(0, host->base + CLRFALLINT);
+ iowrite8(0, host->base + ENFALLINT);
+ iowrite8(0, host->base + CLRHILVINT);
+ iowrite8(0, host->base + ENHILVINT);
+ iowrite8(0, host->base + ENSYSINT);
+ iowrite8(0, host->base + SECOINT);
+
+ irq_set_handler_data(res_irq->start, host);
+ irq_set_chained_handler(res_irq->start, lp8x4x_irq_handler);
+
+ return 0;
+}
+
+static struct platform_driver lp8x4x_irq_driver = {
+ .probe = lp8x4x_irq_probe,
+ .driver = {
+ .name = "irq-lp8x4x",
+ .of_match_table = lp8x4x_irq_dt_ids,
+ },
+};
+
+static int __init lp8x4x_irq_init(void)
+{
+ return platform_driver_register(&lp8x4x_irq_driver);
+}
+postcore_initcall(lp8x4x_irq_init);
--
1.8.4.2
^ permalink raw reply related [flat|nested] 148+ messages in thread
* [PATCH v4 12/21] serial: support for 16550A serial ports on LP-8x4x
[not found] ` <1397668667-27328-1-git-send-email-ynvich@gmail.com>
` (3 preceding siblings ...)
2014-04-16 17:17 ` [PATCH v4 11/21] ARM: pxa: support ICP DAS LP-8x4x FPGA irq Sergei Ianovich
@ 2014-04-16 17:17 ` Sergei Ianovich
2014-04-16 18:35 ` One Thousand Gnomes
2014-04-16 17:17 ` [PATCH v4 13/21] misc: support for LP-8x4x custom parallel bus Sergei Ianovich
` (6 subsequent siblings)
11 siblings, 1 reply; 148+ messages in thread
From: Sergei Ianovich @ 2014-04-16 17:17 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel
Cc: Sergei Ianovich, Rob Herring, Pawel Moll, Mark Rutland,
Ian Campbell, Kumar Gala, Randy Dunlap, Russell King,
Greg Kroah-Hartman, Jiri Slaby, Grant Likely, Heikki Krogerus,
Arnd Bergmann, Paul Bolle, Stefan Seyfried, James Cameron,
open list:OPEN FIRMWARE AND..., open list:DOCUMENTATION,
open list:SERIAL DRIVERS
The patch adds support for 3 additional LP-8x4x built-in serial
ports.
The device can also host up to 8 extension cards with 4 serial ports
on each card for a total of 35 ports. However, I don't have
the hardware to test extension cards, so they are not supported, yet.
Signed-off-by: Sergei Ianovich <ynvich@gmail.com>
Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
---
v3..v4
* move DTS bindings to a different patch (8/21) as suggested by
Heikki Krogerus
v2..v3
* no changes (except number 10/16 -> 12/21)
v0..v2
* register platform driver instead of platform device
* use device tree
* use devm helpers where possible
.../devicetree/bindings/serial/lp8x4x-serial.txt | 35 +++++
arch/arm/configs/lp8x4x_defconfig | 1 +
drivers/tty/serial/8250/8250_lp8x4x.c | 169 +++++++++++++++++++++
drivers/tty/serial/8250/Kconfig | 12 ++
drivers/tty/serial/8250/Makefile | 1 +
5 files changed, 218 insertions(+)
create mode 100644 Documentation/devicetree/bindings/serial/lp8x4x-serial.txt
create mode 100644 drivers/tty/serial/8250/8250_lp8x4x.c
diff --git a/Documentation/devicetree/bindings/serial/lp8x4x-serial.txt b/Documentation/devicetree/bindings/serial/lp8x4x-serial.txt
new file mode 100644
index 0000000..5f9a4c1
--- /dev/null
+++ b/Documentation/devicetree/bindings/serial/lp8x4x-serial.txt
@@ -0,0 +1,35 @@
+UART ports on ICP DAS LP-8x4x
+
+ICP DAS LP-8x4x contains three additional serial ports interfaced via
+Analog Devices ADM213EA chips in addition to 3 serial ports on PXA CPU.
+
+Required properties:
+- compatible : should be "icpdas,uart-lp8x4x"
+
+- reg : should provide 16 byte man IO memory region and 1 byte region for
+ termios
+
+- interrupts : should provide interrupt
+
+- interrupt-parent : should provide a link to interrupt controller either
+ explicitly or implicitly from a parent node
+
+Examples (from pxa27x-lp8x4x.dts):
+
+ uart@9050 {
+ compatible = "icpdas,uart-lp8x4x";
+ reg = <0x9050 0x10
+ 0x9030 0x02>;
+ interrupt-parent = <&fpgairg>;
+ interrupts = <13>;
+ status = "okay";
+ };
+
+ uart@9060 {
+ compatible = "icpdas,uart-lp8x4x";
+ reg = <0x9060 0x10
+ 0x9032 0x02>;
+ interrupt-parent = <&fpgairg>;
+ interrupts = <14>;
+ status = "okay";
+ };
diff --git a/arch/arm/configs/lp8x4x_defconfig b/arch/arm/configs/lp8x4x_defconfig
index 17a4e6f..9116ce1 100644
--- a/arch/arm/configs/lp8x4x_defconfig
+++ b/arch/arm/configs/lp8x4x_defconfig
@@ -112,6 +112,7 @@ CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_MANY_PORTS=y
CONFIG_SERIAL_8250_SHARE_IRQ=y
CONFIG_SERIAL_PXA=y
+CONFIG_SERIAL_8250_LP8X4X=m
CONFIG_HW_RANDOM=y
CONFIG_I2C=m
# CONFIG_I2C_COMPAT is not set
diff --git a/drivers/tty/serial/8250/8250_lp8x4x.c b/drivers/tty/serial/8250/8250_lp8x4x.c
new file mode 100644
index 0000000..93e0f59
--- /dev/null
+++ b/drivers/tty/serial/8250/8250_lp8x4x.c
@@ -0,0 +1,169 @@
+/* linux/drivers/tty/serial/8250/8250_lp8x4x.c
+ *
+ * Support for 16550A serial ports on ICP DAS LP-8x4x
+ *
+ * Copyright (C) 2013 Sergei Ianovich <ynvich@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+#include <linux/serial_8250.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+
+struct lp8x4x_serial_data {
+ int line;
+ void *ios_mem;
+};
+
+static void lp8x4x_serial_set_termios(struct uart_port *port,
+ struct ktermios *termios, struct ktermios *old)
+{
+ unsigned int len;
+ unsigned int baud;
+ struct lp8x4x_serial_data *data = port->private_data;
+
+ switch (termios->c_cflag & CSIZE) {
+ case CS5:
+ len = 7;
+ break;
+ case CS6:
+ len = 8;
+ break;
+ case CS7:
+ len = 9;
+ break;
+ default:
+ case CS8:
+ len = 10;
+ break;
+ }
+
+ if (termios->c_cflag & CSTOPB)
+ len++;
+ if (termios->c_cflag & PARENB)
+ len++;
+ if (!(termios->c_cflag & PARODD))
+ len++;
+#ifdef CMSPAR
+ if (termios->c_cflag & CMSPAR)
+ len++;
+#endif
+
+ len -= 9;
+ len &= 3;
+ len <<= 3;
+ /*
+ * Ask the core to calculate the divisor for us.
+ */
+ baud = uart_get_baud_rate(port, termios, old,
+ port->uartclk / 16 / 0xffff,
+ port->uartclk / 16);
+ switch (baud) {
+ case 2400:
+ len |= 1;
+ break;
+ case 4800:
+ len |= 2;
+ break;
+ case 19200:
+ len |= 4;
+ break;
+ case 38400:
+ len |= 5;
+ break;
+ case 57600:
+ len |= 6;
+ break;
+ case 115200:
+ len |= 7;
+ break;
+ case 9600:
+ default:
+ len |= 3;
+ break;
+ };
+ iowrite8(len, data->ios_mem);
+
+ serial8250_do_set_termios(port, termios, old);
+}
+
+static struct of_device_id lp8x4x_serial_dt_ids[] = {
+ { .compatible = "icpdas,uart-lp8x4x", },
+ {}
+};
+MODULE_DEVICE_TABLE(of, lp8x4x_serial_dt_ids);
+
+static int lp8x4x_serial_probe(struct platform_device *pdev)
+{
+ struct uart_8250_port uart = {};
+ struct lp8x4x_serial_data *data;
+ struct resource *mmres, *mires, *irqres;
+ int ret;
+
+ mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ mires = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ irqres = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (!mmres || !mires || !irqres)
+ return -ENODEV;
+
+ data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ data->ios_mem = devm_ioremap_resource(&pdev->dev, mires);
+ if (!data->ios_mem)
+ return -EFAULT;
+
+ uart.port.iotype = UPIO_MEM;
+ uart.port.mapbase = mmres->start;
+ uart.port.iobase = mmres->start;
+ uart.port.regshift = 1;
+ uart.port.irq = irqres->start;
+ uart.port.flags = UPF_IOREMAP;
+ uart.port.dev = &pdev->dev;
+ uart.port.uartclk = 14745600;
+ uart.port.set_termios = lp8x4x_serial_set_termios;
+ uart.port.private_data = data;
+
+ ret = serial8250_register_8250_port(&uart);
+ if (ret < 0)
+ return ret;
+
+ data->line = ret;
+
+ platform_set_drvdata(pdev, data);
+
+ return 0;
+}
+
+static int lp8x4x_serial_remove(struct platform_device *pdev)
+{
+ struct lp8x4x_serial_data *data = platform_get_drvdata(pdev);
+
+ serial8250_unregister_port(data->line);
+
+ return 0;
+}
+
+static struct platform_driver lp8x4x_serial_driver = {
+ .probe = lp8x4x_serial_probe,
+ .remove = lp8x4x_serial_remove,
+
+ .driver = {
+ .name = "uart-lp8x4x",
+ .owner = THIS_MODULE,
+ .of_match_table = lp8x4x_serial_dt_ids,
+ },
+};
+
+module_platform_driver(lp8x4x_serial_driver);
+
+MODULE_AUTHOR("Sergei Ianovich");
+MODULE_DESCRIPTION("8250 serial port module for LP-8x4x");
+MODULE_LICENSE("GPL");
diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig
index 81bd7c9..9fb0fbb 100644
--- a/drivers/tty/serial/8250/Kconfig
+++ b/drivers/tty/serial/8250/Kconfig
@@ -311,3 +311,15 @@ config SERIAL_PXA
can enable its onboard serial ports by enabling this option.
If you choose M here, the module name will be 8250_pxa.
+
+config SERIAL_8250_LP8X4X
+ tristate "Support 16550A ports on ICP DAS LP-8x4x"
+ depends on OF && SERIAL_8250 && SERIAL_8250_MANY_PORTS && ARCH_PXA
+ select LP8X4X_IRQ
+ help
+ In addition to serial ports on PXA270 SoC, LP-8x4x has 1 dual
+ RS232/RS485 port, 1 RS485 port and 1 RS232 port.
+
+ Say N here, unless you plan to run this kernel on a LP-8x4x system.
+
+ If you choose M here, the module name will be 8250_lp8x4x.
diff --git a/drivers/tty/serial/8250/Makefile b/drivers/tty/serial/8250/Makefile
index b7d1b61..7370bfb 100644
--- a/drivers/tty/serial/8250/Makefile
+++ b/drivers/tty/serial/8250/Makefile
@@ -17,6 +17,7 @@ obj-$(CONFIG_SERIAL_8250_ACCENT) += 8250_accent.o
obj-$(CONFIG_SERIAL_8250_BOCA) += 8250_boca.o
obj-$(CONFIG_SERIAL_8250_EXAR_ST16C554) += 8250_exar_st16c554.o
obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o
+obj-$(CONFIG_SERIAL_8250_LP8X4X) += 8250_lp8x4x.o
obj-$(CONFIG_SERIAL_8250_FSL) += 8250_fsl.o
obj-$(CONFIG_SERIAL_8250_DW) += 8250_dw.o
obj-$(CONFIG_SERIAL_8250_EM) += 8250_em.o
--
1.8.4.2
^ permalink raw reply related [flat|nested] 148+ messages in thread
* [PATCH v4 13/21] misc: support for LP-8x4x custom parallel bus
[not found] ` <1397668667-27328-1-git-send-email-ynvich@gmail.com>
` (4 preceding siblings ...)
2014-04-16 17:17 ` [PATCH v4 12/21] serial: support for 16550A serial ports on LP-8x4x Sergei Ianovich
@ 2014-04-16 17:17 ` Sergei Ianovich
2014-04-16 18:41 ` One Thousand Gnomes
2014-04-16 17:17 ` [PATCH v4 14/21] misc: support for LP-8x4x rotary switch Sergei Ianovich
` (5 subsequent siblings)
11 siblings, 1 reply; 148+ messages in thread
From: Sergei Ianovich @ 2014-04-16 17:17 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel
Cc: Mark Rutland, open list:OPEN FIRMWARE AND..., Heikki Krogerus,
Russell King, Arnd Bergmann, Pawel Moll, Ian Campbell,
Greg Kroah-Hartman, Randy Dunlap, open list:DOCUMENTATION,
Sergei Ianovich, Rob Herring, Kumar Gala, Grant Likely
This patch implements probing for the bus and reporting the number
of available expansion slots.
Signed-off-by: Sergei Ianovich <ynvich@gmail.com>
---
v3..v4
* move DTS binding to a different patch (8/21)
v2..v3
* fixed goto after bus_register
* number change (11/16 -> 13/21)
v0..v2
* use device tree
* use devm helpers where possible
.../devicetree/bindings/misc/lp8x4x-bus.txt | 16 ++
Documentation/misc-devices/lp8x4x_bus.txt | 30 ++++
arch/arm/configs/lp8x4x_defconfig | 1 +
drivers/misc/Kconfig | 13 ++
drivers/misc/Makefile | 1 +
drivers/misc/lp8x4x_bus.c | 167 +++++++++++++++++++++
6 files changed, 228 insertions(+)
create mode 100644 Documentation/devicetree/bindings/misc/lp8x4x-bus.txt
create mode 100644 Documentation/misc-devices/lp8x4x_bus.txt
create mode 100644 drivers/misc/lp8x4x_bus.c
diff --git a/Documentation/devicetree/bindings/misc/lp8x4x-bus.txt b/Documentation/devicetree/bindings/misc/lp8x4x-bus.txt
new file mode 100644
index 0000000..1c87a29
--- /dev/null
+++ b/Documentation/devicetree/bindings/misc/lp8x4x-bus.txt
@@ -0,0 +1,16 @@
+Custom parallel bus on ICP DAS LP-8x4x industrial computers
+
+See Documentation/misc-devices/lp8x4x_bus.txt for details.
+
+Required properties:
+- compatible : should be "icpdas,backplane-lp8x4x"
+
+- reg: physical base address of the slot count register and the length
+ of the memory mapped region.
+
+Example:
+
+ backplane {
+ compatible = "icpdas,backplane-lp8x4x";
+ reg = <0x17009046 0x2>;
+ };
diff --git a/Documentation/misc-devices/lp8x4x_bus.txt b/Documentation/misc-devices/lp8x4x_bus.txt
new file mode 100644
index 0000000..f5392b3
--- /dev/null
+++ b/Documentation/misc-devices/lp8x4x_bus.txt
@@ -0,0 +1,30 @@
+Kernel driver lpx8x4x_bus
+======================
+
+Supported hardare:
+Custom parallel bus on ICP DAS LP-8x4x industrial computers
+
+Data sheet:
+Not freely available
+
+Author:
+Sergei Ianovich <ynvich@gmail.com>
+
+Description
+-----------
+
+http://www.icpdas.com/root/product/solutions/pac/linpac/lp-8x4x_hardware.html
+
+LP-8x4x is an ARM-based industrial computer with a custom parallel bus to
+connect expansion modules with digital input/output, analog input/output,
+serial, CAN and other types of ports.
+
+The bus is implemented by a FPGA.
+
+SYSFS
+-----
+
+/sys/bus/icpdas/devices/backplane:
+
+slot_count
+ RO - shows total number of expansion slots on the device
diff --git a/arch/arm/configs/lp8x4x_defconfig b/arch/arm/configs/lp8x4x_defconfig
index 9116ce1..c34eb2a 100644
--- a/arch/arm/configs/lp8x4x_defconfig
+++ b/arch/arm/configs/lp8x4x_defconfig
@@ -62,6 +62,7 @@ CONFIG_PROC_DEVICETREE=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_LOOP_MIN_COUNT=2
CONFIG_EEPROM_AT24=m
+CONFIG_LP8X4X_BUS=m
CONFIG_SCSI=y
# CONFIG_SCSI_PROC_FS is not set
CONFIG_BLK_DEV_SD=y
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 1cb7408..08ffe63 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -515,6 +515,19 @@ config SRAM
the genalloc API. It is supposed to be used for small on-chip SRAM
areas found on many SoCs.
+config LP8X4X_BUS
+ tristate "ICP DAS LP-8x4x industrial IO bus"
+ depends on OF && ARCH_PXA
+ select SYSFS
+ ---help---
+ This is a driver for ICP DAS LP-8x4x programmable automation
+ controller. It exposes a custom parallel bus. The bus services
+ data acquisition and control modules.
+
+ Say N, unless you plan to run this kernel on a LP-8x4x system.
+
+ If you say M here, the module will be called lp8x4x_bus.
+
source "drivers/misc/c2port/Kconfig"
source "drivers/misc/eeprom/Kconfig"
source "drivers/misc/cb710/Kconfig"
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 7eb4b69..2bfe25d 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -55,3 +55,4 @@ obj-$(CONFIG_SRAM) += sram.o
obj-y += mic/
obj-$(CONFIG_GENWQE) += genwqe/
obj-$(CONFIG_ECHO) += echo/
+obj-$(CONFIG_LP8X4X_BUS) += lp8x4x_bus.o
diff --git a/drivers/misc/lp8x4x_bus.c b/drivers/misc/lp8x4x_bus.c
new file mode 100644
index 0000000..7aa55cf
--- /dev/null
+++ b/drivers/misc/lp8x4x_bus.c
@@ -0,0 +1,167 @@
+/*
+ * linux/misc/lp8x4x_bus.c
+ *
+ * Support for ICP DAS LP-8x4x programmable automation controller bus
+ * Copyright (C) 2013 Sergei Ianovich <ynvich@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation or any later version.
+ */
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#define MODULE_NAME "lp8x4x-bus"
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Sergei Ianovich <ynvich@gmail.com>");
+MODULE_DESCRIPTION("ICP DAS LP-8x4x parallel bus driver");
+
+struct lp8x4x_master {
+ unsigned int slot_count;
+ void *count_addr;
+ struct device dev;
+};
+
+static int lp8x4x_match(struct device *dev, struct device_driver *drv)
+{
+ return 1;
+}
+
+static struct bus_type lp8x4x_bus_type = {
+ .name = "icpdas",
+ .match = lp8x4x_match,
+};
+
+static void lp8x4x_master_release(struct device *dev)
+{
+ struct lp8x4x_master *m = container_of(dev, struct lp8x4x_master, dev);
+ WARN_ON(!dev);
+
+ kfree(m);
+}
+
+static ssize_t slot_count_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct lp8x4x_master *m = container_of(dev, struct lp8x4x_master, dev);
+
+ return sprintf(buf, "%u\n", m->slot_count);
+}
+
+static DEVICE_ATTR_RO(slot_count);
+
+static struct attribute *master_dev_attrs[] = {
+ &dev_attr_slot_count.attr,
+ NULL,
+};
+ATTRIBUTE_GROUPS(master_dev);
+
+
+static void devm_lp8x4x_bus_release(struct device *dev, void *res)
+{
+ struct lp8x4x_master *m = *(struct lp8x4x_master **)res;
+
+ dev_dbg(dev, "releasing devices\n");
+ device_unregister(&m->dev);
+ bus_unregister(&lp8x4x_bus_type);
+}
+
+static int __init lp8x4x_bus_probe(struct platform_device *pdev)
+{
+ struct lp8x4x_master *m, **p;
+ struct resource *res;
+ int err = 0;
+
+ m = kzalloc(sizeof(*m), GFP_KERNEL);
+ if (!m)
+ return -ENOMEM;
+
+ p = devres_alloc(devm_lp8x4x_bus_release, sizeof(*p), GFP_KERNEL);
+ if (!p) {
+ err = -ENOMEM;
+ goto err1;
+ }
+ *p = m;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "could not get slot count address\n");
+ err = -ENODEV;
+ goto err2;
+ }
+
+ m->count_addr = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(m->count_addr)) {
+ dev_err(&pdev->dev, "Failed to ioremap slot count address\n");
+ err = PTR_ERR(m->count_addr);
+ goto err2;
+ }
+
+ m->slot_count = ioread8(m->count_addr);
+ switch (m->slot_count) {
+ case 1:
+ case 4:
+ break;
+ case 7:
+ m->slot_count = 8;
+ break;
+ default:
+ dev_err(&pdev->dev, "unexpected slot number(%u)",
+ m->slot_count);
+ err = -ENODEV;
+ goto err2;
+ };
+
+ dev_info(&pdev->dev, "found bus with up to %u slots\n", m->slot_count);
+
+ err = bus_register(&lp8x4x_bus_type);
+ if (err < 0) {
+ dev_err(&pdev->dev, "failed to register bus type\n");
+ goto err2;
+ }
+
+ m->dev.bus = &lp8x4x_bus_type;
+ dev_set_name(&m->dev, "backplane");
+ m->dev.parent = &pdev->dev;
+ m->dev.release = lp8x4x_master_release;
+ m->dev.groups = master_dev_groups;
+
+ err = device_register(&m->dev);
+ if (err < 0) {
+ dev_err(&pdev->dev, "failed to register backplane device\n");
+ goto err3;
+ }
+
+ devres_add(&pdev->dev, p);
+ return 0;
+
+err3:
+ bus_unregister(&lp8x4x_bus_type);
+err2:
+ devres_free(p);
+err1:
+ kfree(m);
+ return err;
+}
+
+static const struct of_device_id lp8x4x_bus_dt_ids[] = {
+ { .compatible = "icpdas,backplane-lp8x4x" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, lp8x4x_bus_dt_ids);
+
+static struct platform_driver lp8x4x_bus_driver = {
+ .driver = {
+ .name = MODULE_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = lp8x4x_bus_dt_ids,
+ },
+};
+
+module_platform_driver_probe(lp8x4x_bus_driver, lp8x4x_bus_probe);
--
1.8.4.2
^ permalink raw reply related [flat|nested] 148+ messages in thread
* [PATCH v4 14/21] misc: support for LP-8x4x rotary switch
[not found] ` <1397668667-27328-1-git-send-email-ynvich@gmail.com>
` (5 preceding siblings ...)
2014-04-16 17:17 ` [PATCH v4 13/21] misc: support for LP-8x4x custom parallel bus Sergei Ianovich
@ 2014-04-16 17:17 ` Sergei Ianovich
2014-04-16 17:17 ` [PATCH v4 15/21] misc: support for LP-8x4x DIP switch Sergei Ianovich
` (4 subsequent siblings)
11 siblings, 0 replies; 148+ messages in thread
From: Sergei Ianovich @ 2014-04-16 17:17 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel
Cc: Sergei Ianovich, Rob Herring, Pawel Moll, Mark Rutland,
Ian Campbell, Kumar Gala, Randy Dunlap, Arnd Bergmann,
Greg Kroah-Hartman, open list:OPEN FIRMWARE AND...,
open list:DOCUMENTATION
Signed-off-by: Sergei Ianovich <ynvich@gmail.com>
---
v3..v4
* move DTS binding to a different patch (8/21)
v2..v3
* new patch
.../devicetree/bindings/misc/lp8x4x-bus.txt | 8 ++--
Documentation/misc-devices/lp8x4x_bus.txt | 3 ++
drivers/misc/lp8x4x_bus.c | 43 ++++++++++++++++++----
3 files changed, 43 insertions(+), 11 deletions(-)
diff --git a/Documentation/devicetree/bindings/misc/lp8x4x-bus.txt b/Documentation/devicetree/bindings/misc/lp8x4x-bus.txt
index 1c87a29..8a55020 100644
--- a/Documentation/devicetree/bindings/misc/lp8x4x-bus.txt
+++ b/Documentation/devicetree/bindings/misc/lp8x4x-bus.txt
@@ -5,12 +5,14 @@ See Documentation/misc-devices/lp8x4x_bus.txt for details.
Required properties:
- compatible : should be "icpdas,backplane-lp8x4x"
-- reg: physical base address of the slot count register and the length
- of the memory mapped region.
+- reg: physical base addresses and region lengths of
+ * the rotary switch
+ * the slot count register
Example:
backplane {
compatible = "icpdas,backplane-lp8x4x";
- reg = <0x17009046 0x2>;
+ reg = <0x0 0x2
+ 0x9046 0x2>;
};
diff --git a/Documentation/misc-devices/lp8x4x_bus.txt b/Documentation/misc-devices/lp8x4x_bus.txt
index f5392b3..bea435b 100644
--- a/Documentation/misc-devices/lp8x4x_bus.txt
+++ b/Documentation/misc-devices/lp8x4x_bus.txt
@@ -26,5 +26,8 @@ SYSFS
/sys/bus/icpdas/devices/backplane:
+rotary
+ RO - shows position of LP-8x4x rotary switch (0-9)
+
slot_count
RO - shows total number of expansion slots on the device
diff --git a/drivers/misc/lp8x4x_bus.c b/drivers/misc/lp8x4x_bus.c
index 7aa55cf..18ca8f8 100644
--- a/drivers/misc/lp8x4x_bus.c
+++ b/drivers/misc/lp8x4x_bus.c
@@ -25,6 +25,7 @@ MODULE_DESCRIPTION("ICP DAS LP-8x4x parallel bus driver");
struct lp8x4x_master {
unsigned int slot_count;
void *count_addr;
+ void *rotary_addr;
struct device dev;
};
@@ -56,8 +57,19 @@ static ssize_t slot_count_show(struct device *dev,
static DEVICE_ATTR_RO(slot_count);
+static ssize_t rotary_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct lp8x4x_master *m = container_of(dev, struct lp8x4x_master, dev);
+
+ return sprintf(buf, "%u\n", (ioread8(m->rotary_addr) ^ 0xf) & 0xf);
+}
+
+static DEVICE_ATTR_RO(rotary);
+
static struct attribute *master_dev_attrs[] = {
&dev_attr_slot_count.attr,
+ &dev_attr_rotary.attr,
NULL,
};
ATTRIBUTE_GROUPS(master_dev);
@@ -76,6 +88,7 @@ static int __init lp8x4x_bus_probe(struct platform_device *pdev)
{
struct lp8x4x_master *m, **p;
struct resource *res;
+ int r = 0;
int err = 0;
m = kzalloc(sizeof(*m), GFP_KERNEL);
@@ -89,18 +102,32 @@ static int __init lp8x4x_bus_probe(struct platform_device *pdev)
}
*p = m;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ res = platform_get_resource(pdev, IORESOURCE_MEM, r++);
+ if (!res) {
+ dev_err(&pdev->dev, "Failed to get rotary address\n");
+ err = -ENODEV;
+ goto err_free;
+ }
+
+ m->rotary_addr = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(m->rotary_addr)) {
+ dev_err(&pdev->dev, "Failed to ioremap rotary address\n");
+ err = PTR_ERR(m->rotary_addr);
+ goto err_free;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, r++);
if (!res) {
dev_err(&pdev->dev, "could not get slot count address\n");
err = -ENODEV;
- goto err2;
+ goto err_free;
}
m->count_addr = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(m->count_addr)) {
dev_err(&pdev->dev, "Failed to ioremap slot count address\n");
err = PTR_ERR(m->count_addr);
- goto err2;
+ goto err_free;
}
m->slot_count = ioread8(m->count_addr);
@@ -115,7 +142,7 @@ static int __init lp8x4x_bus_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "unexpected slot number(%u)",
m->slot_count);
err = -ENODEV;
- goto err2;
+ goto err_free;
};
dev_info(&pdev->dev, "found bus with up to %u slots\n", m->slot_count);
@@ -123,7 +150,7 @@ static int __init lp8x4x_bus_probe(struct platform_device *pdev)
err = bus_register(&lp8x4x_bus_type);
if (err < 0) {
dev_err(&pdev->dev, "failed to register bus type\n");
- goto err2;
+ goto err_free;
}
m->dev.bus = &lp8x4x_bus_type;
@@ -135,15 +162,15 @@ static int __init lp8x4x_bus_probe(struct platform_device *pdev)
err = device_register(&m->dev);
if (err < 0) {
dev_err(&pdev->dev, "failed to register backplane device\n");
- goto err3;
+ goto err_bus;
}
devres_add(&pdev->dev, p);
return 0;
-err3:
+err_bus:
bus_unregister(&lp8x4x_bus_type);
-err2:
+err_free:
devres_free(p);
err1:
kfree(m);
--
1.8.4.2
^ permalink raw reply related [flat|nested] 148+ messages in thread
* [PATCH v4 15/21] misc: support for LP-8x4x DIP switch
[not found] ` <1397668667-27328-1-git-send-email-ynvich@gmail.com>
` (6 preceding siblings ...)
2014-04-16 17:17 ` [PATCH v4 14/21] misc: support for LP-8x4x rotary switch Sergei Ianovich
@ 2014-04-16 17:17 ` Sergei Ianovich
2014-04-16 17:17 ` [PATCH v4 16/21] misc: support for writing to LP-8x4x EEPROM Sergei Ianovich
` (3 subsequent siblings)
11 siblings, 0 replies; 148+ messages in thread
From: Sergei Ianovich @ 2014-04-16 17:17 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel
Cc: Mark Rutland, open list:OPEN FIRMWARE AND..., Arnd Bergmann,
Pawel Moll, Ian Campbell, Greg Kroah-Hartman, Randy Dunlap,
open list:DOCUMENTATION, Sergei Ianovich, Rob Herring, Kumar Gala
Signed-off-by: Sergei Ianovich <ynvich@gmail.com>
---
v3..v4
* move DTS binding to a different patch (8/21)
v2..v3
* new patch
.../devicetree/bindings/misc/lp8x4x-bus.txt | 2 ++
Documentation/misc-devices/lp8x4x_bus.txt | 3 +++
drivers/misc/lp8x4x_bus.c | 26 ++++++++++++++++++++++
3 files changed, 31 insertions(+)
diff --git a/Documentation/devicetree/bindings/misc/lp8x4x-bus.txt b/Documentation/devicetree/bindings/misc/lp8x4x-bus.txt
index 8a55020..1b1776a 100644
--- a/Documentation/devicetree/bindings/misc/lp8x4x-bus.txt
+++ b/Documentation/devicetree/bindings/misc/lp8x4x-bus.txt
@@ -7,6 +7,7 @@ Required properties:
- reg: physical base addresses and region lengths of
* the rotary switch
+ * the 8bit DIP switch
* the slot count register
Example:
@@ -14,5 +15,6 @@ Example:
backplane {
compatible = "icpdas,backplane-lp8x4x";
reg = <0x0 0x2
+ 0x9002 0x2
0x9046 0x2>;
};
diff --git a/Documentation/misc-devices/lp8x4x_bus.txt b/Documentation/misc-devices/lp8x4x_bus.txt
index bea435b..829781b 100644
--- a/Documentation/misc-devices/lp8x4x_bus.txt
+++ b/Documentation/misc-devices/lp8x4x_bus.txt
@@ -26,6 +26,9 @@ SYSFS
/sys/bus/icpdas/devices/backplane:
+dip
+ RO - shows status of LP-8x4x 8bit DIP switch
+
rotary
RO - shows position of LP-8x4x rotary switch (0-9)
diff --git a/drivers/misc/lp8x4x_bus.c b/drivers/misc/lp8x4x_bus.c
index 18ca8f8..dfbc8c4 100644
--- a/drivers/misc/lp8x4x_bus.c
+++ b/drivers/misc/lp8x4x_bus.c
@@ -26,6 +26,7 @@ struct lp8x4x_master {
unsigned int slot_count;
void *count_addr;
void *rotary_addr;
+ void *dip_addr;
struct device dev;
};
@@ -67,9 +68,20 @@ static ssize_t rotary_show(struct device *dev,
static DEVICE_ATTR_RO(rotary);
+static ssize_t dip_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct lp8x4x_master *m = container_of(dev, struct lp8x4x_master, dev);
+
+ return sprintf(buf, "0x%02x\n", ioread8(m->dip_addr) ^ 0xff);
+}
+
+static DEVICE_ATTR_RO(dip);
+
static struct attribute *master_dev_attrs[] = {
&dev_attr_slot_count.attr,
&dev_attr_rotary.attr,
+ &dev_attr_dip.attr,
NULL,
};
ATTRIBUTE_GROUPS(master_dev);
@@ -118,6 +130,20 @@ static int __init lp8x4x_bus_probe(struct platform_device *pdev)
res = platform_get_resource(pdev, IORESOURCE_MEM, r++);
if (!res) {
+ dev_err(&pdev->dev, "Failed to get DIP switch address\n");
+ err = -ENODEV;
+ goto err_free;
+ }
+
+ m->dip_addr = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(m->dip_addr)) {
+ dev_err(&pdev->dev, "Failed to ioremap DIP switch address\n");
+ err = PTR_ERR(m->dip_addr);
+ goto err_free;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, r++);
+ if (!res) {
dev_err(&pdev->dev, "could not get slot count address\n");
err = -ENODEV;
goto err_free;
--
1.8.4.2
^ permalink raw reply related [flat|nested] 148+ messages in thread
* [PATCH v4 16/21] misc: support for writing to LP-8x4x EEPROM
[not found] ` <1397668667-27328-1-git-send-email-ynvich@gmail.com>
` (7 preceding siblings ...)
2014-04-16 17:17 ` [PATCH v4 15/21] misc: support for LP-8x4x DIP switch Sergei Ianovich
@ 2014-04-16 17:17 ` Sergei Ianovich
2014-04-16 17:17 ` [PATCH v4 17/21] misc: support for serial slots in LP-8x4x Sergei Ianovich
` (2 subsequent siblings)
11 siblings, 0 replies; 148+ messages in thread
From: Sergei Ianovich @ 2014-04-16 17:17 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel
Cc: Sergei Ianovich, Rob Herring, Pawel Moll, Mark Rutland,
Ian Campbell, Kumar Gala, Randy Dunlap, Arnd Bergmann,
Greg Kroah-Hartman, open list:OPEN FIRMWARE AND...,
open list:DOCUMENTATION
at24c128 write protection is implemented by a separate GPIO line.
EEPROM driver doesn't provide this option, so we implement it
in the board-specific device.
Signed-off-by: Sergei Ianovich <ynvich@gmail.com>
---
v3..v4
* move DTS binding to a different patch (8/21)
v2..v3
* new patch
.../devicetree/bindings/misc/lp8x4x-bus.txt | 3 ++
Documentation/misc-devices/lp8x4x_bus.txt | 3 ++
drivers/misc/lp8x4x_bus.c | 50 ++++++++++++++++++++++
3 files changed, 56 insertions(+)
diff --git a/Documentation/devicetree/bindings/misc/lp8x4x-bus.txt b/Documentation/devicetree/bindings/misc/lp8x4x-bus.txt
index 1b1776a..b0fb145 100644
--- a/Documentation/devicetree/bindings/misc/lp8x4x-bus.txt
+++ b/Documentation/devicetree/bindings/misc/lp8x4x-bus.txt
@@ -10,6 +10,8 @@ Required properties:
* the 8bit DIP switch
* the slot count register
+- eeprom-gpios : should point to active-low write enable GPIO
+
Example:
backplane {
@@ -17,4 +19,5 @@ Example:
reg = <0x0 0x2
0x9002 0x2
0x9046 0x2>;
+ eeprom-gpios = <&gpio 4 0>;
};
diff --git a/Documentation/misc-devices/lp8x4x_bus.txt b/Documentation/misc-devices/lp8x4x_bus.txt
index 829781b..78ea0a89 100644
--- a/Documentation/misc-devices/lp8x4x_bus.txt
+++ b/Documentation/misc-devices/lp8x4x_bus.txt
@@ -29,6 +29,9 @@ SYSFS
dip
RO - shows status of LP-8x4x 8bit DIP switch
+eeprom_write_enable
+ RW - controls write access to board's EEPROM (1 - enable)
+
rotary
RO - shows position of LP-8x4x rotary switch (0-9)
diff --git a/drivers/misc/lp8x4x_bus.c b/drivers/misc/lp8x4x_bus.c
index dfbc8c4..567fe078 100644
--- a/drivers/misc/lp8x4x_bus.c
+++ b/drivers/misc/lp8x4x_bus.c
@@ -9,6 +9,7 @@
* published by the Free Software Foundation or any later version.
*/
#include <linux/err.h>
+#include <linux/gpio/consumer.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/list.h>
@@ -27,6 +28,7 @@ struct lp8x4x_master {
void *count_addr;
void *rotary_addr;
void *dip_addr;
+ struct gpio_desc *eeprom_nWE;
struct device dev;
};
@@ -68,6 +70,40 @@ static ssize_t rotary_show(struct device *dev,
static DEVICE_ATTR_RO(rotary);
+static ssize_t eeprom_write_enable_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct lp8x4x_master *m = container_of(dev, struct lp8x4x_master, dev);
+
+ return sprintf(buf, "%u\n", !gpiod_get_value(m->eeprom_nWE));
+}
+
+static ssize_t eeprom_write_enable_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct lp8x4x_master *m = container_of(dev, struct lp8x4x_master, dev);
+ unsigned int val = 0;
+ int err;
+
+ if (!buf)
+ return count;
+
+ if (0 == count)
+ return count;
+
+ err = kstrtouint(buf, 10, &val);
+ if (err != 0) {
+ dev_err(dev, "Bad input %s\n", buf);
+ return count;
+ }
+
+ gpiod_set_value(m->eeprom_nWE, !val);
+
+ return count;
+}
+
+static DEVICE_ATTR_RW(eeprom_write_enable);
+
static ssize_t dip_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -81,6 +117,7 @@ static DEVICE_ATTR_RO(dip);
static struct attribute *master_dev_attrs[] = {
&dev_attr_slot_count.attr,
&dev_attr_rotary.attr,
+ &dev_attr_eeprom_write_enable.attr,
&dev_attr_dip.attr,
NULL,
};
@@ -156,6 +193,19 @@ static int __init lp8x4x_bus_probe(struct platform_device *pdev)
goto err_free;
}
+ m->eeprom_nWE = devm_gpiod_get(&pdev->dev, "eeprom");
+ if (IS_ERR(m->eeprom_nWE)) {
+ err = PTR_ERR(m->eeprom_nWE);
+ dev_err(&pdev->dev, "Failed to get eeprom GPIO\n");
+ goto err_free;
+ }
+
+ err = gpiod_direction_output(m->eeprom_nWE, 1);
+ if (err < 0) {
+ dev_err(&pdev->dev, "Failed to set eeprom GPIO output\n");
+ goto err_free;
+ }
+
m->slot_count = ioread8(m->count_addr);
switch (m->slot_count) {
case 1:
--
1.8.4.2
^ permalink raw reply related [flat|nested] 148+ messages in thread
* [PATCH v4 17/21] misc: support for serial slots in LP-8x4x
[not found] ` <1397668667-27328-1-git-send-email-ynvich@gmail.com>
` (8 preceding siblings ...)
2014-04-16 17:17 ` [PATCH v4 16/21] misc: support for writing to LP-8x4x EEPROM Sergei Ianovich
@ 2014-04-16 17:17 ` Sergei Ianovich
2014-04-16 17:17 ` [PATCH v4 18/21] misc: support for parallel " Sergei Ianovich
[not found] ` <1397668667-27328-1-git-send-email-ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
11 siblings, 0 replies; 148+ messages in thread
From: Sergei Ianovich @ 2014-04-16 17:17 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel
Cc: Sergei Ianovich, Rob Herring, Pawel Moll, Mark Rutland,
Ian Campbell, Kumar Gala, Randy Dunlap, Arnd Bergmann,
Greg Kroah-Hartman, open list:OPEN FIRMWARE AND...,
open list:DOCUMENTATION
Serial modules (I-870xxW series) implement DCON protocol which
allows one-master-many-slaves configuration over RS-485. When
these modules are installed into the device, they could be
accessed using the 2nd PXA built-in UART port (/dev/ttyS1).
However, it seems that addresses are not processed by the modules.
So the parallel bus needs to select which slot is connected.
Signed-off-by: Sergei Ianovich <ynvich@gmail.com>
---
v3..v4
* move DTS binding to a different patch (8/21)
v2..v3
* no changes (except number 12/16 -> 17/21)
v0..v2
* use device tree
* use devm helpers where possible
.../devicetree/bindings/misc/lp8x4x-bus.txt | 2 +
Documentation/misc-devices/lp8x4x_bus.txt | 15 +++++-
drivers/misc/lp8x4x_bus.c | 63 ++++++++++++++++++++++
3 files changed, 79 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/misc/lp8x4x-bus.txt b/Documentation/devicetree/bindings/misc/lp8x4x-bus.txt
index b0fb145..24a8c62 100644
--- a/Documentation/devicetree/bindings/misc/lp8x4x-bus.txt
+++ b/Documentation/devicetree/bindings/misc/lp8x4x-bus.txt
@@ -8,6 +8,7 @@ Required properties:
- reg: physical base addresses and region lengths of
* the rotary switch
* the 8bit DIP switch
+ * the serial slot select register
* the slot count register
- eeprom-gpios : should point to active-low write enable GPIO
@@ -18,6 +19,7 @@ Example:
compatible = "icpdas,backplane-lp8x4x";
reg = <0x0 0x2
0x9002 0x2
+ 0x9004 0x2
0x9046 0x2>;
eeprom-gpios = <&gpio 4 0>;
};
diff --git a/Documentation/misc-devices/lp8x4x_bus.txt b/Documentation/misc-devices/lp8x4x_bus.txt
index 78ea0a89..7b86797 100644
--- a/Documentation/misc-devices/lp8x4x_bus.txt
+++ b/Documentation/misc-devices/lp8x4x_bus.txt
@@ -19,13 +19,26 @@ LP-8x4x is an ARM-based industrial computer with a custom parallel bus to
connect expansion modules with digital input/output, analog input/output,
serial, CAN and other types of ports.
-The bus is implemented by a FPGA.
+The bus is implemented by a FPGA. There are two major groups of expansion
+modules: serial and parallel.
+
+Serial modules (I-870xxW series) implement DCON protocol which allows one-
+master-many-slaves configuration over RS-485. When these modules are installed
+into the device, they could be accessed using the 2nd PXA built-in UART port
+(/dev/ttyS1). However, it seems that addresses are not processed by
+the modules. So the parallel bus needs to select which slot is connected.
SYSFS
-----
/sys/bus/icpdas/devices/backplane:
+active_slot
+ RW - connects the select slot for serial communications. If there
+ is a parallel module in the selected slot, it simply ignores
+ incoming packets. So it is safe to activate any available
+ slot.
+
dip
RO - shows status of LP-8x4x 8bit DIP switch
diff --git a/drivers/misc/lp8x4x_bus.c b/drivers/misc/lp8x4x_bus.c
index 567fe078..e805640 100644
--- a/drivers/misc/lp8x4x_bus.c
+++ b/drivers/misc/lp8x4x_bus.c
@@ -29,6 +29,8 @@ struct lp8x4x_master {
void *rotary_addr;
void *dip_addr;
struct gpio_desc *eeprom_nWE;
+ unsigned int active_slot;
+ void *switch_addr;
struct device dev;
};
@@ -47,6 +49,9 @@ static void lp8x4x_master_release(struct device *dev)
struct lp8x4x_master *m = container_of(dev, struct lp8x4x_master, dev);
WARN_ON(!dev);
+ /* Disable serial communications */
+ iowrite8(0xff, m->switch_addr);
+
kfree(m);
}
@@ -114,11 +119,52 @@ static ssize_t dip_show(struct device *dev,
static DEVICE_ATTR_RO(dip);
+static ssize_t active_slot_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct lp8x4x_master *m = container_of(dev, struct lp8x4x_master, dev);
+
+ return sprintf(buf, "%u\n", m->active_slot);
+}
+
+static ssize_t active_slot_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct lp8x4x_master *m = container_of(dev, struct lp8x4x_master, dev);
+ unsigned int active_slot = 0;
+ int err;
+
+ if (!buf)
+ return count;
+ if (0 == count)
+ return count;
+
+ err = kstrtouint(buf, 10, &active_slot);
+ if (err != 0 || active_slot > m->slot_count) {
+ dev_err(dev, "slot number is out of range 1..%u\n",
+ m->slot_count);
+ return count;
+ }
+
+ if (!active_slot) {
+ m->active_slot = 0;
+ iowrite8(0xff, m->switch_addr);
+ return count;
+ }
+
+ m->active_slot = active_slot;
+ iowrite8((1 << (m->active_slot - 1)) ^ 0xff, m->switch_addr);
+ return count;
+}
+
+static DEVICE_ATTR_RW(active_slot);
+
static struct attribute *master_dev_attrs[] = {
&dev_attr_slot_count.attr,
&dev_attr_rotary.attr,
&dev_attr_eeprom_write_enable.attr,
&dev_attr_dip.attr,
+ &dev_attr_active_slot.attr,
NULL,
};
ATTRIBUTE_GROUPS(master_dev);
@@ -181,6 +227,20 @@ static int __init lp8x4x_bus_probe(struct platform_device *pdev)
res = platform_get_resource(pdev, IORESOURCE_MEM, r++);
if (!res) {
+ dev_err(&pdev->dev, "Failed to get slot switch address\n");
+ err = -ENODEV;
+ goto err_free;
+ }
+
+ m->switch_addr = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(m->switch_addr)) {
+ dev_err(&pdev->dev, "Failed to ioremap switch address\n");
+ err = PTR_ERR(m->switch_addr);
+ goto err_free;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, r++);
+ if (!res) {
dev_err(&pdev->dev, "could not get slot count address\n");
err = -ENODEV;
goto err_free;
@@ -223,6 +283,9 @@ static int __init lp8x4x_bus_probe(struct platform_device *pdev)
dev_info(&pdev->dev, "found bus with up to %u slots\n", m->slot_count);
+ /* Disable serial communications until explicitly enabled */
+ iowrite8(0xff, m->switch_addr);
+
err = bus_register(&lp8x4x_bus_type);
if (err < 0) {
dev_err(&pdev->dev, "failed to register bus type\n");
--
1.8.4.2
^ permalink raw reply related [flat|nested] 148+ messages in thread
* [PATCH v4 18/21] misc: support for parallel slots in LP-8x4x
[not found] ` <1397668667-27328-1-git-send-email-ynvich@gmail.com>
` (9 preceding siblings ...)
2014-04-16 17:17 ` [PATCH v4 17/21] misc: support for serial slots in LP-8x4x Sergei Ianovich
@ 2014-04-16 17:17 ` Sergei Ianovich
[not found] ` <1397668667-27328-1-git-send-email-ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
11 siblings, 0 replies; 148+ messages in thread
From: Sergei Ianovich @ 2014-04-16 17:17 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel
Cc: Sergei Ianovich, Rob Herring, Pawel Moll, Mark Rutland,
Ian Campbell, Kumar Gala, Randy Dunlap, Arnd Bergmann,
Greg Kroah-Hartman, open list:OPEN FIRMWARE AND...,
open list:DOCUMENTATION
This patch enumerates parallel modules in expansion slots and exposes
model numbers via sysfs.
Signed-off-by: Sergei Ianovich <ynvich@gmail.com>
---
v3..v4
* move DTS binding to a different patch (8/21)
v2..v3
* no changes (except number 13/16 -> 18/21)
v0..v2
* use device tree
* use devm helpers where possible
.../devicetree/bindings/misc/lp8x4x-bus.txt | 9 ++
Documentation/misc-devices/lp8x4x_bus.txt | 8 ++
drivers/misc/lp8x4x_bus.c | 119 +++++++++++++++++++++
3 files changed, 136 insertions(+)
diff --git a/Documentation/devicetree/bindings/misc/lp8x4x-bus.txt b/Documentation/devicetree/bindings/misc/lp8x4x-bus.txt
index 24a8c62..75ac3b2 100644
--- a/Documentation/devicetree/bindings/misc/lp8x4x-bus.txt
+++ b/Documentation/devicetree/bindings/misc/lp8x4x-bus.txt
@@ -7,6 +7,7 @@ Required properties:
- reg: physical base addresses and region lengths of
* the rotary switch
+ * 8 plugable industrial IO slots
* the 8bit DIP switch
* the serial slot select register
* the slot count register
@@ -18,6 +19,14 @@ Example:
backplane {
compatible = "icpdas,backplane-lp8x4x";
reg = <0x0 0x2
+ 0x1000 0x10
+ 0x2000 0x10
+ 0x3000 0x10
+ 0x4000 0x10
+ 0x5000 0x10
+ 0x6000 0x10
+ 0x7000 0x10
+ 0x8000 0x10
0x9002 0x2
0x9004 0x2
0x9046 0x2>;
diff --git a/Documentation/misc-devices/lp8x4x_bus.txt b/Documentation/misc-devices/lp8x4x_bus.txt
index 7b86797..09380fd 100644
--- a/Documentation/misc-devices/lp8x4x_bus.txt
+++ b/Documentation/misc-devices/lp8x4x_bus.txt
@@ -28,6 +28,9 @@ into the device, they could be accessed using the 2nd PXA built-in UART port
(/dev/ttyS1). However, it seems that addresses are not processed by
the modules. So the parallel bus needs to select which slot is connected.
+Parallel modules allow much faster communication. There are accessed using
+IO memory through the FPGA. Their ports are exposed via sysfs.
+
SYSFS
-----
@@ -50,3 +53,8 @@ rotary
slot_count
RO - shows total number of expansion slots on the device
+
+/sys/bus/icpdas/devices/slot%02i:
+
+model
+ RO - shows expansion module model number
diff --git a/drivers/misc/lp8x4x_bus.c b/drivers/misc/lp8x4x_bus.c
index e805640..59dc767 100644
--- a/drivers/misc/lp8x4x_bus.c
+++ b/drivers/misc/lp8x4x_bus.c
@@ -23,6 +23,13 @@ MODULE_LICENSE("GPL");
MODULE_AUTHOR("Sergei Ianovich <ynvich@gmail.com>");
MODULE_DESCRIPTION("ICP DAS LP-8x4x parallel bus driver");
+struct lp8x4x_slot {
+ void *data_addr;
+ unsigned int model;
+ struct device dev;
+};
+
+#define LP8X4X_MAX_SLOT_COUNT 8
struct lp8x4x_master {
unsigned int slot_count;
void *count_addr;
@@ -31,9 +38,45 @@ struct lp8x4x_master {
struct gpio_desc *eeprom_nWE;
unsigned int active_slot;
void *switch_addr;
+ struct lp8x4x_slot slot[LP8X4X_MAX_SLOT_COUNT];
struct device dev;
};
+static unsigned char lp8x4x_model[256] = {
+ 0, 0, 0, 0x11, 0, 0x18, 0x13, 0x11,
+ 0x0e, 0x11, 0, 0, 0, 0x5a, 0x5b, 0x5c,
+ 0x3c, 0x44, 0x34, 0x3a, 0x39, 0x36, 0x37, 0x33,
+ 0x35, 0x40, 0x41, 0x42, 0x38, 0x3f, 0x32, 0x45,
+ 0xac, 0x70, 0x8e, 0x8e, 0x1e, 0x72, 0x90, 0x29,
+ 0x4a, 0x22, 0xd3, 0xd2, 0x28, 0x25, 0x2a, 0x29,
+ 0x48, 0x49, 0x5d, 0x1f, 0x20, 0x23, 0x24, 0x4d,
+ 0x3d, 0x3e, 0, 0, 0, 0, 0, 0,
+ 0, 0x78, 0x72, 0x2b, 0x5e, 0x5e, 0x36, 0xae,
+ 0x30, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0x5c, 0x5e, 0, 0x5e, 0, 0,
+ 0, 0x3b, 0, 0, 0, 0, 0, 0,
+ 0, 0x50, 0x2e, 0, 0x58, 0, 0, 0x43,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0x54, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0
+};
+
static int lp8x4x_match(struct device *dev, struct device_driver *drv)
{
return 1;
@@ -44,6 +87,26 @@ static struct bus_type lp8x4x_bus_type = {
.match = lp8x4x_match,
};
+static void lp8x4x_slot_release(struct device *dev)
+{
+}
+
+static ssize_t model_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct lp8x4x_slot *s = container_of(dev, struct lp8x4x_slot, dev);
+
+ return sprintf(buf, "%u\n", s->model + 8000);
+}
+
+static DEVICE_ATTR_RO(model);
+
+static struct attribute *slot_dev_attrs[] = {
+ &dev_attr_model.attr,
+ NULL,
+};
+ATTRIBUTE_GROUPS(slot_dev);
+
static void lp8x4x_master_release(struct device *dev)
{
struct lp8x4x_master *m = container_of(dev, struct lp8x4x_master, dev);
@@ -173,18 +236,50 @@ ATTRIBUTE_GROUPS(master_dev);
static void devm_lp8x4x_bus_release(struct device *dev, void *res)
{
struct lp8x4x_master *m = *(struct lp8x4x_master **)res;
+ struct lp8x4x_slot *s;
+ int i;
dev_dbg(dev, "releasing devices\n");
+ for (i = 0; i < LP8X4X_MAX_SLOT_COUNT; i++) {
+ s = &m->slot[i];
+ if (s->model)
+ device_unregister(&s->dev);
+ }
device_unregister(&m->dev);
bus_unregister(&lp8x4x_bus_type);
}
+static void __init lp8x4x_bus_probe_slot(struct lp8x4x_master *m, int i,
+ unsigned char model)
+{
+ struct lp8x4x_slot *s = &m->slot[i];
+ int err;
+
+ dev_info(&m->dev, "found %u in slot %i\n", 8000 + model, i + 1);
+
+ s->dev.bus = &lp8x4x_bus_type;
+ dev_set_name(&s->dev, "slot%02i", i + 1);
+ s->dev.parent = &m->dev;
+ s->dev.release = lp8x4x_slot_release;
+ s->dev.groups = slot_dev_groups;
+ s->model = model;
+
+ err = device_register(&s->dev);
+ if (err < 0) {
+ dev_err(&s->dev, "failed to register device\n");
+ s->model = 0;
+ return;
+ }
+}
+
static int __init lp8x4x_bus_probe(struct platform_device *pdev)
{
struct lp8x4x_master *m, **p;
struct resource *res;
int r = 0;
+ int i;
int err = 0;
+ unsigned int model;
m = kzalloc(sizeof(*m), GFP_KERNEL);
if (!m)
@@ -211,6 +306,23 @@ static int __init lp8x4x_bus_probe(struct platform_device *pdev)
goto err_free;
}
+ for (i = 0; i < LP8X4X_MAX_SLOT_COUNT; i++) {
+ res = platform_get_resource(pdev, IORESOURCE_MEM, r++);
+ if (!res) {
+ dev_err(&pdev->dev, "Failed to get slot %i address\n",
+ i);
+ err = -ENODEV;
+ goto err_free;
+ }
+
+ m->slot[i].data_addr = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(m->slot[i].data_addr)) {
+ dev_err(&pdev->dev, "Failed to ioremap slot %i\n", i);
+ err = PTR_ERR(m->slot[i].data_addr);
+ goto err_free;
+ }
+ }
+
res = platform_get_resource(pdev, IORESOURCE_MEM, r++);
if (!res) {
dev_err(&pdev->dev, "Failed to get DIP switch address\n");
@@ -305,6 +417,13 @@ static int __init lp8x4x_bus_probe(struct platform_device *pdev)
}
devres_add(&pdev->dev, p);
+ for (i = 0; i < LP8X4X_MAX_SLOT_COUNT; i++) {
+ model = lp8x4x_model[ioread8(m->slot[i].data_addr)];
+ if (!model)
+ continue;
+
+ lp8x4x_bus_probe_slot(m, i, model);
+ }
return 0;
err_bus:
--
1.8.4.2
^ permalink raw reply related [flat|nested] 148+ messages in thread
* Re: [PATCH v4 12/21] serial: support for 16550A serial ports on LP-8x4x
2014-04-16 17:17 ` [PATCH v4 12/21] serial: support for 16550A serial ports on LP-8x4x Sergei Ianovich
@ 2014-04-16 18:35 ` One Thousand Gnomes
2014-04-16 19:01 ` Sergei Ianovich
0 siblings, 1 reply; 148+ messages in thread
From: One Thousand Gnomes @ 2014-04-16 18:35 UTC (permalink / raw)
To: Sergei Ianovich
Cc: linux-kernel, linux-arm-kernel, Rob Herring, Pawel Moll,
Mark Rutland, Ian Campbell, Kumar Gala, Randy Dunlap,
Russell King, Greg Kroah-Hartman, Jiri Slaby, Grant Likely,
Heikki Krogerus, Arnd Bergmann, Paul Bolle, Stefan Seyfried,
James Cameron, open list:OPEN FIRMWARE AND...,
open list:DOCUMENTATION, open list:SERIAL DRIVERS
> + baud = uart_get_baud_rate(port, termios, old,
> + port->uartclk / 16 / 0xffff,
> + port->uartclk / 16);
> + switch (baud) {
> + case 2400:
> + len |= 1;
> + break;
> + case 4800:
> + len |= 2;
> + break;
> + case 19200:
> + len |= 4;
> + break;
> + case 38400:
> + len |= 5;
> + break;
> + case 57600:
> + len |= 6;
> + break;
> + case 115200:
> + len |= 7;
> + break;
> + case 9600:
> + default:
> + len |= 3;
> + break;
> + };
Some explanation of this would be useful - eg why is it set to 7 for
115200 baud and 3 for 115201 baud ?
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH v4 13/21] misc: support for LP-8x4x custom parallel bus
2014-04-16 17:17 ` [PATCH v4 13/21] misc: support for LP-8x4x custom parallel bus Sergei Ianovich
@ 2014-04-16 18:41 ` One Thousand Gnomes
2014-04-16 18:42 ` Arnd Bergmann
2014-04-16 19:53 ` Sergei Ianovich
0 siblings, 2 replies; 148+ messages in thread
From: One Thousand Gnomes @ 2014-04-16 18:41 UTC (permalink / raw)
To: Sergei Ianovich
Cc: linux-kernel, linux-arm-kernel, Rob Herring, Pawel Moll,
Mark Rutland, Ian Campbell, Kumar Gala, Randy Dunlap,
Russell King, Arnd Bergmann, Greg Kroah-Hartman, Grant Likely,
Heikki Krogerus, open list:OPEN FIRMWARE AND...,
open list:DOCUMENTATION
On Wed, 16 Apr 2014 21:17:18 +0400
Sergei Ianovich <ynvich@gmail.com> wrote:
> This patch implements probing for the bus and reporting the number
> of available expansion slots.
This appears to be a bus not a misc device. I don't think it belongs in
misc. As you've got devices on this bus (or nailed into the 'bus' driver)
perhaps this belongs as drivers/platform/lp8x4x or similar with any
specific drivers split out - or even drivers/lp8x4x if there will be more
of them and more than one platform using it ?
Alan
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH v4 13/21] misc: support for LP-8x4x custom parallel bus
2014-04-16 18:41 ` One Thousand Gnomes
@ 2014-04-16 18:42 ` Arnd Bergmann
2014-04-16 20:29 ` One Thousand Gnomes
2014-04-16 19:53 ` Sergei Ianovich
1 sibling, 1 reply; 148+ messages in thread
From: Arnd Bergmann @ 2014-04-16 18:42 UTC (permalink / raw)
To: One Thousand Gnomes
Cc: Sergei Ianovich, linux-kernel, linux-arm-kernel, Rob Herring,
Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala, Randy Dunlap,
Russell King, Greg Kroah-Hartman, Grant Likely, Heikki Krogerus,
open list:OPEN FIRMWARE AND..., open list:DOCUMENTATION
On Wednesday 16 April 2014 19:41:09 One Thousand Gnomes wrote:
> On Wed, 16 Apr 2014 21:17:18 +0400
> Sergei Ianovich <ynvich@gmail.com> wrote:
>
> > This patch implements probing for the bus and reporting the number
> > of available expansion slots.
>
> This appears to be a bus not a misc device. I don't think it belongs in
> misc. As you've got devices on this bus (or nailed into the 'bus' driver)
> perhaps this belongs as drivers/platform/lp8x4x or similar with any
> specific drivers split out - or even drivers/lp8x4x if there will be more
> of them and more than one platform using it ?
We have drivers/bus now, I think it could fit well in there.
Arnd
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH v4 12/21] serial: support for 16550A serial ports on LP-8x4x
2014-04-16 18:35 ` One Thousand Gnomes
@ 2014-04-16 19:01 ` Sergei Ianovich
2014-04-16 20:00 ` One Thousand Gnomes
0 siblings, 1 reply; 148+ messages in thread
From: Sergei Ianovich @ 2014-04-16 19:01 UTC (permalink / raw)
To: One Thousand Gnomes
Cc: linux-kernel, linux-arm-kernel, Rob Herring, Pawel Moll,
Mark Rutland, Ian Campbell, Kumar Gala, Randy Dunlap,
Russell King, Greg Kroah-Hartman, Jiri Slaby, Grant Likely,
Heikki Krogerus, Arnd Bergmann, Paul Bolle, Stefan Seyfried,
James Cameron, devicetree, linux-doc, linux-serial
One Thousand Gnomes <gnomes@lxorguk.ukuu.org.uk> wrote:
>> + baud = uart_get_baud_rate(port, termios, old,
>> + port->uartclk / 16 / 0xffff,
>> + port->uartclk / 16);
>> + switch (baud) {
>> + case 2400:
>> + len |= 1;
>> + break;
>> + case 4800:
>> + len |= 2;
>> + break;
>> + case 19200:
>> + len |= 4;
>> + break;
>> + case 38400:
>> + len |= 5;
>> + break;
>> + case 57600:
>> + len |= 6;
>> + break;
>> + case 115200:
>> + len |= 7;
>> + break;
>> + case 9600:
>> + default:
>> + len |= 3;
>> + break;
>> + };
>
>Some explanation of this would be useful - eg why is it set to 7 for
>115200 baud and 3 for 115201 baud ?
I am not related to the device vendor in any way, so please take my answers for what they are worth.
It seems that there is not enough pins to properly connect the chips to the memory bus and just you the standard 8250 UART driver. Instead, clock divisor is set using this register.
So, if you know you're asking for (115200) you get it. If you don't or guess (115201), you get the default 9600.
This is a policy, it may not be the right way to write a driver, but it is cheap and it works.
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH v4 13/21] misc: support for LP-8x4x custom parallel bus
2014-04-16 18:41 ` One Thousand Gnomes
2014-04-16 18:42 ` Arnd Bergmann
@ 2014-04-16 19:53 ` Sergei Ianovich
1 sibling, 0 replies; 148+ messages in thread
From: Sergei Ianovich @ 2014-04-16 19:53 UTC (permalink / raw)
To: One Thousand Gnomes
Cc: linux-kernel, linux-arm-kernel, Rob Herring, Pawel Moll,
Mark Rutland, Ian Campbell, Kumar Gala, Randy Dunlap,
Russell King, Arnd Bergmann, Greg Kroah-Hartman, Grant Likely,
Heikki Krogerus, devicetree, linux-doc
One Thousand Gnomes <gnomes@lxorguk.ukuu.org.uk> wrote:
>On Wed, 16 Apr 2014 21:17:18 +0400
>Sergei Ianovich <ynvich@gmail.com> wrote:
>
>> This patch implements probing for the bus and reporting the number
>> of available expansion slots.
>
>This appears to be a bus not a misc device. I don't think it belongs in
>misc. As you've got devices on this bus (or nailed into the 'bus'
>driver)
>perhaps this belongs as drivers/platform/lp8x4x or similar with any
>specific drivers split out - or even drivers/lp8x4x if there will be
>more
>of them and more than one platform using it ?
Thanks again for responding. I don't have a clear idea about proper code organization concering this bus.
The total number of possible bus devices is quite large, around 30. Half of them would take less than 10 extra lines to get support. The rest is more complicated.
LP-8x4x has several features that would require a misc device anyway. It has a rotary switch which isn't an input device, because it produces no interrupts. The device also has a similar DIP switch. In addition, it acts as a kind of RS-485-port-to-multi-RS-232-ports logical bridge. It has a multiplexer which allows to talk to several serial modules which support a custom protocol designed for RS-485 using a RS-232 port.
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH v4 12/21] serial: support for 16550A serial ports on LP-8x4x
2014-04-16 19:01 ` Sergei Ianovich
@ 2014-04-16 20:00 ` One Thousand Gnomes
[not found] ` <20140416210051.01bef49e-mUKnrFFms3BCCTY1wZZT65JpZx93mCW/@public.gmane.org>
0 siblings, 1 reply; 148+ messages in thread
From: One Thousand Gnomes @ 2014-04-16 20:00 UTC (permalink / raw)
To: Sergei Ianovich
Cc: linux-kernel, linux-arm-kernel, Rob Herring, Pawel Moll,
Mark Rutland, Ian Campbell, Kumar Gala, Randy Dunlap,
Russell King, Greg Kroah-Hartman, Jiri Slaby, Grant Likely,
Heikki Krogerus, Arnd Bergmann, Paul Bolle, Stefan Seyfried,
James Cameron, devicetree, linux-doc, linux-serial
On Wed, 16 Apr 2014 23:01:47 +0400
Sergei Ianovich <ynvich@gmail.com> wrote:
> One Thousand Gnomes <gnomes@lxorguk.ukuu.org.uk> wrote:
> >> + baud = uart_get_baud_rate(port, termios, old,
> >> + port->uartclk / 16 / 0xffff,
> >> + port->uartclk / 16);
> >> + switch (baud) {
> >> + case 2400:
> >> + len |= 1;
> >> + break;
> >> + case 4800:
> >> + len |= 2;
> >> + break;
> >> + case 19200:
> >> + len |= 4;
> >> + break;
> >> + case 38400:
> >> + len |= 5;
> >> + break;
> >> + case 57600:
> >> + len |= 6;
> >> + break;
> >> + case 115200:
> >> + len |= 7;
> >> + break;
> >> + case 9600:
> >> + default:
> >> + len |= 3;
> >> + break;
> >> + };
> >
> >Some explanation of this would be useful - eg why is it set to 7 for
> >115200 baud and 3 for 115201 baud ?
>
> I am not related to the device vendor in any way, so please take my answers for what they are worth.
>
> It seems that there is not enough pins to properly connect the chips to the memory bus and just you the standard 8250 UART driver. Instead, clock divisor is set using this register.
>
> So, if you know you're asking for (115200) you get it. If you don't or guess (115201), you get the default 9600.
Thats not quite what the code actually implements though.
> This is a policy, it may not be the right way to write a driver, but it is cheap and it works.
If thats how the hardware works and only supports a few fixed rates then
fine, but for default: you need to actually update he baudrate in the
passed termios struct so that the userspace knows its request was not
matched.
Take a look how the standard 8250 termios does it.
Also looking at this and some of the other serial bits I see no
dependencies on the problematic DMA driver, so does that mean you've got
a set of pieces that can be submitted anyway while the DMA driver
discussion continues ?
Alan
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH v4 13/21] misc: support for LP-8x4x custom parallel bus
2014-04-16 18:42 ` Arnd Bergmann
@ 2014-04-16 20:29 ` One Thousand Gnomes
0 siblings, 0 replies; 148+ messages in thread
From: One Thousand Gnomes @ 2014-04-16 20:29 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Sergei Ianovich, linux-kernel, linux-arm-kernel, Rob Herring,
Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala, Randy Dunlap,
Russell King, Greg Kroah-Hartman, Grant Likely, Heikki Krogerus,
open list:OPEN FIRMWARE AND..., open list:DOCUMENTATION
On Wed, 16 Apr 2014 20:42:39 +0200
Arnd Bergmann <arnd@arndb.de> wrote:
> On Wednesday 16 April 2014 19:41:09 One Thousand Gnomes wrote:
> > On Wed, 16 Apr 2014 21:17:18 +0400
> > Sergei Ianovich <ynvich@gmail.com> wrote:
> >
> > > This patch implements probing for the bus and reporting the number
> > > of available expansion slots.
> >
> > This appears to be a bus not a misc device. I don't think it belongs in
> > misc. As you've got devices on this bus (or nailed into the 'bus' driver)
> > perhaps this belongs as drivers/platform/lp8x4x or similar with any
> > specific drivers split out - or even drivers/lp8x4x if there will be more
> > of them and more than one platform using it ?
>
> We have drivers/bus now, I think it could fit well in there.
Agreed
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH v4 12/21] serial: support for 16550A serial ports on LP-8x4x
[not found] ` <20140416210051.01bef49e-mUKnrFFms3BCCTY1wZZT65JpZx93mCW/@public.gmane.org>
@ 2014-04-16 20:32 ` Sergei Ianovich
0 siblings, 0 replies; 148+ messages in thread
From: Sergei Ianovich @ 2014-04-16 20:32 UTC (permalink / raw)
To: One Thousand Gnomes
Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Rob Herring,
Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala, Randy Dunlap,
Russell King, Greg Kroah-Hartman, Jiri Slaby, Grant Likely,
Heikki Krogerus, Arnd Bergmann, Paul Bolle, Stefan Seyfried,
James Cameron, devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-doc-u79uwXL29TY76Z2rM5mHXA,
linux-serial-u79uwXL29TY76Z2rM5mHXA
One Thousand Gnomes <gnomes-qBU/x9rampVanCEyBjwyrvXRex20P6io@public.gmane.org> wrote:
>On Wed, 16 Apr 2014 23:01:47 +0400
>Sergei Ianovich <ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
>
>> One Thousand Gnomes <gnomes-qBU/x9rampVanCEyBjwyrvXRex20P6io@public.gmane.org> wrote:
>> >> + baud = uart_get_baud_rate(port, termios, old,
>> >> + port->uartclk / 16 / 0xffff,
>> >> + port->uartclk / 16);
>> >> + switch (baud) {
>> >> + case 2400:
>> >> + len |= 1;
>> >> + break;
>> >> + case 4800:
>> >> + len |= 2;
>> >> + break;
>> >> + case 19200:
>> >> + len |= 4;
>> >> + break;
>> >> + case 38400:
>> >> + len |= 5;
>> >> + break;
>> >> + case 57600:
>> >> + len |= 6;
>> >> + break;
>> >> + case 115200:
>> >> + len |= 7;
>> >> + break;
>> >> + case 9600:
>> >> + default:
>> >> + len |= 3;
>> >> + break;
>> >> + };
>> >
>> >Some explanation of this would be useful - eg why is it set to 7 for
>> >115200 baud and 3 for 115201 baud ?
>>
>> I am not related to the device vendor in any way, so please take my
>answers for what they are worth.
>>
>> It seems that there is not enough pins to properly connect the chips
>to the memory bus and just you the standard 8250 UART driver. Instead,
>clock divisor is set using this register.
>>
>> So, if you know you're asking for (115200) you get it. If you don't
>or guess (115201), you get the default 9600.
>
>Thats not quite what the code actually implements though.
>> This is a policy, it may not be the right way to write a driver, but
>it is cheap and it works.
>If thats how the hardware works and only supports a few fixed rates
>then
>fine, but for default: you need to actually update he baudrate in the
>passed termios struct so that the userspace knows its request was not
>matched.
>
>Take a look how the standard 8250 termios does it.
I will. I've tested the driver by setting termios from userspace. There was no chance to ask for arbitrary rate, so I didn't think much about this case.
>Also looking at this and some of the other serial bits I see no
>dependencies on the problematic DMA driver, so does that mean you've
>got
>a set of pieces that can be submitted anyway while the DMA driver
>discussion continues ?
Yes, getting each peace in will reduce the support burden.
The degree of interdependence varies from feature to feature. rtc, mtd, irq and serial could be taken independently.
The main patch is #8. It requires #1-7. The is problem with DMA is one of policy, not technical one. It is explained in #6-7 in details.
Everything in the misc depends on bus. But the bus is very simple. There is even no interrupts.
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH v4 08/21] ARM: pxa27x: device tree support ICP DAS LP-8x4x
2014-04-16 17:17 ` [PATCH v4 08/21] ARM: pxa27x: device tree support ICP DAS LP-8x4x Sergei Ianovich
@ 2014-04-17 10:54 ` Daniel Mack
0 siblings, 0 replies; 148+ messages in thread
From: Daniel Mack @ 2014-04-17 10:54 UTC (permalink / raw)
To: Sergei Ianovich, linux-kernel, linux-arm-kernel
Cc: Arnd Bergmann, Rob Herring, Pawel Moll, Mark Rutland,
Ian Campbell, Kumar Gala, Randy Dunlap, Russell King, Eric Miao,
Haojian Zhuang, Thierry Reding, Florian Vaussard,
Jonathan Cameron, Shawn Guo, Andrew Lunn, Silvio F,
Heikki Krogerus, open list:OPEN FIRMWARE AND..., open, list,
DOCUMENTATION
On 04/16/2014 07:17 PM, Sergei Ianovich wrote:
> diff --git a/arch/arm/mach-pxa/pxa27x-dt.c b/arch/arm/mach-pxa/pxa27x-dt.c
> new file mode 100644
> index 0000000..865cf46
> --- /dev/null
> +++ b/arch/arm/mach-pxa/pxa27x-dt.c
> @@ -0,0 +1,64 @@
> +/*
> + * linux/arch/arm/mach-pxa/pxa27x-dt.c
> + *
> + * Copyright (C) 2013 Sergei Ianovich
> + *
> + * based mostly on linux/arch/arm/mach-pxa/pxa-dt.c by Daniel Mack
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * publishhed by the Free Software Foundation.
> + */
> +
> +#include <linux/irq.h>
> +#include <linux/irqdomain.h>
> +#include <linux/of_irq.h>
> +#include <linux/of_platform.h>
> +#include <asm/io.h>
> +#include <asm/mach/arch.h>
> +#include <asm/mach/time.h>
> +#include <mach/irqs.h>
> +#include <mach/pxa27x.h>
> +
> +#include "generic.h"
> +
> +#ifdef CONFIG_PXA27x
> +static const struct of_dev_auxdata pxa27x_auxdata_lookup[] __initconst = {
> + OF_DEV_AUXDATA("mrvl,pxa-uart", 0x40100000, "pxa2xx-uart.0", NULL),
> + OF_DEV_AUXDATA("mrvl,pxa-uart", 0x40200000, "pxa2xx-uart.1", NULL),
> + OF_DEV_AUXDATA("mrvl,pxa-uart", 0x40700000, "pxa2xx-uart.2", NULL),
> + OF_DEV_AUXDATA("mrvl,pxa-uart", 0x41600000, "pxa2xx-uart.3", NULL),
> + OF_DEV_AUXDATA("marvell,pxa-mmc", 0x41100000, "pxa2xx-mci.0", NULL),
> + OF_DEV_AUXDATA("intel,pxa27x-gpio", 0x40e00000, "pxa27x-gpio", NULL),
> + OF_DEV_AUXDATA("marvell,pxa-ohci", 0x4c000000, "pxa27x-ohci", NULL),
> + OF_DEV_AUXDATA("mrvl,pxa-i2c", 0x40301680, "pxa2xx-i2c.0", NULL),
> + {}
> +};
This patch should be split into a generic pxa27x part and one for your
platform. The former should also include the changes to pxa27x.dtsi.
Thanks,
Daniel
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH v4 10/21] mtd: support BB SRAM on ICP DAS LP-8x4x
2014-04-16 17:17 ` [PATCH v4 10/21] mtd: support BB SRAM " Sergei Ianovich
@ 2014-04-30 17:21 ` Brian Norris
2014-04-30 17:35 ` ООО "ЭлектроПлюс"
[not found] ` <1397668667-27328-4-git-send-email-ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
1 sibling, 1 reply; 148+ messages in thread
From: Brian Norris @ 2014-04-30 17:21 UTC (permalink / raw)
To: Sergei Ianovich
Cc: linux-kernel, linux-arm-kernel, Rob Herring, Pawel Moll,
Mark Rutland, Ian Campbell, Kumar Gala, Randy Dunlap,
Russell King, David Woodhouse, Grant Likely, Heikki Krogerus,
Lee Jones, Artem Bityutskiy, Robert Jarzmik, Michael Opdenacker,
open list:OPEN FIRMWARE AND..., open list:DOCUMENTATION,
open list:MEMORY TECHNOLOGY...
Hi Sergei,
A few more small comments.
On Wed, Apr 16, 2014 at 09:17:15PM +0400, Sergei Ianovich wrote:
> This provides an MTD device driver for 512kB of battery backed up SRAM
> on ICPDAS LP-8X4X programmable automation controllers.
>
> SRAM chip is connected via FPGA and is not accessible without a driver,
> unlike flash memory which is wired to CPU MMU.
>
> This SRAM becomes an excellent persisent storage of volatile process
> data like counter values and sensor statuses. Storing those data in
> flash or mmc card is not a viable solution.
>
> Signed-off-by: Sergei Ianovich <ynvich@gmail.com>
> Reviewed-by: Brian Norris <computersforpeace@gmail.com>
> ---
> v3..v4 for Brian Norris 'Reviewed-by'
> * add doc file for DT binding
> * move DTS binding to a different patch (8/21)
> * drop unused include directive
> * drop safely unused callback
> * drop non-default partion probe types
> * drop duplicate error checks
> * drop duplicate error reporting
> * fixed error message on MTD registeration
> * fixed module removal routine
Thanks for the updates. This patch looks pretty good to me.
> v2..v3
> * no changes (except number 08/16 -> 10/21)
>
> v0..v2
> * use device tree
> * use devm helpers where possible
>
> .../devicetree/bindings/mtd/sram-lp8x4x.txt | 22 +++
> arch/arm/configs/lp8x4x_defconfig | 1 +
> drivers/mtd/devices/Kconfig | 14 ++
> drivers/mtd/devices/Makefile | 1 +
> drivers/mtd/devices/sram_lp8x4x.c | 204 +++++++++++++++++++++
> 5 files changed, 242 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/mtd/sram-lp8x4x.txt
> create mode 100644 drivers/mtd/devices/sram_lp8x4x.c
>
> diff --git a/Documentation/devicetree/bindings/mtd/sram-lp8x4x.txt b/Documentation/devicetree/bindings/mtd/sram-lp8x4x.txt
> new file mode 100644
> index 0000000..8b1e864
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mtd/sram-lp8x4x.txt
> @@ -0,0 +1,22 @@
> +512kB battery backed up SRAM on LP-8x4x industrial computers
> +
> +Required properties:
> +- compatible : should be "icpdas,sram-lp8x4x"
> +
> +- reg: physical base addresses and region lengths of
> + * IO memory range
> + * SRAM page selector
Are these region types pretty static for this type of hardware? If not,
it helps to have a reg-names property in the DT, when there are 2 or
more register resources.
> +- eeprom-gpios : should point to active-low write enable GPIO
I'm curious: your driver doesn't actually utilize this binding. Is this
intentional? Is it actually optional? (I note that the example DT below
doesn't have this property...)
> +
> +SRAM chip is connected via FPGA and is not accessible without a driver,
> +unlike flash memory which is wired to CPU MMU. Driver is essentially
> +an address translation routine.
> +
> +Example:
> +
> + sram@a000 {
> + compatible = "icpdas,sram-lp8x4x";
> + reg = <0xa000 0x1000
> + 0x901e 0x1>;
> + };
> diff --git a/arch/arm/configs/lp8x4x_defconfig b/arch/arm/configs/lp8x4x_defconfig
> index d60e37a..17a4e6f 100644
> --- a/arch/arm/configs/lp8x4x_defconfig
> +++ b/arch/arm/configs/lp8x4x_defconfig
> @@ -57,6 +57,7 @@ CONFIG_MTD_CFI_ADV_OPTIONS=y
> CONFIG_MTD_CFI_GEOMETRY=y
> CONFIG_MTD_CFI_INTELEXT=y
> CONFIG_MTD_PHYSMAP_OF=y
> +CONFIG_MTD_SRAM_LP8X4X=y
> CONFIG_PROC_DEVICETREE=y
> CONFIG_BLK_DEV_LOOP=y
> CONFIG_BLK_DEV_LOOP_MIN_COUNT=2
I can't take the defconfig update via MTD; it will need to go via the
appropriate ARM tree (arm-soc?). So this hunk needs to move to another
patch.
> diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig
> index 1210bc2..fc8552b 100644
> --- a/drivers/mtd/devices/Kconfig
> +++ b/drivers/mtd/devices/Kconfig
> @@ -225,4 +225,18 @@ config BCH_CONST_T
> default 4
> endif
>
> +config MTD_SRAM_LP8X4X
> + tristate "SRAM on ICPDAS LP-8X4X"
> + depends on OF && ARCH_PXA
> + ---help---
> + This provides an MTD device driver for 512kiB of battery backed up SRAM
> + on ICPDAS LP-8X4X programmable automation controllers.
> +
> + SRAM chip is connected via FPGA and is not accessible without a driver,
> + unlike flash memory which is wired to CPU MMU.
> +
> + Say N, unless you plan to run this kernel on LP-8X4X.
> +
> + If you say M, the module will be called sram_lp8x4x.
> +
> endmenu
> diff --git a/drivers/mtd/devices/Makefile b/drivers/mtd/devices/Makefile
> index c68868f..a7d86e2 100644
> --- a/drivers/mtd/devices/Makefile
> +++ b/drivers/mtd/devices/Makefile
> @@ -17,6 +17,7 @@ obj-$(CONFIG_MTD_SPEAR_SMI) += spear_smi.o
> obj-$(CONFIG_MTD_SST25L) += sst25l.o
> obj-$(CONFIG_MTD_BCM47XXSFLASH) += bcm47xxsflash.o
> obj-$(CONFIG_MTD_ST_SPI_FSM) += st_spi_fsm.o
> +obj-$(CONFIG_MTD_SRAM_LP8X4X) += sram_lp8x4x.o
>
>
> CFLAGS_docg3.o += -I$(src)
> diff --git a/drivers/mtd/devices/sram_lp8x4x.c b/drivers/mtd/devices/sram_lp8x4x.c
> new file mode 100644
> index 0000000..4cfa70b
> --- /dev/null
> +++ b/drivers/mtd/devices/sram_lp8x4x.c
> @@ -0,0 +1,204 @@
> +/*
> + * linux/drivers/mtd/devices/lp8x4x_sram.c
> + *
> + * MTD Driver for SRAM on ICPDAS LP-8x4x
> + * Copyright (C) 2013 Sergei Ianovich <ynvich@gmail.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation or any later version.
> + */
> +
> +#include <linux/init.h>
> +#include <linux/io.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/mtd/map.h>
> +#include <linux/mtd/mtd.h>
> +#include <linux/mtd/partitions.h>
> +#include <linux/platform_device.h>
> +#include <linux/of_device.h>
> +#include <linux/slab.h>
> +#include <linux/string_helpers.h>
> +#include <linux/types.h>
> +
> +struct lp8x4x_sram_info {
> + void __iomem *bank;
> + void __iomem *virt;
> + struct mutex lock;
> + unsigned active_bank;
> + struct mtd_info mtd;
> +};
> +
> +static int
> +lp8x4x_sram_erase(struct mtd_info *mtd, struct erase_info *instr)
> +{
> + struct lp8x4x_sram_info *info = mtd->priv;
> + unsigned bank = instr->addr >> 11;
> + unsigned offset = (instr->addr & 0x7ff) << 1;
> + loff_t i;
> +
> + mutex_lock(&info->lock);
> + if (unlikely(bank != info->active_bank)) {
> + info->active_bank = bank;
> + iowrite8(bank, info->bank);
> + }
> + for (i = 0; i < instr->len; i++) {
> + iowrite8(0xff, info->virt + offset);
> + offset += 2;
> + if (unlikely(offset == 0)) {
> + info->active_bank++;
> + iowrite8(info->active_bank, info->bank);
> + }
> + }
> + mutex_unlock(&info->lock);
> + instr->state = MTD_ERASE_DONE;
> + mtd_erase_callback(instr);
> +
> + return 0;
> +}
> +
> +static int
> +lp8x4x_sram_write(struct mtd_info *mtd, loff_t to, size_t len,
> + size_t *retlen, const u_char *b)
> +{
> + struct lp8x4x_sram_info *info = mtd->priv;
> + unsigned bank = to >> 11;
> + unsigned offset = (to & 0x7ff) << 1;
> + loff_t i;
> +
> + mutex_lock(&info->lock);
> + if (unlikely(bank != info->active_bank)) {
> + info->active_bank = bank;
> + iowrite8(bank, info->bank);
> + }
> + for (i = 0; i < len; i++) {
> + iowrite8(b[i], info->virt + offset);
> + offset += 2;
> + if (unlikely(offset == 0)) {
> + info->active_bank++;
> + iowrite8(info->active_bank, info->bank);
> + }
> + }
> + mutex_unlock(&info->lock);
> + *retlen = len;
> + return 0;
> +}
> +
> +static int
> +lp8x4x_sram_read(struct mtd_info *mtd, loff_t from, size_t len,
> + size_t *retlen, u_char *b)
> +{
> + struct lp8x4x_sram_info *info = mtd->priv;
> + unsigned bank = from >> 11;
> + unsigned offset = (from & 0x7ff) << 1;
> + loff_t i;
> +
> + mutex_lock(&info->lock);
> + if (unlikely(bank != info->active_bank)) {
> + info->active_bank = bank;
> + iowrite8(bank, info->bank);
> + }
> + for (i = 0; i < len; i++) {
> + b[i] = ioread8(info->virt + offset);
> + offset += 2;
> + if (unlikely(offset == 0)) {
> + info->active_bank++;
> + iowrite8(info->active_bank, info->bank);
> + }
> + }
> + mutex_unlock(&info->lock);
> + *retlen = len;
> + return 0;
> +}
> +
> +static struct of_device_id of_flash_match[] = {
> + {
> + .compatible = "icpdas,sram-lp8x4x",
> + },
> + { },
> +};
> +MODULE_DEVICE_TABLE(of, of_flash_match);
> +
> +static int
> +lp8x4x_sram_probe(struct platform_device *pdev)
> +{
> + const struct of_device_id *match;
> + struct lp8x4x_sram_info *info;
> + struct resource *res_virt, *res_bank;
> + char sz_str[16];
> + struct mtd_part_parser_data ppdata;
> + int err = 0;
> +
> + match = of_match_device(of_flash_match, &pdev->dev);
> + if (!match)
> + return -EINVAL;
Does this of_match_device() serve any particular purpose? Your driver
already matches against these IDs, and you're not actually retrieving
any of-data from the match, so this looks redundant.
> +
> + info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
> + if (!info)
> + return -ENOMEM;
> +
> + res_virt = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> + info->virt = devm_ioremap_resource(&pdev->dev, res_virt);
> + if (IS_ERR(info->virt))
> + return PTR_ERR(info->virt);
> +
> + res_bank = platform_get_resource(pdev, IORESOURCE_MEM, 1);
> + info->bank = devm_ioremap_resource(&pdev->dev, res_bank);
> + if (IS_ERR(info->bank))
> + return PTR_ERR(info->bank);
> +
> + info->mtd.priv = info;
> + info->mtd.name = "SRAM";
Are you absolutely sure there is only ever a single SRAM device on a
given system? Because otherwise, you will get redundantly-named MTD's.
If the answer is no, you might consider a unique naming scheme.
> + info->mtd.type = MTD_RAM;
> + info->mtd.flags = MTD_CAP_RAM;
> + info->mtd.size = resource_size(res_virt) << 7;
> + info->mtd.erasesize = 512;
> + info->mtd.writesize = 4;
> + info->mtd._erase = lp8x4x_sram_erase;
> + info->mtd._write = lp8x4x_sram_write;
> + info->mtd._read = lp8x4x_sram_read;
> + info->mtd.owner = THIS_MODULE;
> +
> + mutex_init(&info->lock);
> + iowrite8(info->active_bank, info->bank);
> + platform_set_drvdata(pdev, info);
> +
> + ppdata.of_node = pdev->dev.of_node;
> + err = mtd_device_parse_register(&info->mtd, NULL, &ppdata,
> + NULL, 0);
> +
> + if (err < 0) {
> + dev_err(&pdev->dev, "failed to register MTD\n");
> + return err;
> + }
> +
> + string_get_size(info->mtd.size, STRING_UNITS_2, sz_str,
> + sizeof(sz_str));
> + dev_info(&pdev->dev, "using %s SRAM on LP-8X4X as %s\n", sz_str,
> + dev_name(&info->mtd.dev));
> + return 0;
> +}
> +
> +static int
> +lp8x4x_sram_remove(struct platform_device *dev)
> +{
> + struct lp8x4x_sram_info *info = platform_get_drvdata(dev);
> + return mtd_device_unregister(&info->mtd);
> +}
> +
> +static struct platform_driver lp8x4x_sram_driver = {
> + .driver = {
> + .name = "sram-lp8x4x",
> + .owner = THIS_MODULE,
> + .of_match_table = of_flash_match,
> + },
> + .probe = lp8x4x_sram_probe,
> + .remove = lp8x4x_sram_remove,
> +};
> +
> +module_platform_driver(lp8x4x_sram_driver);
> +
> +MODULE_LICENSE("GPL");
> +MODULE_AUTHOR("Sergei Ianovich <ynvich@gmail.com>");
> +MODULE_DESCRIPTION("MTD driver for SRAM on ICPDAS LP-8x4x");
Thanks,
Brian
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH v4 10/21] mtd: support BB SRAM on ICP DAS LP-8x4x
2014-04-30 17:21 ` Brian Norris
@ 2014-04-30 17:35 ` ООО "ЭлектроПлюс"
0 siblings, 0 replies; 148+ messages in thread
From: ООО "ЭлектроПлюс" @ 2014-04-30 17:35 UTC (permalink / raw)
To: Brian Norris
Cc: linux-kernel, linux-arm-kernel, Rob Herring, Pawel Moll,
Mark Rutland, Ian Campbell, Kumar Gala, Randy Dunlap,
Russell King, David Woodhouse, Grant Likely, Heikki Krogerus,
Lee Jones, Artem Bityutskiy, Robert Jarzmik, Michael Opdenacker,
open list:OPEN FIRMWARE AND..., open list:DOCUMENTATION,
open list:MEMORY TECHNOLOGY...
Hi Brian,
On Wed, 2014-04-30 at 10:21 -0700, Brian Norris wrote:
> A few more small comments.
>
> On Wed, Apr 16, 2014 at 09:17:15PM +0400, Sergei Ianovich wrote:
> > +++ b/Documentation/devicetree/bindings/mtd/sram-lp8x4x.txt
> > @@ -0,0 +1,22 @@
> > +512kB battery backed up SRAM on LP-8x4x industrial computers
> > +
> > +Required properties:
> > +- compatible : should be "icpdas,sram-lp8x4x"
> > +
> > +- reg: physical base addresses and region lengths of
> > + * IO memory range
> > + * SRAM page selector
>
> Are these region types pretty static for this type of hardware? If not,
> it helps to have a reg-names property in the DT, when there are 2 or
> more register resources.
The regions are fixed. The addresses are hard-wired.
> > +- eeprom-gpios : should point to active-low write enable GPIO
>
> I'm curious: your driver doesn't actually utilize this binding. Is this
> intentional? Is it actually optional? (I note that the example DT below
> doesn't have this property...)
Thanks for noticing. It's an artifact of copy-paste. I'll drop this.
> > +++ b/arch/arm/configs/lp8x4x_defconfig
> > @@ -57,6 +57,7 @@ CONFIG_MTD_CFI_ADV_OPTIONS=y
> > CONFIG_MTD_CFI_GEOMETRY=y
> > CONFIG_MTD_CFI_INTELEXT=y
> > CONFIG_MTD_PHYSMAP_OF=y
> > +CONFIG_MTD_SRAM_LP8X4X=y
> > CONFIG_PROC_DEVICETREE=y
> > CONFIG_BLK_DEV_LOOP=y
> > CONFIG_BLK_DEV_LOOP_MIN_COUNT=2
>
> I can't take the defconfig update via MTD; it will need to go via the
> appropriate ARM tree (arm-soc?). So this hunk needs to move to another
> patch.
Sure. I'll remove this chunk and put it into main device patch.
> > + match = of_match_device(of_flash_match, &pdev->dev);
> > + if (!match)
> > + return -EINVAL;
>
> Does this of_match_device() serve any particular purpose? Your driver
> already matches against these IDs, and you're not actually retrieving
> any of-data from the match, so this looks redundant.
Point taken, I'll drop this.
> > +
> > + info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
> > + if (!info)
> > + return -ENOMEM;
> > +
> > + res_virt = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > + info->virt = devm_ioremap_resource(&pdev->dev, res_virt);
> > + if (IS_ERR(info->virt))
> > + return PTR_ERR(info->virt);
> > +
> > + res_bank = platform_get_resource(pdev, IORESOURCE_MEM, 1);
> > + info->bank = devm_ioremap_resource(&pdev->dev, res_bank);
> > + if (IS_ERR(info->bank))
> > + return PTR_ERR(info->bank);
> > +
> > + info->mtd.priv = info;
> > + info->mtd.name = "SRAM";
>
> Are you absolutely sure there is only ever a single SRAM device on a
> given system? Because otherwise, you will get redundantly-named MTD's.
> If the answer is no, you might consider a unique naming scheme.
Like .999999 sure. This one is hard-wired. There is no extension slots
to plug in any memory device.
I'll post a new version with the rest of the series. Thanks for
reviewing.
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH v4 01/21] serial: rewrite pxa2xx-uart to use 8250_core
2014-04-16 17:13 ` [PATCH v4 01/21] serial: rewrite pxa2xx-uart to use 8250_core Sergei Ianovich
@ 2015-01-19 18:08 ` Rob Herring
0 siblings, 0 replies; 148+ messages in thread
From: Rob Herring @ 2015-01-19 18:08 UTC (permalink / raw)
To: Sergei Ianovich
Cc: linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, Russell King,
Greg Kroah-Hartman, Jiri Slaby, Grant Likely, Rob Herring,
James Cameron, Heikki Krogerus, Paul Bolle, Arnd Bergmann,
Randy Dunlap, Stefan Seyfried, open list:SERIAL DRIVERS,
open list:OPEN FIRMWARE AND...
On Wed, Apr 16, 2014 at 12:13 PM, Sergei Ianovich <ynvich@gmail.com> wrote:
> pxa2xx-uart was a separate uart platform driver. It was declaring
> the same device names and numbers as 8250 driver. As a result,
> it was impossible to use 8250 driver on PXA SoCs.
>
> Upon closer examination pxa2xx-uart turned out to be a clone of
> 8250_core driver.
>
> Workaround for Erratum #19 according to Marvel(R) PXA270M Processor
> Specification Update (April 19, 2010) is dropped. 8250_core reads
> from FIFO immediately after checking DR bit in LSR.
>
> Signed-off-by: Sergei Ianovich <ynvich@gmail.com>
> Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
> Reviewed-by: James Cameron <quozl@laptop.org>
> Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> ---
> Resenging together with the rest of the series as the series
> breaks without this one at [PATCH 12/21]
Whatever happened with merging this? I'm asking because either this or
fixes to PXA uart are needed to coexist with the 8250 driver and for
earlycon to work.
Rob
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [v4,09/21] rtc: support DS1302 RTC on ICP DAS LP-8x4x
2014-04-16 17:17 ` [PATCH v4 09/21] rtc: support DS1302 RTC on " Sergei Ianovich
@ 2015-06-08 12:07 ` Alexandre Belloni
2015-06-08 12:12 ` Sergei Ianovich
0 siblings, 1 reply; 148+ messages in thread
From: Alexandre Belloni @ 2015-06-08 12:07 UTC (permalink / raw)
To: Sergey Yanovich
Cc: linux-kernel, linux-arm-kernel, Kumar Gala, Randy Dunlap,
Russell King, Alessandro Zummo, Grant Likely, Heikki Krogerus,
open list:OPEN FIRMWARE AND..., open list:DOCUMENTATION,
rtc-linux
Hi Sergey,
Are you still interested in seeing that patch going upstream?
On 16/04/2014 at 21:17:14 +0400, Sergey Yanovich wrote :
> Signed-off-by: Sergei Ianovich <ynvich@gmail.com>
> ---
> v3..v4
> * move DTS bindings to a different patch (8/21)
>
> v2..v3
> * use usleep_range instead of custom nsleep
> * number change (07/16 -> 09/21)
>
> v0..v2
> * use device tree
> * use devm helpers where possible
>
> .../devicetree/bindings/rtc/rtc-ds1302.txt | 14 +++
> arch/arm/configs/lp8x4x_defconfig | 1 +
> drivers/rtc/Kconfig | 2 +-
> drivers/rtc/rtc-ds1302.c | 100 ++++++++++++++++++++-
> 4 files changed, 114 insertions(+), 3 deletions(-)
> create mode 100644 Documentation/devicetree/bindings/rtc/rtc-ds1302.txt
>
> diff --git a/Documentation/devicetree/bindings/rtc/rtc-ds1302.txt b/Documentation/devicetree/bindings/rtc/rtc-ds1302.txt
> new file mode 100644
> index 0000000..810613b
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/rtc/rtc-ds1302.txt
> @@ -0,0 +1,14 @@
> +* Dallas Semiconductor DS-1302 RTC
> +
> +Simple device which could be used to store date/time between reboots.
> +
> +Required properties:
> +- compatible : Should be "dallas,rtc-ds1302"
> +- reg : Should be address and size of IO memory region
> +
> +Examples:
> +
> +rtc@40900000 {
> + compatible = "dallas,rtc-ds1302";
> + reg = <0x1700901c 0x1>;
> +};
> diff --git a/arch/arm/configs/lp8x4x_defconfig b/arch/arm/configs/lp8x4x_defconfig
> index 9f1efb6..d60e37a 100644
> --- a/arch/arm/configs/lp8x4x_defconfig
> +++ b/arch/arm/configs/lp8x4x_defconfig
> @@ -141,6 +141,7 @@ CONFIG_LEDS_GPIO=y
> CONFIG_LEDS_TRIGGERS=y
> CONFIG_LEDS_TRIGGER_HEARTBEAT=y
> CONFIG_RTC_CLASS=y
> +CONFIG_RTC_DRV_DS1302=y
> CONFIG_RTC_DRV_PXA=m
> # CONFIG_IOMMU_SUPPORT is not set
> CONFIG_EXT2_FS=m
> diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
> index 2e565f8..80aaaa1 100644
> --- a/drivers/rtc/Kconfig
> +++ b/drivers/rtc/Kconfig
> @@ -710,7 +710,7 @@ config RTC_DRV_DS1286
>
> config RTC_DRV_DS1302
> tristate "Dallas DS1302"
> - depends on SH_SECUREEDGE5410
> + depends on SH_SECUREEDGE5410 || (ARCH_PXA && HIGH_RES_TIMERS)
> help
> If you say yes here you get support for the Dallas DS1302 RTC chips.
>
> diff --git a/drivers/rtc/rtc-ds1302.c b/drivers/rtc/rtc-ds1302.c
> index 07e8d79..3c49023 100644
> --- a/drivers/rtc/rtc-ds1302.c
> +++ b/drivers/rtc/rtc-ds1302.c
> @@ -50,7 +50,7 @@
> #define ds1302_set_tx()
> #define ds1302_set_rx()
>
> -static inline int ds1302_hw_init(void)
> +static inline int ds1302_hw_init(struct platform_device *pdev)
> {
> return 0;
> }
> @@ -86,6 +86,101 @@ static inline int ds1302_rxbit(void)
> return !!(get_dp() & RTC_IODATA);
> }
>
> +#elif defined(CONFIG_ARCH_PXA) && defined(CONFIG_HIGH_RES_TIMERS)
> +
> +#include <linux/delay.h>
> +#include <linux/of.h>
> +
> +#define RTC_CE 0x01
> +#define RTC_CLK 0x02
> +#define RTC_nWE 0x04
> +#define RTC_IODATA 0x08
> +
> +static unsigned long ds1302_state;
> +
> +static void *mem;
> +
> +static inline int ds1302_hw_init(struct platform_device *pdev)
> +{
> + struct resource *r;
> +
> + r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> + if (!r)
> + return -ENODEV;
> +
> + mem = devm_ioremap_resource(&pdev->dev, r);
> + if (!mem)
> + return -EFAULT;
> +
> + return 0;
> +}
> +
> +static inline void ds1302_reset(void)
> +{
> + ds1302_state = 0;
> + iowrite8(ds1302_state, mem);
> + usleep_range(4, 5);
> +}
> +
> +static inline void ds1302_clock(void)
> +{
> + usleep_range(1, 2);
> + ds1302_state |= RTC_CLK;
> + iowrite8(ds1302_state, mem);
> + usleep_range(1, 2);
> + ds1302_state &= ~RTC_CLK;
> + iowrite8(ds1302_state, mem);
> +}
> +
> +static inline void ds1302_start(void)
> +{
> + ds1302_state &= ~RTC_CLK;
> + ds1302_state |= RTC_CE;
> + iowrite8(ds1302_state, mem);
> + usleep_range(3, 4);
> +}
> +
> +static inline void ds1302_stop(void)
> +{
> + ds1302_state &= ~RTC_CE;
> + iowrite8(ds1302_state, mem);
> +}
> +
> +static inline void ds1302_set_tx(void)
> +{
> + ds1302_state &= ~RTC_nWE;
> + iowrite8(ds1302_state, mem);
> +}
> +
> +static inline void ds1302_set_rx(void)
> +{
> + ds1302_state |= RTC_nWE;
> + iowrite8(ds1302_state, mem);
> +}
> +
> +static inline void ds1302_txbit(int bit)
> +{
> + if (bit)
> + ds1302_state |= RTC_IODATA;
> + else
> + ds1302_state &= ~RTC_IODATA;
> + iowrite8(ds1302_state, mem);
> +}
> +
> +static inline int ds1302_rxbit(void)
> +{
> + return ioread8(mem) & 0x1;
> +}
> +
> +#ifdef CONFIG_OF
> +static const struct of_device_id ds1302_dt_ids[] = {
> + { .compatible = "dallas,rtc-ds1302" },
> + { }
> +};
> +
> +MODULE_DEVICE_TABLE(of, ds1302_dt_ids);
> +#endif
> +
> #else
> #error "Add support for your platform"
> #endif
> @@ -216,7 +311,7 @@ static int __init ds1302_rtc_probe(struct platform_device *pdev)
> {
> struct rtc_device *rtc;
>
> - if (ds1302_hw_init()) {
> + if (ds1302_hw_init(pdev)) {
> dev_err(&pdev->dev, "Failed to init communication channel");
> return -EINVAL;
> }
> @@ -245,6 +340,7 @@ static struct platform_driver ds1302_platform_driver = {
> .driver = {
> .name = DRV_NAME,
> .owner = THIS_MODULE,
> + .of_match_table = of_match_ptr(ds1302_dt_ids),
> },
> };
>
--
Alexandre Belloni, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [v4,09/21] rtc: support DS1302 RTC on ICP DAS LP-8x4x
2015-06-08 12:07 ` [v4,09/21] " Alexandre Belloni
@ 2015-06-08 12:12 ` Sergei Ianovich
0 siblings, 0 replies; 148+ messages in thread
From: Sergei Ianovich @ 2015-06-08 12:12 UTC (permalink / raw)
To: Alexandre Belloni
Cc: linux-kernel, linux-arm-kernel, Kumar Gala, Randy Dunlap,
Russell King, Alessandro Zummo, Grant Likely, Heikki Krogerus,
open list:OPEN FIRMWARE AND..., open list:DOCUMENTATION,
rtc-linux
Hi Alexandre,
On Mon, 2015-06-08 at 14:07 +0200, Alexandre Belloni wrote:
> Are you still interested in seeing that patch going upstream?
Sure.
^ permalink raw reply [flat|nested] 148+ messages in thread
* [PATCH v4 2/2] arm: pxa27x: support for ICP DAS LP-8x4x w/ DT
[not found] ` <1449700088-28076-1-git-send-email-ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2015-12-09 22:28 ` Sergei Ianovich
2015-12-11 2:53 ` Rob Herring
[not found] ` <1449700088-28076-3-git-send-email-ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
0 siblings, 2 replies; 148+ messages in thread
From: Sergei Ianovich @ 2015-12-09 22:28 UTC (permalink / raw)
To: linux-kernel-u79uwXL29TY76Z2rM5mHXA
Cc: Sergei Ianovich, Daniel Mack, Robert Jarzmik, Arnd Bergmann,
Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
Russell King, Thierry Reding, Jonathan Cameron, Dmitry Torokhov,
Philipp Zabel, Arnaud Ebalard, Kuninori Morimoto,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
moderated list:ARM PORT
ICP DAS calls LP-8x4x 'programmable automation controller'. It is
an industrial computer based on PXA270 SoC. They ship it with a 2.6.19
kernel and proprietary kernel module and userspace library to access
its industrial IO.
This patch allows to boot a modern kernel with device tree on
the device. It adds support for:
* MMC card interface on PXA270
* USB 1.1 port on PXA270
* 2 NOR flash devices
* 2 onboard ethernet Davicom DM9000 devices
* 3 serial UART ports on PXA270
* front panel red LED
* 64bit 1-wire system ID chip
* 16 kiB EEPROM (reading)
Support for these devices will be added in separate patches, since
they are not currently supported by the kernel:
* DS1302 RTC
* 512kiB SRAM
* FPGA irq chip
* 3 built-in 16550A serial UART ports
* industrial IO parallel bus
* 10 position rotary switch
* 8 pin DIP switch
* 16 kiB EEPROM (writing)
* serial interface for digital and analog industrial IO modules on
parallel bus (all I-87xxx modules)
* digital and analog industrial IO modules for parallel bus:
** I-8024 4 port analog output
** I-8041 32 port digital output
** I-8042 16 port digital output/16 port digital input
Not supported for now:
* VGA interface on PXA270 for lack of dts binding
* the rest of parallel bus (I-8xxx) modules for lack of hardware
* GPIO reset for lack of relevance (watchdog reset is working)
Newer LP-8x4x devices have twice as much flash and a different
partition structure otherwise being the same. When each device
is provided with a correct device tree, all of them can be booted
using the same kernel.
Signed-off-by: Sergei Ianovich <ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
CC: Daniel Mack <zonque-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
CC: Robert Jarzmik <robert.jarzmik-GANU6spQydw@public.gmane.org>
CC: Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org>
---
v3..v4
* support for newer flavor w/ 96Mb flash memory
* use 'partitions' subnodes
* move device-specific tweaking to device .dts file and drop
patches to pxa27x.dtsi
v2..v3
* added extbus which maps synchronous, static, and variable-latency
I/O (VLIO) interfaces of PXA27x SoC as suggested by Arnd Bergmann
* map is placed into platform include
* configured existing kernel drivers to support:
- front panel LED using gpio-leds
- 64bit 1-wire system ID chip using w1-gpio
- 16 kiB EEPROM using at24 over i2c-gpio
* number change (06/16 -> 08/21)
v1..v2
* drop left-over extern declaration
* use of_have_populated_dt() instead of a static variable
* drop wildcards in compatible
* drop machine-special machine description
* number changed from 9 to 6 (dropped patches)
.../devicetree/bindings/vendor-prefixes.txt | 1 +
arch/arm/boot/dts/Makefile | 3 +
arch/arm/boot/dts/pxa27x-lp8x4x-i105.dts | 50 ++++
arch/arm/boot/dts/pxa27x-lp8x4x.dts | 260 +++++++++++++++++++++
arch/arm/configs/lp8x4x_defconfig | 176 ++++++++++++++
5 files changed, 490 insertions(+)
create mode 100644 arch/arm/boot/dts/pxa27x-lp8x4x-i105.dts
create mode 100644 arch/arm/boot/dts/pxa27x-lp8x4x.dts
create mode 100644 arch/arm/configs/lp8x4x_defconfig
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index 55df1d4..2f1b078 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -109,6 +109,7 @@ honeywell Honeywell
hp Hewlett Packard
i2se I2SE GmbH
ibm International Business Machines (IBM)
+icpdas ICP DAS CO., LTD.
idt Integrated Device Technologies, Inc.
iom Iomega Corporation
img Imagination Technologies Ltd.
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 30bbc37..ed182ea 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -499,6 +499,9 @@ dtb-$(CONFIG_ARCH_ORION5X) += \
orion5x-rd88f5182-nas.dtb
dtb-$(CONFIG_ARCH_PRIMA2) += \
prima2-evb.dtb
+dtb-$(CONFIG_MACH_PXA27X_DT) += \
+ pxa27x-lp8x4x.dtb \
+ pxa27x-lp8x4x-i105.dtb
dtb-$(CONFIG_ARCH_QCOM) += \
qcom-apq8064-cm-qs600.dtb \
qcom-apq8064-ifc6410.dtb \
diff --git a/arch/arm/boot/dts/pxa27x-lp8x4x-i105.dts b/arch/arm/boot/dts/pxa27x-lp8x4x-i105.dts
new file mode 100644
index 0000000..903f5c7
--- /dev/null
+++ b/arch/arm/boot/dts/pxa27x-lp8x4x-i105.dts
@@ -0,0 +1,50 @@
+/* Device tree for ICP DAS LP-8x4x i105 flavor */
+
+#include "pxa27x-lp8x4x.dts"
+
+/ {
+ extbus {
+ flash@0 {
+ compatible = "cfi-flash";
+ reg = <0 0 0x04000000>;
+ bank-width = <4>;
+ device-width = <2>;
+
+ partitions {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ fs@0 {
+ label = "u-boot";
+ reg = <0 0x40000>;
+ };
+ fs@40000 {
+ label = "settings";
+ reg = <0x40000 0x40000>;
+ };
+ fs@80000 {
+ label = "device_tree";
+ reg = <0x80000 0x40000>;
+ };
+ fs@c0000 {
+ label = "kernel";
+ reg = <0xc0000 0x2c0000>;
+ };
+ fs@300000 {
+ label = "root_fs";
+ reg = <0x380000 0x3c80000>;
+ };
+ };
+ };
+
+ flash@1 {
+ compatible = "cfi-flash";
+ reg = <1 0x0 0x02000000>;
+ bank-width = <2>;
+ device-width = <1>;
+ partitions {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/pxa27x-lp8x4x.dts b/arch/arm/boot/dts/pxa27x-lp8x4x.dts
new file mode 100644
index 0000000..bbb5b75
--- /dev/null
+++ b/arch/arm/boot/dts/pxa27x-lp8x4x.dts
@@ -0,0 +1,260 @@
+/* Device tree for ICP DAS LP-8x4x */
+/dts-v1/;
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include "pxa27x.dtsi"
+
+/ {
+ model = "ICP DAS LP-8x4x programmable automation controller";
+ compatible = "marvell,pxa270";
+
+ aliases {
+ ethernet0 = ð0;
+ ethernet1 = ð1;
+ };
+
+ memory {
+ reg = <0xa0000000 0x08000000>;
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ vmmc: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "vmmc";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ };
+
+ pxabus {
+ pxairq: interrupt-controller@40d00000 {
+ marvell,intc-priority;
+ marvell,intc-nr-irqs = <34>;
+ };
+
+ gpio: gpio@40e00000 {
+ interrupts = <8>, <9>, <10>;
+ interrupt-names = "gpio0", "gpio1", "gpio_mux";
+ };
+
+ uart@40100000 {
+ status = "okay";
+ };
+
+ uart@40200000 {
+ status = "okay";
+ };
+
+ uart@40700000 {
+ status = "okay";
+ };
+
+ mmc0: mmc@41100000 {
+ vmmc-supply = <&vmmc>;
+ status = "okay";
+ };
+
+ usb0: ohci@4c000000 {
+ marvell,port-mode = <3>;
+ marvell,oc-mode-perport;
+ marvell,enable-port1;
+ status = "okay";
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ status {
+ gpios = <&gpio 84 1>;
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
+ i2c: i2c-gpio {
+ compatible = "i2c-gpio";
+ gpios = <&gpio 22 0 /* sda */
+ &gpio 12 0 /* scl */>;
+ i2c-gpio,delay-us = <1>;
+ i2c-gpio,timeout-ms = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ eeprom@50 {
+ compatible = "atmel,24c128";
+ reg = <0x50>;
+ pagesize = <64>;
+ };
+ };
+
+ w1: w1-gpio {
+ compatible = "w1-gpio";
+ gpios = <&gpio 83 0>;
+ };
+ };
+
+ extbus {
+ /*
+ * PXA27x synchrous, static and
+ * variable-latency IO interfaces
+ */
+ compatible = "simple-bus";
+
+ #address-cells = <2>; /* first cell is nCS, second is address */
+ #size-cells = <1>;
+ ranges = <0 0 0 0x04000000
+ 1 0 0x04000000 0x04000000
+ 2 0 0x08000000 0x04000000
+ 3 0 0x0c000000 0x04000000
+ 4 0 0x10000000 0x04000000
+ 5 0 0x14000000 0x04000000>;
+
+ flash@0 {
+ compatible = "cfi-flash";
+ reg = <0 0 0x02000000>;
+ bank-width = <4>;
+ device-width = <2>;
+
+ partitions {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ fs@0 {
+ label = "u-boot";
+ reg = <0 0x40000>;
+ };
+ fs@40000 {
+ label = "settings";
+ reg = <0x40000 0x40000>;
+ };
+ fs@80000 {
+ label = "device_tree";
+ reg = <0x80000 0x40000>;
+ };
+ fs@c0000 {
+ label = "kernel";
+ reg = <0xc0000 0x240000>;
+ };
+ fs@300000 {
+ label = "root_fs";
+ reg = <0x300000 0x1d00000>;
+ };
+ };
+ };
+
+ flash@1 {
+ compatible = "cfi-flash";
+ reg = <1 0x0 0x01000000>;
+ bank-width = <2>;
+ device-width = <1>;
+ partitions {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
+ };
+
+ netio@3 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 3 0 0x02000000>;
+ interrupt-parent = <&gpio>;
+
+ eth0: eth@0 {
+ compatible = "davicom,dm9000";
+ reg = <0x0 0x2
+ 0x4000 0x2>;
+ interrupts = <9 IRQ_TYPE_EDGE_RISING>;
+ status = "okay";
+ };
+
+ eth1: eth@1000000 {
+ compatible = "davicom,dm9000";
+ reg = <0x1000000 0x2
+ 0x1004000 0x2>;
+ interrupts = <82 IRQ_TYPE_EDGE_RISING>;
+ status = "okay";
+ };
+ };
+
+ fpga@5 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 5 0x3000000 0x10000>;
+ interrupt-parent = <&fpgairq>;
+
+ rtc@901c {
+ compatible = "dallas,rtc-ds1302";
+ reg = <0x901c 0x1>;
+ status = "okay";
+ };
+
+ sram@a000 {
+ compatible = "icpdas,sram-lp8x4x";
+ reg = <0xa000 0x1000
+ 0x901e 0x1>;
+
+ partitions {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
+ };
+
+ fpgairq: irq@9006 {
+ compatible = "icpdas,irq-lp8x4x";
+ reg = <0x9006 0x16>;
+ interrupt-parent = <&gpio>;
+ interrupts = <3 IRQ_TYPE_EDGE_FALLING>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ status = "okay";
+ };
+
+ uart@9050 {
+ compatible = "icpdas,uart-lp8x4x";
+ reg = <0x9050 0x10
+ 0x9030 0x02>;
+ interrupts = <13>;
+ status = "okay";
+ };
+
+ uart@9060 {
+ compatible = "icpdas,uart-lp8x4x";
+ reg = <0x9060 0x10
+ 0x9032 0x02>;
+ interrupts = <14>;
+ status = "okay";
+ };
+
+ uart@9070 {
+ compatible = "icpdas,uart-lp8x4x";
+ reg = <0x9070 0x10
+ 0x9034 0x02>;
+ interrupts = <15>;
+ status = "okay";
+ };
+
+ backplane {
+ compatible = "icpdas,backplane-lp8x4x";
+ reg = <0x0 0x2
+ 0x1000 0x10
+ 0x2000 0x10
+ 0x3000 0x10
+ 0x4000 0x10
+ 0x5000 0x10
+ 0x6000 0x10
+ 0x7000 0x10
+ 0x8000 0x10
+ 0x9002 0x2
+ 0x9004 0x2
+ 0x9046 0x2>;
+ eeprom-gpios = <&gpio 4 0>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/configs/lp8x4x_defconfig b/arch/arm/configs/lp8x4x_defconfig
new file mode 100644
index 0000000..0eb87df
--- /dev/null
+++ b/arch/arm/configs/lp8x4x_defconfig
@@ -0,0 +1,176 @@
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_RCU_BOOST=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+# CONFIG_UID16 is not set
+# CONFIG_SHMEM is not set
+CONFIG_EMBEDDED=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLOB=y
+CONFIG_JUMP_LABEL=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+# CONFIG_LBDAF is not set
+CONFIG_BLK_CMDLINE_PARSER=y
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+CONFIG_ARCH_PXA=y
+CONFIG_MACH_PXA27X_DT=y
+# CONFIG_ARM_THUMB is not set
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+# CONFIG_COMPACTION is not set
+# CONFIG_CROSS_MEMORY_ATTACH is not set
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="init=/sbin/init root=/dev/mmcblk0p1 rw rootfstype=ext4 console=ttyS0,115200 mem=128M rootwait"
+# CONFIG_SUSPEND is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_BRIDGE=m
+CONFIG_BRIDGE_VLAN_FILTERING=y
+CONFIG_VLAN_8021Q=m
+CONFIG_VLAN_8021Q_GVRP=y
+CONFIG_VLAN_8021Q_MVRP=y
+# CONFIG_WIRELESS is not set
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_FW_LOADER is not set
+CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_GEOMETRY=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_PHYSMAP_OF=y
+CONFIG_MTD_SRAM_LP8X4X=y
+CONFIG_PROC_DEVICETREE=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_LOOP_MIN_COUNT=2
+CONFIG_EEPROM_AT24=m
+CONFIG_LP8X4X_BUS=m
+CONFIG_SCSI=y
+# CONFIG_SCSI_PROC_FS is not set
+CONFIG_BLK_DEV_SD=y
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_NETDEVICES=y
+CONFIG_BONDING=m
+CONFIG_MACVLAN=m
+CONFIG_MACVTAP=m
+CONFIG_TUN=m
+# CONFIG_NET_VENDOR_ARC is not set
+# CONFIG_NET_CADENCE is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CIRRUS is not set
+CONFIG_DM9000=y
+CONFIG_DM9000_FORCE_SIMPLE_PHY_POLL=y
+# CONFIG_NET_VENDOR_FARADAY 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_SEEQ is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_VIA is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
+CONFIG_PPP=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPPOE=m
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+# CONFIG_WLAN is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=800
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=600
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_8250=y
+# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=40
+CONFIG_SERIAL_8250_RUNTIME_UARTS=40
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_MANY_PORTS=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_8250_PXA=y
+CONFIG_SERIAL_8250_LP8X4X=m
+CONFIG_HW_RANDOM=y
+CONFIG_I2C=m
+# CONFIG_I2C_COMPAT is not set
+CONFIG_I2C_GPIO=m
+CONFIG_W1=m
+CONFIG_W1_MASTER_GPIO=m
+CONFIG_W1_SLAVE_SMEM=m
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_SA1100_WATCHDOG=m
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_FB=y
+CONFIG_FB_PXA=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_LOGO=y
+CONFIG_USB=m
+CONFIG_USB_OHCI_HCD=m
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+CONFIG_USB_STORAGE=m
+CONFIG_USB_SERIAL=m
+CONFIG_MMC=y
+CONFIG_MMC_PXA=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_DS1302=y
+CONFIG_RTC_DRV_PXA=m
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_DMA_ENGINE=y
+CONFIG_DMA_VIRTUAL_CHANNELS=y
+CONFIG_DMA_OF=y
+CONFIG_PXA_DMA=y
+CONFIG_EXT2_FS=m
+CONFIG_EXT3_FS=y
+CONFIG_EXT4_FS=y
+CONFIG_REISERFS_FS=m
+CONFIG_ISO9660_FS=m
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_NTFS_FS=m
+CONFIG_NTFS_RW=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+CONFIG_CIFS=m
+CONFIG_CIFS_STATS=y
+CONFIG_CODA_FS=m
+CONFIG_NLS_DEFAULT="cp855"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_855=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_UTF8=y
+CONFIG_PRINTK_TIME=y
--
2.6.2
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 148+ messages in thread
* Re: [PATCH v4 2/2] arm: pxa27x: support for ICP DAS LP-8x4x w/ DT
2015-12-09 22:28 ` [PATCH v4 2/2] arm: pxa27x: support for ICP DAS LP-8x4x w/ DT Sergei Ianovich
@ 2015-12-11 2:53 ` Rob Herring
[not found] ` <1449700088-28076-3-git-send-email-ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
1 sibling, 0 replies; 148+ messages in thread
From: Rob Herring @ 2015-12-11 2:53 UTC (permalink / raw)
To: Sergei Ianovich
Cc: linux-kernel, Daniel Mack, Robert Jarzmik, Arnd Bergmann,
Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala, Russell King,
Thierry Reding, Jonathan Cameron, Dmitry Torokhov, Philipp Zabel,
Arnaud Ebalard, Kuninori Morimoto,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
moderated list:ARM PORT
On Thu, Dec 10, 2015 at 01:28:08AM +0300, Sergei Ianovich wrote:
> ICP DAS calls LP-8x4x 'programmable automation controller'. It is
> an industrial computer based on PXA270 SoC. They ship it with a 2.6.19
> kernel and proprietary kernel module and userspace library to access
> its industrial IO.
2 comments, otherwise:
Acked-by: Rob Herring <robh@kernel.org>
> diff --git a/arch/arm/boot/dts/pxa27x-lp8x4x.dts b/arch/arm/boot/dts/pxa27x-lp8x4x.dts
> new file mode 100644
> index 0000000..bbb5b75
> --- /dev/null
> +++ b/arch/arm/boot/dts/pxa27x-lp8x4x.dts
> @@ -0,0 +1,260 @@
> +/* Device tree for ICP DAS LP-8x4x */
> +/dts-v1/;
> +
> +#include <dt-bindings/interrupt-controller/arm-gic.h>
Pretty sure this does not have a GIC.
> +#include "pxa27x.dtsi"
> +
> +/ {
> + model = "ICP DAS LP-8x4x programmable automation controller";
> + compatible = "marvell,pxa270";
You should have a compatible string for this board.
Rob
^ permalink raw reply [flat|nested] 148+ messages in thread
* [PATCH v5 2/2] arm: pxa27x: support for ICP DAS LP-8x4x w/ DT
[not found] ` <1449700088-28076-3-git-send-email-ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2015-12-15 16:27 ` Sergei Ianovich
2015-12-15 16:32 ` Arnd Bergmann
0 siblings, 1 reply; 148+ messages in thread
From: Sergei Ianovich @ 2015-12-15 16:27 UTC (permalink / raw)
To: linux-kernel-u79uwXL29TY76Z2rM5mHXA
Cc: Sergei Ianovich, Daniel Mack, Robert Jarzmik, Arnd Bergmann,
Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
Russell King, Thierry Reding, Jonathan Cameron, Dmitry Torokhov,
Philipp Zabel, Arnaud Ebalard, Kuninori Morimoto,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
moderated list:ARM PORT
ICP DAS calls LP-8x4x 'programmable automation controller'. It is
an industrial computer based on PXA270 SoC. They ship it with a 2.6.19
kernel and proprietary kernel module and userspace library to access
its industrial IO.
This patch allows to boot a modern kernel with device tree on
the device. It adds support for:
* MMC card interface on PXA270
* USB 1.1 port on PXA270
* 2 NOR flash devices
* 2 onboard ethernet Davicom DM9000 devices
* 3 serial UART ports on PXA270
* front panel red LED
* 64bit 1-wire system ID chip
* 16 kiB EEPROM (reading)
Support for these devices will be added in separate patches, since
they are not currently supported by the kernel:
* DS1302 RTC
* 512kiB SRAM
* FPGA irq chip
* 3 built-in 16550A serial UART ports
* industrial IO parallel bus
* 10 position rotary switch
* 8 pin DIP switch
* 16 kiB EEPROM (writing)
* serial interface for digital and analog industrial IO modules on
parallel bus (all I-87xxx modules)
* digital and analog industrial IO modules for parallel bus:
** I-8024 4 port analog output
** I-8041 32 port digital output
** I-8042 16 port digital output/16 port digital input
Not supported for now:
* VGA interface on PXA270 for lack of dts binding
* the rest of parallel bus (I-8xxx) modules for lack of hardware
* GPIO reset for lack of relevance (watchdog reset is working)
Newer LP-8x4x devices have twice as much flash and a different
partition structure otherwise being the same. When each device
is provided with a correct device tree, all of them can be booted
using the same kernel.
Signed-off-by: Sergei Ianovich <ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
CC: Daniel Mack <zonque-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
CC: Robert Jarzmik <robert.jarzmik-GANU6spQydw@public.gmane.org>
CC: Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org>
---
v4..v5
fixes to apply Rob Herring's "Acked-by":
* provide board compatible string
* remove unused include directive in pxa27x-lp8x4x.dts
v3..v4
* support for newer flavor w/ 96Mb flash memory
* use 'partitions' subnodes
* move device-specific tweaking to device .dts file and drop
patches to pxa27x.dtsi
v2..v3
* added extbus which maps synchronous, static, and variable-latency
I/O (VLIO) interfaces of PXA27x SoC as suggested by Arnd Bergmann
* map is placed into platform include
* configured existing kernel drivers to support:
- front panel LED using gpio-leds
- 64bit 1-wire system ID chip using w1-gpio
- 16 kiB EEPROM using at24 over i2c-gpio
* number change (06/16 -> 08/21)
v1..v2
* drop left-over extern declaration
* use of_have_populated_dt() instead of a static variable
* drop wildcards in compatible
* drop machine-special machine description
* number changed from 9 to 6 (dropped patches)
.../devicetree/bindings/vendor-prefixes.txt | 1 +
arch/arm/boot/dts/Makefile | 3 +
arch/arm/boot/dts/pxa27x-lp8x4x-i105.dts | 50 ++++
arch/arm/boot/dts/pxa27x-lp8x4x.dts | 259 +++++++++++++++++++++
arch/arm/configs/lp8x4x_defconfig | 176 ++++++++++++++
5 files changed, 489 insertions(+)
create mode 100644 arch/arm/boot/dts/pxa27x-lp8x4x-i105.dts
create mode 100644 arch/arm/boot/dts/pxa27x-lp8x4x.dts
create mode 100644 arch/arm/configs/lp8x4x_defconfig
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index 55df1d4..2f1b078 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -109,6 +109,7 @@ honeywell Honeywell
hp Hewlett Packard
i2se I2SE GmbH
ibm International Business Machines (IBM)
+icpdas ICP DAS CO., LTD.
idt Integrated Device Technologies, Inc.
iom Iomega Corporation
img Imagination Technologies Ltd.
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 30bbc37..ed182ea 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -499,6 +499,9 @@ dtb-$(CONFIG_ARCH_ORION5X) += \
orion5x-rd88f5182-nas.dtb
dtb-$(CONFIG_ARCH_PRIMA2) += \
prima2-evb.dtb
+dtb-$(CONFIG_MACH_PXA27X_DT) += \
+ pxa27x-lp8x4x.dtb \
+ pxa27x-lp8x4x-i105.dtb
dtb-$(CONFIG_ARCH_QCOM) += \
qcom-apq8064-cm-qs600.dtb \
qcom-apq8064-ifc6410.dtb \
diff --git a/arch/arm/boot/dts/pxa27x-lp8x4x-i105.dts b/arch/arm/boot/dts/pxa27x-lp8x4x-i105.dts
new file mode 100644
index 0000000..903f5c7
--- /dev/null
+++ b/arch/arm/boot/dts/pxa27x-lp8x4x-i105.dts
@@ -0,0 +1,50 @@
+/* Device tree for ICP DAS LP-8x4x i105 flavor */
+
+#include "pxa27x-lp8x4x.dts"
+
+/ {
+ extbus {
+ flash@0 {
+ compatible = "cfi-flash";
+ reg = <0 0 0x04000000>;
+ bank-width = <4>;
+ device-width = <2>;
+
+ partitions {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ fs@0 {
+ label = "u-boot";
+ reg = <0 0x40000>;
+ };
+ fs@40000 {
+ label = "settings";
+ reg = <0x40000 0x40000>;
+ };
+ fs@80000 {
+ label = "device_tree";
+ reg = <0x80000 0x40000>;
+ };
+ fs@c0000 {
+ label = "kernel";
+ reg = <0xc0000 0x2c0000>;
+ };
+ fs@300000 {
+ label = "root_fs";
+ reg = <0x380000 0x3c80000>;
+ };
+ };
+ };
+
+ flash@1 {
+ compatible = "cfi-flash";
+ reg = <1 0x0 0x02000000>;
+ bank-width = <2>;
+ device-width = <1>;
+ partitions {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/pxa27x-lp8x4x.dts b/arch/arm/boot/dts/pxa27x-lp8x4x.dts
new file mode 100644
index 0000000..7f33912c
--- /dev/null
+++ b/arch/arm/boot/dts/pxa27x-lp8x4x.dts
@@ -0,0 +1,259 @@
+/* Device tree for ICP DAS LP-8x4x */
+/dts-v1/;
+
+#include "pxa27x.dtsi"
+
+/ {
+ model = "ICP DAS LP-8x4x programmable automation controller";
+ compatible = "icpdas,lp8x4x", "marvell,pxa270";
+
+ aliases {
+ ethernet0 = ð0;
+ ethernet1 = ð1;
+ };
+
+ memory {
+ reg = <0xa0000000 0x08000000>;
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ vmmc: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "vmmc";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ };
+
+ pxabus {
+ pxairq: interrupt-controller@40d00000 {
+ marvell,intc-priority;
+ marvell,intc-nr-irqs = <34>;
+ };
+
+ gpio: gpio@40e00000 {
+ interrupts = <8>, <9>, <10>;
+ interrupt-names = "gpio0", "gpio1", "gpio_mux";
+ };
+
+ uart@40100000 {
+ status = "okay";
+ };
+
+ uart@40200000 {
+ status = "okay";
+ };
+
+ uart@40700000 {
+ status = "okay";
+ };
+
+ mmc0: mmc@41100000 {
+ vmmc-supply = <&vmmc>;
+ status = "okay";
+ };
+
+ usb0: ohci@4c000000 {
+ marvell,port-mode = <3>;
+ marvell,oc-mode-perport;
+ marvell,enable-port1;
+ status = "okay";
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ status {
+ gpios = <&gpio 84 1>;
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
+ i2c: i2c-gpio {
+ compatible = "i2c-gpio";
+ gpios = <&gpio 22 0 /* sda */
+ &gpio 12 0 /* scl */>;
+ i2c-gpio,delay-us = <1>;
+ i2c-gpio,timeout-ms = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ eeprom@50 {
+ compatible = "atmel,24c128";
+ reg = <0x50>;
+ pagesize = <64>;
+ };
+ };
+
+ w1: w1-gpio {
+ compatible = "w1-gpio";
+ gpios = <&gpio 83 0>;
+ };
+ };
+
+ extbus {
+ /*
+ * PXA27x synchrous, static and
+ * variable-latency IO interfaces
+ */
+ compatible = "simple-bus";
+
+ #address-cells = <2>; /* first cell is nCS, second is address */
+ #size-cells = <1>;
+ ranges = <0 0 0 0x04000000
+ 1 0 0x04000000 0x04000000
+ 2 0 0x08000000 0x04000000
+ 3 0 0x0c000000 0x04000000
+ 4 0 0x10000000 0x04000000
+ 5 0 0x14000000 0x04000000>;
+
+ flash@0 {
+ compatible = "cfi-flash";
+ reg = <0 0 0x02000000>;
+ bank-width = <4>;
+ device-width = <2>;
+
+ partitions {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ fs@0 {
+ label = "u-boot";
+ reg = <0 0x40000>;
+ };
+ fs@40000 {
+ label = "settings";
+ reg = <0x40000 0x40000>;
+ };
+ fs@80000 {
+ label = "device_tree";
+ reg = <0x80000 0x40000>;
+ };
+ fs@c0000 {
+ label = "kernel";
+ reg = <0xc0000 0x240000>;
+ };
+ fs@300000 {
+ label = "root_fs";
+ reg = <0x300000 0x1d00000>;
+ };
+ };
+ };
+
+ flash@1 {
+ compatible = "cfi-flash";
+ reg = <1 0x0 0x01000000>;
+ bank-width = <2>;
+ device-width = <1>;
+ partitions {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
+ };
+
+ netio@3 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 3 0 0x02000000>;
+ interrupt-parent = <&gpio>;
+
+ eth0: eth@0 {
+ compatible = "davicom,dm9000";
+ reg = <0x0 0x2
+ 0x4000 0x2>;
+ interrupts = <9 IRQ_TYPE_EDGE_RISING>;
+ status = "okay";
+ };
+
+ eth1: eth@1000000 {
+ compatible = "davicom,dm9000";
+ reg = <0x1000000 0x2
+ 0x1004000 0x2>;
+ interrupts = <82 IRQ_TYPE_EDGE_RISING>;
+ status = "okay";
+ };
+ };
+
+ fpga@5 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 5 0x3000000 0x10000>;
+ interrupt-parent = <&fpgairq>;
+
+ rtc@901c {
+ compatible = "dallas,rtc-ds1302";
+ reg = <0x901c 0x1>;
+ status = "okay";
+ };
+
+ sram@a000 {
+ compatible = "icpdas,sram-lp8x4x";
+ reg = <0xa000 0x1000
+ 0x901e 0x1>;
+
+ partitions {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
+ };
+
+ fpgairq: irq@9006 {
+ compatible = "icpdas,irq-lp8x4x";
+ reg = <0x9006 0x16>;
+ interrupt-parent = <&gpio>;
+ interrupts = <3 IRQ_TYPE_EDGE_FALLING>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ status = "okay";
+ };
+
+ uart@9050 {
+ compatible = "icpdas,uart-lp8x4x";
+ reg = <0x9050 0x10
+ 0x9030 0x02>;
+ interrupts = <13>;
+ status = "okay";
+ };
+
+ uart@9060 {
+ compatible = "icpdas,uart-lp8x4x";
+ reg = <0x9060 0x10
+ 0x9032 0x02>;
+ interrupts = <14>;
+ status = "okay";
+ };
+
+ uart@9070 {
+ compatible = "icpdas,uart-lp8x4x";
+ reg = <0x9070 0x10
+ 0x9034 0x02>;
+ interrupts = <15>;
+ status = "okay";
+ };
+
+ backplane {
+ compatible = "icpdas,backplane-lp8x4x";
+ reg = <0x0 0x2
+ 0x1000 0x10
+ 0x2000 0x10
+ 0x3000 0x10
+ 0x4000 0x10
+ 0x5000 0x10
+ 0x6000 0x10
+ 0x7000 0x10
+ 0x8000 0x10
+ 0x9002 0x2
+ 0x9004 0x2
+ 0x9046 0x2>;
+ eeprom-gpios = <&gpio 4 0>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/configs/lp8x4x_defconfig b/arch/arm/configs/lp8x4x_defconfig
new file mode 100644
index 0000000..0eb87df
--- /dev/null
+++ b/arch/arm/configs/lp8x4x_defconfig
@@ -0,0 +1,176 @@
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_RCU_BOOST=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+# CONFIG_UID16 is not set
+# CONFIG_SHMEM is not set
+CONFIG_EMBEDDED=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLOB=y
+CONFIG_JUMP_LABEL=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+# CONFIG_LBDAF is not set
+CONFIG_BLK_CMDLINE_PARSER=y
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+CONFIG_ARCH_PXA=y
+CONFIG_MACH_PXA27X_DT=y
+# CONFIG_ARM_THUMB is not set
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+# CONFIG_COMPACTION is not set
+# CONFIG_CROSS_MEMORY_ATTACH is not set
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="init=/sbin/init root=/dev/mmcblk0p1 rw rootfstype=ext4 console=ttyS0,115200 mem=128M rootwait"
+# CONFIG_SUSPEND is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_BRIDGE=m
+CONFIG_BRIDGE_VLAN_FILTERING=y
+CONFIG_VLAN_8021Q=m
+CONFIG_VLAN_8021Q_GVRP=y
+CONFIG_VLAN_8021Q_MVRP=y
+# CONFIG_WIRELESS is not set
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_FW_LOADER is not set
+CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_GEOMETRY=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_PHYSMAP_OF=y
+CONFIG_MTD_SRAM_LP8X4X=y
+CONFIG_PROC_DEVICETREE=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_LOOP_MIN_COUNT=2
+CONFIG_EEPROM_AT24=m
+CONFIG_LP8X4X_BUS=m
+CONFIG_SCSI=y
+# CONFIG_SCSI_PROC_FS is not set
+CONFIG_BLK_DEV_SD=y
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_NETDEVICES=y
+CONFIG_BONDING=m
+CONFIG_MACVLAN=m
+CONFIG_MACVTAP=m
+CONFIG_TUN=m
+# CONFIG_NET_VENDOR_ARC is not set
+# CONFIG_NET_CADENCE is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CIRRUS is not set
+CONFIG_DM9000=y
+CONFIG_DM9000_FORCE_SIMPLE_PHY_POLL=y
+# CONFIG_NET_VENDOR_FARADAY 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_SEEQ is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_VIA is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
+CONFIG_PPP=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPPOE=m
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+# CONFIG_WLAN is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=800
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=600
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_8250=y
+# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=40
+CONFIG_SERIAL_8250_RUNTIME_UARTS=40
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_MANY_PORTS=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_8250_PXA=y
+CONFIG_SERIAL_8250_LP8X4X=m
+CONFIG_HW_RANDOM=y
+CONFIG_I2C=m
+# CONFIG_I2C_COMPAT is not set
+CONFIG_I2C_GPIO=m
+CONFIG_W1=m
+CONFIG_W1_MASTER_GPIO=m
+CONFIG_W1_SLAVE_SMEM=m
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_SA1100_WATCHDOG=m
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_FB=y
+CONFIG_FB_PXA=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_LOGO=y
+CONFIG_USB=m
+CONFIG_USB_OHCI_HCD=m
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+CONFIG_USB_STORAGE=m
+CONFIG_USB_SERIAL=m
+CONFIG_MMC=y
+CONFIG_MMC_PXA=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_DS1302=y
+CONFIG_RTC_DRV_PXA=m
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_DMA_ENGINE=y
+CONFIG_DMA_VIRTUAL_CHANNELS=y
+CONFIG_DMA_OF=y
+CONFIG_PXA_DMA=y
+CONFIG_EXT2_FS=m
+CONFIG_EXT3_FS=y
+CONFIG_EXT4_FS=y
+CONFIG_REISERFS_FS=m
+CONFIG_ISO9660_FS=m
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_NTFS_FS=m
+CONFIG_NTFS_RW=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+CONFIG_CIFS=m
+CONFIG_CIFS_STATS=y
+CONFIG_CODA_FS=m
+CONFIG_NLS_DEFAULT="cp855"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_855=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_UTF8=y
+CONFIG_PRINTK_TIME=y
--
2.6.2
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 148+ messages in thread
* Re: [PATCH v5 2/2] arm: pxa27x: support for ICP DAS LP-8x4x w/ DT
2015-12-15 16:27 ` [PATCH v5 " Sergei Ianovich
@ 2015-12-15 16:32 ` Arnd Bergmann
2015-12-15 16:42 ` Sergei Ianovich
0 siblings, 1 reply; 148+ messages in thread
From: Arnd Bergmann @ 2015-12-15 16:32 UTC (permalink / raw)
To: Sergei Ianovich
Cc: linux-kernel, Daniel Mack, Robert Jarzmik, Rob Herring,
Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala, Russell King,
Thierry Reding, Jonathan Cameron, Dmitry Torokhov, Philipp Zabel,
Arnaud Ebalard, Kuninori Morimoto,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
moderated list:ARM PORT
On Tuesday 15 December 2015 19:27:50 Sergei Ianovich wrote:
> .../devicetree/bindings/vendor-prefixes.txt | 1 +
> arch/arm/boot/dts/Makefile | 3 +
> arch/arm/boot/dts/pxa27x-lp8x4x-i105.dts | 50 ++++
> arch/arm/boot/dts/pxa27x-lp8x4x.dts | 259 +++++++++++++++++++++
> arch/arm/configs/lp8x4x_defconfig | 176 ++++++++++++++
>
I had not noticed earlier that you are adding a new defconfig file. PXA is
already the platform with the most defconfig files, and I'd rather like
to see that reduced than increased.
Is there a chance you could merge this one with some of the existing files
into one configuration that handles them all?
Arnd
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH v5 2/2] arm: pxa27x: support for ICP DAS LP-8x4x w/ DT
2015-12-15 16:32 ` Arnd Bergmann
@ 2015-12-15 16:42 ` Sergei Ianovich
2015-12-15 17:02 ` Arnd Bergmann
0 siblings, 1 reply; 148+ messages in thread
From: Sergei Ianovich @ 2015-12-15 16:42 UTC (permalink / raw)
To: Arnd Bergmann
Cc: linux-kernel, Daniel Mack, Robert Jarzmik, Rob Herring,
Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala, Russell King,
Thierry Reding, Jonathan Cameron, Dmitry Torokhov, Philipp Zabel,
Arnaud Ebalard, Kuninori Morimoto,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
moderated list:ARM PORT
On Tue, 2015-12-15 at 17:32 +0100, Arnd Bergmann wrote:
> On Tuesday 15 December 2015 19:27:50 Sergei Ianovich wrote:
> > .../devicetree/bindings/vendor-prefixes.txt | 1 +
> > arch/arm/boot/dts/Makefile | 3 +
> > arch/arm/boot/dts/pxa27x-lp8x4x-i105.dts | 50 ++++
> > arch/arm/boot/dts/pxa27x-lp8x4x.dts | 259
> > +++++++++++++++++++++
> > arch/arm/configs/lp8x4x_defconfig | 176
> > ++++++++++++++
> >
>
> I had not noticed earlier that you are adding a new defconfig file.
> PXA is
> already the platform with the most defconfig files, and I'd rather
> like
> to see that reduced than increased.
>
> Is there a chance you could merge this one with some of the existing
> files
> into one configuration that handles them all?
There are several board-specific devices on LP8x4x: custom FPGA, custom
UART, custom IRQ on FPGA, custom parallel bus for industrial IO. The
defconfig file could alert potential users to this fact. If this is not
a sufficient reason to have a defconfig file, it can be dropped.
I use the full .config anyway :)
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH v5 2/2] arm: pxa27x: support for ICP DAS LP-8x4x w/ DT
2015-12-15 16:42 ` Sergei Ianovich
@ 2015-12-15 17:02 ` Arnd Bergmann
2015-12-15 17:24 ` Sergei Ianovich
2015-12-19 12:27 ` Robert Jarzmik
0 siblings, 2 replies; 148+ messages in thread
From: Arnd Bergmann @ 2015-12-15 17:02 UTC (permalink / raw)
To: Sergei Ianovich
Cc: linux-kernel, Daniel Mack, Robert Jarzmik, Rob Herring,
Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala, Russell King,
Thierry Reding, Jonathan Cameron, Dmitry Torokhov, Philipp Zabel,
Arnaud Ebalard, Kuninori Morimoto,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
moderated list:ARM PORT
On Tuesday 15 December 2015 19:42:07 Sergei Ianovich wrote:
> On Tue, 2015-12-15 at 17:32 +0100, Arnd Bergmann wrote:
> > On Tuesday 15 December 2015 19:27:50 Sergei Ianovich wrote:
> > > .../devicetree/bindings/vendor-prefixes.txt | 1 +
> > > arch/arm/boot/dts/Makefile | 3 +
> > > arch/arm/boot/dts/pxa27x-lp8x4x-i105.dts | 50 ++++
> > > arch/arm/boot/dts/pxa27x-lp8x4x.dts | 259
> > > +++++++++++++++++++++
> > > arch/arm/configs/lp8x4x_defconfig | 176
> > > ++++++++++++++
> > >
> >
> > I had not noticed earlier that you are adding a new defconfig file.
> > PXA is
> > already the platform with the most defconfig files, and I'd rather
> > like
> > to see that reduced than increased.
> >
> > Is there a chance you could merge this one with some of the existing
> > files
> > into one configuration that handles them all?
>
> There are several board-specific devices on LP8x4x: custom FPGA, custom
> UART, custom IRQ on FPGA, custom parallel bus for industrial IO. The
> defconfig file could alert potential users to this fact. If this is not
> a sufficient reason to have a defconfig file, it can be dropped.
>
> I use the full .config anyway
I would like those drivers to be enabled in some defconfig, so we get
compile-time coverage, but we generally stopped having one-config-per-board
files.
Maybe we can have a pxa_defconfig file that enables lots of boards
and then we remove the individual configs? We don't have to remove
them all at once, but it would make me very happy if we could at
least kill off some of the ones that are not used regularly.
Arnd
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH v5 2/2] arm: pxa27x: support for ICP DAS LP-8x4x w/ DT
2015-12-15 17:02 ` Arnd Bergmann
@ 2015-12-15 17:24 ` Sergei Ianovich
2015-12-15 18:06 ` Robert Jarzmik
2015-12-19 12:27 ` Robert Jarzmik
1 sibling, 1 reply; 148+ messages in thread
From: Sergei Ianovich @ 2015-12-15 17:24 UTC (permalink / raw)
To: Arnd Bergmann
Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA, Daniel Mack, Robert Jarzmik,
Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
Russell King, Thierry Reding, Jonathan Cameron, Dmitry Torokhov,
Philipp Zabel, Arnaud Ebalard, Kuninori Morimoto,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
moderated list:ARM PORT
On Tue, 2015-12-15 at 18:02 +0100, Arnd Bergmann wrote:
> On Tuesday 15 December 2015 19:42:07 Sergei Ianovich wrote:
> > There are several board-specific devices on LP8x4x: custom FPGA,
> > custom
> > UART, custom IRQ on FPGA, custom parallel bus for industrial IO. The
> > defconfig file could alert potential users to this fact. If this is
> > not
> > a sufficient reason to have a defconfig file, it can be dropped.
> >
> > I use the full .config anyway
>
> I would like those drivers to be enabled in some defconfig, so we get
> compile-time coverage, but we generally stopped having one-config-per-
> board
> files.
>
> Maybe we can have a pxa_defconfig file that enables lots of boards
> and then we remove the individual configs? We don't have to remove
> them all at once, but it would make me very happy if we could at
> least kill off some of the ones that are not used regularly.
lp8x4x seems to be the first pxa board which requires DT.
We can create pxa27x-dt_defconfig which selects:
1. PXA27X_DT
2. PXA_FB and 8250_PXA to enable console
3. MMC, MMC_PXA and EXT4_FS to enable boot from MMC
4. all optional pxa stuff as modules
5. all stuff on supported pxa boards as modules
If #5 is extended when support for new boards is added, it should be
possible to run any supported pxa27x board with pxa27x_defconfig.
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH v5 2/2] arm: pxa27x: support for ICP DAS LP-8x4x w/ DT
2015-12-15 17:24 ` Sergei Ianovich
@ 2015-12-15 18:06 ` Robert Jarzmik
2015-12-15 18:50 ` Sergei Ianovich
0 siblings, 1 reply; 148+ messages in thread
From: Robert Jarzmik @ 2015-12-15 18:06 UTC (permalink / raw)
To: Sergei Ianovich
Cc: Arnd Bergmann, linux-kernel, Daniel Mack, Rob Herring, Pawel Moll,
Mark Rutland, Ian Campbell, Kumar Gala, Russell King,
Thierry Reding, Jonathan Cameron, Dmitry Torokhov, Philipp Zabel,
Arnaud Ebalard, Kuninori Morimoto,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
moderated list:ARM PORT
Sergei Ianovich <ynvich@gmail.com> writes:
> On Tue, 2015-12-15 at 18:02 +0100, Arnd Bergmann wrote:
>> On Tuesday 15 December 2015 19:42:07 Sergei Ianovich wrote:
>> > There are several board-specific devices on LP8x4x: custom FPGA,
>> > custom
>> > UART, custom IRQ on FPGA, custom parallel bus for industrial IO. The
>> > defconfig file could alert potential users to this fact. If this is
>> > not
>> > a sufficient reason to have a defconfig file, it can be dropped.
>> >
>> > I use the full .config anyway
>>
>> I would like those drivers to be enabled in some defconfig, so we get
>> compile-time coverage, but we generally stopped having one-config-per-
>> board
>> files.
>>
>> Maybe we can have a pxa_defconfig file that enables lots of boards
>> and then we remove the individual configs? We don't have to remove
>> them all at once, but it would make me very happy if we could at
>> least kill off some of the ones that are not used regularly.
Yeah, I'd be happy too, that would simplify also my life.
Actually I was thinking of 2 defconfigs :
- one for platform_data based boards pxa2xx
- one for DT only boards pxa2xx
> lp8x4x seems to be the first pxa board which requires DT.
Most probably AFAIK.
> We can create pxa27x-dt_defconfig which selects:
> 1. PXA27X_DT
> 2. PXA_FB and 8250_PXA to enable console
> 3. MMC, MMC_PXA and EXT4_FS to enable boot from MMC
If you put MMC_PXA, one can argue why not any MTD device used on pxa devices,
such as pxa2xx-flash or docg3/docg4, etc ... I won't argue, I'm just pondering
about the right choice.
> 4. all optional pxa stuff as modules
> 5. all stuff on supported pxa boards as modules
> If #5 is extended when support for new boards is added, it should be
> possible to run any supported pxa27x board with pxa27x_defconfig.
I'm very eager to see a patch on that. I can feed my Jenkins with it, it would
greatly help me catch issues earlier. Moreover it would for free test it on
lubbock, mainstone and mioa701. If there was one also for pxa3xx, I would launch
it on zylonite cm-x300 ... (that's a bonus, I know :))
Cheers.
--
Robert
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH v5 2/2] arm: pxa27x: support for ICP DAS LP-8x4x w/ DT
2015-12-15 18:06 ` Robert Jarzmik
@ 2015-12-15 18:50 ` Sergei Ianovich
[not found] ` <1450205413.21989.44.camel-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
0 siblings, 1 reply; 148+ messages in thread
From: Sergei Ianovich @ 2015-12-15 18:50 UTC (permalink / raw)
To: Robert Jarzmik
Cc: Arnd Bergmann, linux-kernel, Daniel Mack, Rob Herring, Pawel Moll,
Mark Rutland, Ian Campbell, Kumar Gala, Russell King,
Thierry Reding, Jonathan Cameron, Dmitry Torokhov, Philipp Zabel,
Arnaud Ebalard, Kuninori Morimoto,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
moderated list:ARM PORT
On Tue, 2015-12-15 at 19:06 +0100, Robert Jarzmik wrote:
>
> > > Maybe we can have a pxa_defconfig file that enables lots of boards
> > > and then we remove the individual configs? We don't have to remove
> > > them all at once, but it would make me very happy if we could at
> > > least kill off some of the ones that are not used regularly.
> Yeah, I'd be happy too, that would simplify also my life.
>
> Actually I was thinking of 2 defconfigs :
> - one for platform_data based boards pxa2xx
> - one for DT only boards pxa2xx
I sincerely hope that dealing with ancient platform_data defconfigs is
out of the scope this patch.
> > lp8x4x seems to be the first pxa board which requires DT.
> Most probably AFAIK.
>
> > We can create pxa27x-dt_defconfig which selects:
> > 1. PXA27X_DT
> > 2. PXA_FB and 8250_PXA to enable console
> > 3. MMC, MMC_PXA and EXT4_FS to enable boot from MMC
> If you put MMC_PXA, one can argue why not any MTD device used on pxa
> devices,
> such as pxa2xx-flash or docg3/docg4, etc ... I won't argue, I'm just
> pondering
> about the right choice.
Great point. We should enable MTD for sure. There is no PXA-specific MTD
drivers, however. That's why MTD failed the grep test.
> > 4. all optional pxa stuff as modules
> > 5. all stuff on supported pxa boards as modules
>
> > If #5 is extended when support for new boards is added, it should be
> > possible to run any supported pxa27x board with pxa27x_defconfig.
>
> I'm very eager to see a patch on that. I can feed my Jenkins with it,
> it would
> greatly help me catch issues earlier. Moreover it would for free test
> it on
> lubbock, mainstone and mioa701. If there was one also for pxa3xx, I
> would launch
> it on zylonite cm-x300 ... (that's a bonus, I know :))
>
Updated plan:
1. MACH_PXA27X_DT
2. PXA_FB and 8250_PXA to enable console
3. MMC, MMC_PXA and EXT4_FS to enable boot from MMC
3.1. MTD, MTD_CFI, MTD_PHYSMAP_OF and JFFS2_FS to enable boot from MTD
4. all optional pxa stuff as modules
5. all stuff on supported pxa boards as modules
6. supported boards should boot the kernel built with
`pxa27x-dt_defconfig` after `make olddefconfig`
It is probably a good idea to put this plan somewhere in Documentation/
and to have a comment about that in the defconfig itself.
Is the plan acceptable?
^ permalink raw reply [flat|nested] 148+ messages in thread
* [PATCH v5] mtd: support BB SRAM on ICP DAS LP-8x4x
[not found] ` <1397668667-27328-4-git-send-email-ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2015-12-15 18:58 ` Sergei Ianovich
2015-12-20 3:38 ` Rob Herring
[not found] ` <1450205941-15593-1-git-send-email-ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
0 siblings, 2 replies; 148+ messages in thread
From: Sergei Ianovich @ 2015-12-15 18:58 UTC (permalink / raw)
To: linux-kernel-u79uwXL29TY76Z2rM5mHXA
Cc: Sergei Ianovich, Rob Herring, Pawel Moll, Mark Rutland,
Ian Campbell, Kumar Gala, David Woodhouse, Brian Norris,
Jeremy Kerr, Cyril Bur, Neelesh Gupta, Michael Ellerman,
Joel Stanley,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list:MEMORY TECHNOLOGY DEVICES MTD
This provides an MTD device driver for 512kB of battery backed up SRAM
on ICPDAS LP-8X4X programmable automation controllers.
SRAM chip is connected via FPGA and is not accessible without a driver,
unlike flash memory which is wired to CPU MMU.
This SRAM becomes an excellent persisent storage of volatile process
data like counter values and sensor statuses. Storing those data in
flash or mmc card is not a viable solution.
Signed-off-by: Sergei Ianovich <ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Reviewed-by: Brian Norris <computersforpeace-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
v4..v5
* remove .owner from struct platform_driver
* constify struct of_device_id
for further Brian Norris comments:
* drop unused property from doc file
* move defconfig update to a different file
* drop extra match w/ of_match_device()
v3..v4 for Brian Norris 'Reviewed-by'
* add doc file for DT binding
* move DTS binding to a different patch (8/21)
* drop unused include directive
* drop safely unused callback
* drop non-default partion probe types
* drop duplicate error checks
* drop duplicate error reporting
* fixed error message on MTD registeration
* fixed module removal routine
v2..v3
* no changes (except number 08/16 -> 10/21)
v0..v2
* use device tree
* use devm helpers where possible
.../devicetree/bindings/mtd/sram-lp8x4x.txt | 20 +++
drivers/mtd/devices/Kconfig | 14 ++
drivers/mtd/devices/Makefile | 1 +
drivers/mtd/devices/sram_lp8x4x.c | 199 +++++++++++++++++++++
4 files changed, 234 insertions(+)
create mode 100644 Documentation/devicetree/bindings/mtd/sram-lp8x4x.txt
create mode 100644 drivers/mtd/devices/sram_lp8x4x.c
diff --git a/Documentation/devicetree/bindings/mtd/sram-lp8x4x.txt b/Documentation/devicetree/bindings/mtd/sram-lp8x4x.txt
new file mode 100644
index 0000000..476934f
--- /dev/null
+++ b/Documentation/devicetree/bindings/mtd/sram-lp8x4x.txt
@@ -0,0 +1,20 @@
+512kB battery backed up SRAM on LP-8x4x industrial computers
+
+Required properties:
+- compatible : should be "icpdas,sram-lp8x4x"
+
+- reg: physical base addresses and region lengths of
+ * IO memory range
+ * SRAM page selector
+
+SRAM chip is connected via FPGA and is not accessible without a driver,
+unlike flash memory which is wired to CPU MMU. Driver is essentially
+an address translation routine.
+
+Example:
+
+ sram@a000 {
+ compatible = "icpdas,sram-lp8x4x";
+ reg = <0xa000 0x1000
+ 0x901e 0x1>;
+ };
diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig
index f73c416..a4573f6 100644
--- a/drivers/mtd/devices/Kconfig
+++ b/drivers/mtd/devices/Kconfig
@@ -233,4 +233,18 @@ config BCH_CONST_T
default 4
endif
+config MTD_SRAM_LP8X4X
+ tristate "SRAM on ICPDAS LP-8X4X"
+ depends on OF && ARCH_PXA
+ ---help---
+ This provides an MTD device driver for 512kiB of battery backed up SRAM
+ on ICPDAS LP-8X4X programmable automation controllers.
+
+ SRAM chip is connected via FPGA and is not accessible without a driver,
+ unlike flash memory which is wired to CPU MMU.
+
+ Say N, unless you plan to run this kernel on LP-8X4X.
+
+ If you say M, the module will be called sram_lp8x4x.
+
endmenu
diff --git a/drivers/mtd/devices/Makefile b/drivers/mtd/devices/Makefile
index 7912d3a..2fd5b7a 100644
--- a/drivers/mtd/devices/Makefile
+++ b/drivers/mtd/devices/Makefile
@@ -17,6 +17,7 @@ obj-$(CONFIG_MTD_SST25L) += sst25l.o
obj-$(CONFIG_MTD_BCM47XXSFLASH) += bcm47xxsflash.o
obj-$(CONFIG_MTD_ST_SPI_FSM) += st_spi_fsm.o
obj-$(CONFIG_MTD_POWERNV_FLASH) += powernv_flash.o
+obj-$(CONFIG_MTD_SRAM_LP8X4X) += sram_lp8x4x.o
CFLAGS_docg3.o += -I$(src)
diff --git a/drivers/mtd/devices/sram_lp8x4x.c b/drivers/mtd/devices/sram_lp8x4x.c
new file mode 100644
index 0000000..e43c7a7
--- /dev/null
+++ b/drivers/mtd/devices/sram_lp8x4x.c
@@ -0,0 +1,199 @@
+/*
+ * linux/drivers/mtd/devices/lp8x4x_sram.c
+ *
+ * MTD Driver for SRAM on ICPDAS LP-8x4x
+ * Copyright (C) 2013 Sergei Ianovich <ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation or any later version.
+ */
+
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/platform_device.h>
+#include <linux/of_device.h>
+#include <linux/slab.h>
+#include <linux/string_helpers.h>
+#include <linux/types.h>
+
+struct lp8x4x_sram_info {
+ void __iomem *bank;
+ void __iomem *virt;
+ struct mutex lock;
+ unsigned active_bank;
+ struct mtd_info mtd;
+};
+
+static int
+lp8x4x_sram_erase(struct mtd_info *mtd, struct erase_info *instr)
+{
+ struct lp8x4x_sram_info *info = mtd->priv;
+ unsigned bank = instr->addr >> 11;
+ unsigned offset = (instr->addr & 0x7ff) << 1;
+ loff_t i;
+
+ mutex_lock(&info->lock);
+ if (unlikely(bank != info->active_bank)) {
+ info->active_bank = bank;
+ iowrite8(bank, info->bank);
+ }
+ for (i = 0; i < instr->len; i++) {
+ iowrite8(0xff, info->virt + offset);
+ offset += 2;
+ if (unlikely(offset == 0)) {
+ info->active_bank++;
+ iowrite8(info->active_bank, info->bank);
+ }
+ }
+ mutex_unlock(&info->lock);
+ instr->state = MTD_ERASE_DONE;
+ mtd_erase_callback(instr);
+
+ return 0;
+}
+
+static int
+lp8x4x_sram_write(struct mtd_info *mtd, loff_t to, size_t len,
+ size_t *retlen, const u_char *b)
+{
+ struct lp8x4x_sram_info *info = mtd->priv;
+ unsigned bank = to >> 11;
+ unsigned offset = (to & 0x7ff) << 1;
+ loff_t i;
+
+ mutex_lock(&info->lock);
+ if (unlikely(bank != info->active_bank)) {
+ info->active_bank = bank;
+ iowrite8(bank, info->bank);
+ }
+ for (i = 0; i < len; i++) {
+ iowrite8(b[i], info->virt + offset);
+ offset += 2;
+ if (unlikely(offset == 0)) {
+ info->active_bank++;
+ iowrite8(info->active_bank, info->bank);
+ }
+ }
+ mutex_unlock(&info->lock);
+ *retlen = len;
+ return 0;
+}
+
+static int
+lp8x4x_sram_read(struct mtd_info *mtd, loff_t from, size_t len,
+ size_t *retlen, u_char *b)
+{
+ struct lp8x4x_sram_info *info = mtd->priv;
+ unsigned bank = from >> 11;
+ unsigned offset = (from & 0x7ff) << 1;
+ loff_t i;
+
+ mutex_lock(&info->lock);
+ if (unlikely(bank != info->active_bank)) {
+ info->active_bank = bank;
+ iowrite8(bank, info->bank);
+ }
+ for (i = 0; i < len; i++) {
+ b[i] = ioread8(info->virt + offset);
+ offset += 2;
+ if (unlikely(offset == 0)) {
+ info->active_bank++;
+ iowrite8(info->active_bank, info->bank);
+ }
+ }
+ mutex_unlock(&info->lock);
+ *retlen = len;
+ return 0;
+}
+
+static const struct of_device_id of_flash_match[] = {
+ {
+ .compatible = "icpdas,sram-lp8x4x",
+ },
+ { },
+};
+MODULE_DEVICE_TABLE(of, of_flash_match);
+
+static int
+lp8x4x_sram_probe(struct platform_device *pdev)
+{
+ struct lp8x4x_sram_info *info;
+ struct resource *res_virt, *res_bank;
+ char sz_str[16];
+ struct mtd_part_parser_data ppdata;
+ int err = 0;
+
+ info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
+ if (!info)
+ return -ENOMEM;
+
+ res_virt = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ info->virt = devm_ioremap_resource(&pdev->dev, res_virt);
+ if (IS_ERR(info->virt))
+ return PTR_ERR(info->virt);
+
+ res_bank = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ info->bank = devm_ioremap_resource(&pdev->dev, res_bank);
+ if (IS_ERR(info->bank))
+ return PTR_ERR(info->bank);
+
+ info->mtd.priv = info;
+ info->mtd.name = "SRAM";
+ info->mtd.type = MTD_RAM;
+ info->mtd.flags = MTD_CAP_RAM;
+ info->mtd.size = resource_size(res_virt) << 7;
+ info->mtd.erasesize = 512;
+ info->mtd.writesize = 4;
+ info->mtd._erase = lp8x4x_sram_erase;
+ info->mtd._write = lp8x4x_sram_write;
+ info->mtd._read = lp8x4x_sram_read;
+ info->mtd.owner = THIS_MODULE;
+
+ mutex_init(&info->lock);
+ iowrite8(info->active_bank, info->bank);
+ platform_set_drvdata(pdev, info);
+
+ ppdata.of_node = pdev->dev.of_node;
+ err = mtd_device_parse_register(&info->mtd, NULL, &ppdata,
+ NULL, 0);
+
+ if (err < 0) {
+ dev_err(&pdev->dev, "failed to register MTD\n");
+ return err;
+ }
+
+ string_get_size(info->mtd.size, 1, STRING_UNITS_2, sz_str,
+ sizeof(sz_str));
+ dev_info(&pdev->dev, "using %s SRAM on LP-8X4X as %s\n", sz_str,
+ dev_name(&info->mtd.dev));
+ return 0;
+}
+
+static int
+lp8x4x_sram_remove(struct platform_device *dev)
+{
+ struct lp8x4x_sram_info *info = platform_get_drvdata(dev);
+
+ return mtd_device_unregister(&info->mtd);
+}
+
+static struct platform_driver lp8x4x_sram_driver = {
+ .driver = {
+ .name = "sram-lp8x4x",
+ .of_match_table = of_flash_match,
+ },
+ .probe = lp8x4x_sram_probe,
+ .remove = lp8x4x_sram_remove,
+};
+
+module_platform_driver(lp8x4x_sram_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Sergei Ianovich <ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>");
+MODULE_DESCRIPTION("MTD driver for SRAM on ICPDAS LP-8x4x");
--
2.6.2
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 148+ messages in thread
* Re: [PATCH v5 2/2] arm: pxa27x: support for ICP DAS LP-8x4x w/ DT
[not found] ` <1450205413.21989.44.camel-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2015-12-15 19:21 ` Arnd Bergmann
2015-12-15 20:01 ` Robert Jarzmik
0 siblings, 1 reply; 148+ messages in thread
From: Arnd Bergmann @ 2015-12-15 19:21 UTC (permalink / raw)
To: Sergei Ianovich
Cc: Robert Jarzmik, linux-kernel-u79uwXL29TY76Z2rM5mHXA, Daniel Mack,
Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
Russell King, Thierry Reding, Jonathan Cameron, Dmitry Torokhov,
Philipp Zabel, Arnaud Ebalard, Kuninori Morimoto,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
moderated list:ARM PORT
On Tuesday 15 December 2015 21:50:13 Sergei Ianovich wrote:
> On Tue, 2015-12-15 at 19:06 +0100, Robert Jarzmik wrote:
> > > 4. all optional pxa stuff as modules
> > > 5. all stuff on supported pxa boards as modules
> >
> > > If #5 is extended when support for new boards is added, it should be
> > > possible to run any supported pxa27x board with pxa27x_defconfig.
> >
> > I'm very eager to see a patch on that. I can feed my Jenkins with it,
> > it would
> > greatly help me catch issues earlier. Moreover it would for free test
> > it on
> > lubbock, mainstone and mioa701. If there was one also for pxa3xx, I
> > would launch
> > it on zylonite cm-x300 ... (that's a bonus, I know :))
> >
>
> Updated plan:
> 1. MACH_PXA27X_DT
> 2. PXA_FB and 8250_PXA to enable console
> 3. MMC, MMC_PXA and EXT4_FS to enable boot from MMC
> 3.1. MTD, MTD_CFI, MTD_PHYSMAP_OF and JFFS2_FS to enable boot from MTD
> 4. all optional pxa stuff as modules
> 5. all stuff on supported pxa boards as modules
> 6. supported boards should boot the kernel built with
> `pxa27x-dt_defconfig` after `make olddefconfig`
>
> It is probably a good idea to put this plan somewhere in Documentation/
> and to have a comment about that in the defconfig itself.
>
> Is the plan acceptable?
Sounds good to me.
Arnd
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 148+ messages in thread
* [PATCH v5] arm: pxa: support ICP DAS LP-8x4x FPGA irq
[not found] ` <1397668667-27328-5-git-send-email-ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2015-12-15 19:26 ` Sergei Ianovich
2015-12-16 11:54 ` Marc Zyngier
` (3 more replies)
0 siblings, 4 replies; 148+ messages in thread
From: Sergei Ianovich @ 2015-12-15 19:26 UTC (permalink / raw)
To: linux-kernel-u79uwXL29TY76Z2rM5mHXA
Cc: Linus Walleij, Sergei Ianovich, Arnd Bergmann, Thomas Gleixner,
Jason Cooper, Marc Zyngier, Rob Herring, Pawel Moll, Mark Rutland,
Ian Campbell, Kumar Gala,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS
ICP DAS LP-8x4x contains FPGA chip. The chip functions as an interrupt
source providing 16 additional interrupts among other things. The
interrupt lines are muxed to a GPIO pin of a 2nd level PXA-GPIO
interrupt controller. GPIO pins of the 2nd level controller are in turn
muxed to a CPU interrupt line.
Until pxa is completely converted to device tree, it is impossible
to use IRQCHIP_DECLARE() and the irqdomain needs to added manually.
Drivers for the on-CPU IRQs and GPIO-IRQs are loaded using
postcore_initcall(). We need to have all irq domain drivers loaded prior
to DT parsing in order to allow normal initialization of IRQ resources
with DT.
Signed-off-by: Sergei Ianovich <ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Reviewed-by: Linus Walleij <linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
CC: Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org>
---
v4..v5
* constify struct of_device_id
* drop irq number from handler signature
v3.2..v4
* move DTS binding to a different patch (8/21)
v3.1..v3.2
fixes to apply Linus Walleij's "Reviewed-by":
* add kerneldoc comment for state container struct
* rename irq -> hwirq for clarity
* drop overzealous error checks from the hotpaths
v3..v3.1
fixes according to Linus Walleij review comments:
* update commit message
* use state container instead of global variables
* get hardware irq nums from irq_data, don't calculate them
* use BIT() macro
* add defines for system irq register masks
* replace cycle control variable with break
* use better names for resource variables
* add a linear domain instead of a legacy one
* use irq_create_mapping() instead of irq_alloc_desc()
v2..v3
* no changes (except number 09/16 -> 11/21)
v0..v2
* extract irqchip and move to drivers/irqchip/
* use device tree
* use devm helpers where possible
.../bindings/interrupt-controller/irq-lp8x4x.txt | 49 +++++
drivers/irqchip/Kconfig | 5 +
drivers/irqchip/Makefile | 1 +
drivers/irqchip/irq-lp8x4x.c | 227 +++++++++++++++++++++
4 files changed, 282 insertions(+)
create mode 100644 Documentation/devicetree/bindings/interrupt-controller/irq-lp8x4x.txt
create mode 100644 drivers/irqchip/irq-lp8x4x.c
diff --git a/Documentation/devicetree/bindings/interrupt-controller/irq-lp8x4x.txt b/Documentation/devicetree/bindings/interrupt-controller/irq-lp8x4x.txt
new file mode 100644
index 0000000..c8940d2
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/irq-lp8x4x.txt
@@ -0,0 +1,49 @@
+ICP DAS LP-8x4x FPGA Interrupt Controller
+
+ICP DAS LP-8x4x contains FPGA chip. The chip functions as a interrupt
+source providing 16 additional interrupts among other things.
+
+Required properties:
+- compatible : should be "icpdas,irq-lp8x4x"
+
+- reg: physical base address of the controller and length of memory mapped
+ region.
+
+- interrupt-controller : identifies the node as an interrupt controller
+
+- #interrupt-cells : should be 1
+
+- interrupts : should provide interrupt
+
+- interrupt-parent : should provide a link to interrupt controller either
+ explicitly and implicitly from a parent node
+
+Example:
+
+ fpga: fpga@17000006 {
+ compatible = "icpdas,irq-lp8x4x";
+ reg = <0x17000006 0x16>;
+ interrupt-parent = <&gpio>;
+ interrupts = <3 IRQ_TYPE_EDGE_RISING>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ status = "okay";
+ };
+
+ uart@17009050 {
+ compatible = "icpdas,uart-lp8x4x";
+ reg = <0x17009050 0x10
+ 0x17009030 0x02>;
+ interrupt-parent = <&fpga>;
+ interrupts = <13>;
+ status = "okay";
+ };
+
+ uart@17009060 {
+ compatible = "icpdas,uart-lp8x4x";
+ reg = <0x17009060 0x10
+ 0x17009032 0x02>;
+ interrupt-parent = <&fpga>;
+ interrupts = <14>;
+ status = "okay";
+ };
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 4d7294e..1de7361 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -193,3 +193,8 @@ config IRQ_MXS
def_bool y if MACH_ASM9260 || ARCH_MXS
select IRQ_DOMAIN
select STMP_DEVICE
+
+config LP8X4X_IRQ
+ bool
+ depends on OF && ARCH_PXA
+ select IRQ_DOMAIN
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index 177f78f..ab9ca67 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -55,3 +55,4 @@ obj-$(CONFIG_RENESAS_H8S_INTC) += irq-renesas-h8s.o
obj-$(CONFIG_ARCH_SA1100) += irq-sa11x0.o
obj-$(CONFIG_INGENIC_IRQ) += irq-ingenic.o
obj-$(CONFIG_IMX_GPCV2) += irq-imx-gpcv2.o
+obj-$(CONFIG_LP8X4X_IRQ) += irq-lp8x4x.o
diff --git a/drivers/irqchip/irq-lp8x4x.c b/drivers/irqchip/irq-lp8x4x.c
new file mode 100644
index 0000000..a03d925
--- /dev/null
+++ b/drivers/irqchip/irq-lp8x4x.c
@@ -0,0 +1,227 @@
+/*
+ * linux/drivers/irqchip/irq-lp8x4x.c
+ *
+ * Support for ICP DAS LP-8x4x FPGA irq
+ * Copyright (C) 2013 Sergei Ianovich <ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation or any later version.
+ */
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+
+#define EOI 0x00000000
+#define INSINT 0x00000002
+#define ENSYSINT 0x00000004
+#define PRIMINT 0x00000006
+#define PRIMINT_MASK 0xe0
+#define SECOINT 0x00000008
+#define SECOINT_MASK 0x1f
+#define ENRISEINT 0x0000000A
+#define CLRRISEINT 0x0000000C
+#define ENHILVINT 0x0000000E
+#define CLRHILVINT 0x00000010
+#define ENFALLINT 0x00000012
+#define CLRFALLINT 0x00000014
+#define IRQ_MEM_SIZE 0x00000016
+#define LP8X4X_NUM_IRQ_DEFAULT 16
+
+/**
+ * struct lp8x4x_irq_data - LP8X4X custom irq controller state container
+ * @base: base IO memory address
+ * @irq_domain: Interrupt translation domain; responsible for mapping
+ * between hwirq number and linux irq number
+ * @irq_sys_enabled: mask keeping track of interrupts enabled in the
+ * register which vendor calls 'system'
+ * @irq_high_enabled: mask keeping track of interrupts enabled in the
+ * register which vendor calls 'high'
+ *
+ * The structure implements State Container from
+ * Documentation/driver-model/design-patterns.txt
+ */
+
+struct lp8x4x_irq_data {
+ void *base;
+ struct irq_domain *domain;
+ unsigned char irq_sys_enabled;
+ unsigned char irq_high_enabled;
+};
+
+static void lp8x4x_mask_irq(struct irq_data *d)
+{
+ unsigned mask;
+ unsigned long hwirq = d->hwirq;
+ struct lp8x4x_irq_data *host = irq_data_get_irq_chip_data(d);
+
+ if (hwirq < 8) {
+ host->irq_high_enabled &= ~BIT(hwirq);
+
+ mask = ioread8(host->base + ENHILVINT);
+ mask &= ~BIT(hwirq);
+ iowrite8(mask, host->base + ENHILVINT);
+ } else {
+ hwirq -= 8;
+ host->irq_sys_enabled &= ~BIT(hwirq);
+
+ mask = ioread8(host->base + ENSYSINT);
+ mask &= ~BIT(hwirq);
+ iowrite8(mask, host->base + ENSYSINT);
+ }
+}
+
+static void lp8x4x_unmask_irq(struct irq_data *d)
+{
+ unsigned mask;
+ unsigned long hwirq = d->hwirq;
+ struct lp8x4x_irq_data *host = irq_data_get_irq_chip_data(d);
+
+ if (hwirq < 8) {
+ host->irq_high_enabled |= BIT(hwirq);
+ mask = ioread8(host->base + CLRHILVINT);
+ mask |= BIT(hwirq);
+ iowrite8(mask, host->base + CLRHILVINT);
+
+ mask = ioread8(host->base + ENHILVINT);
+ mask |= BIT(hwirq);
+ iowrite8(mask, host->base + ENHILVINT);
+ } else {
+ hwirq -= 8;
+ host->irq_sys_enabled |= BIT(hwirq);
+
+ mask = ioread8(host->base + SECOINT);
+ mask |= BIT(hwirq);
+ iowrite8(mask, host->base + SECOINT);
+
+ mask = ioread8(host->base + ENSYSINT);
+ mask |= BIT(hwirq);
+ iowrite8(mask, host->base + ENSYSINT);
+ }
+}
+
+static struct irq_chip lp8x4x_irq_chip = {
+ .name = "FPGA",
+ .irq_ack = lp8x4x_mask_irq,
+ .irq_mask = lp8x4x_mask_irq,
+ .irq_mask_ack = lp8x4x_mask_irq,
+ .irq_unmask = lp8x4x_unmask_irq,
+};
+
+static void lp8x4x_irq_handler(struct irq_desc *desc)
+{
+ int n;
+ unsigned long mask;
+ struct irq_chip *chip = irq_desc_get_chip(desc);
+ struct lp8x4x_irq_data *host = irq_desc_get_handler_data(desc);
+
+ chained_irq_enter(chip, desc);
+
+ for (;;) {
+ mask = ioread8(host->base + CLRHILVINT) & 0xff;
+ mask |= (ioread8(host->base + SECOINT) & SECOINT_MASK) << 8;
+ mask |= (ioread8(host->base + PRIMINT) & PRIMINT_MASK) << 8;
+ mask &= host->irq_high_enabled | (host->irq_sys_enabled << 8);
+ if (mask == 0)
+ break;
+ for_each_set_bit(n, &mask, BITS_PER_LONG)
+ generic_handle_irq(irq_find_mapping(host->domain, n));
+ }
+
+ iowrite8(0, host->base + EOI);
+ chained_irq_exit(chip, desc);
+}
+
+static int lp8x4x_irq_domain_map(struct irq_domain *d, unsigned int irq,
+ irq_hw_number_t hw)
+{
+ struct lp8x4x_irq_data *host = d->host_data;
+ int err;
+
+ err = irq_set_chip_data(irq, host);
+ if (err < 0)
+ return err;
+
+ irq_set_chip_and_handler(irq, &lp8x4x_irq_chip, handle_level_irq);
+ irq_set_probe(irq);
+ return 0;
+}
+
+const struct irq_domain_ops lp8x4x_irq_domain_ops = {
+ .map = lp8x4x_irq_domain_map,
+ .xlate = irq_domain_xlate_onecell,
+};
+
+static const struct of_device_id lp8x4x_irq_dt_ids[] = {
+ { .compatible = "icpdas,irq-lp8x4x", },
+ {}
+};
+
+static int lp8x4x_irq_probe(struct platform_device *pdev)
+{
+ struct resource *res_mem, *res_irq;
+ struct device_node *np = pdev->dev.of_node;
+ struct lp8x4x_irq_data *host;
+ int i, err;
+
+ res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (!res_mem || !res_irq || resource_size(res_mem) < IRQ_MEM_SIZE)
+ return -ENODEV;
+
+ host = devm_kzalloc(&pdev->dev, sizeof(*host), GFP_KERNEL);
+ if (!host)
+ return -ENODEV;
+
+ host->base = devm_ioremap_resource(&pdev->dev, res_mem);
+ if (!host->base) {
+ dev_err(&pdev->dev, "Failed to ioremap %p\n", host->base);
+ return -EFAULT;
+ }
+
+ host->domain = irq_domain_add_linear(np, LP8X4X_NUM_IRQ_DEFAULT,
+ &lp8x4x_irq_domain_ops, host);
+ if (!host->domain) {
+ dev_err(&pdev->dev, "Failed to add IRQ domain\n");
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < LP8X4X_NUM_IRQ_DEFAULT; i++) {
+ err = irq_create_mapping(host->domain, i);
+ if (err < 0)
+ dev_err(&pdev->dev, "Failed to map IRQ %i\n", i);
+ }
+
+ /* Initialize chip registers */
+ iowrite8(0, host->base + CLRRISEINT);
+ iowrite8(0, host->base + ENRISEINT);
+ iowrite8(0, host->base + CLRFALLINT);
+ iowrite8(0, host->base + ENFALLINT);
+ iowrite8(0, host->base + CLRHILVINT);
+ iowrite8(0, host->base + ENHILVINT);
+ iowrite8(0, host->base + ENSYSINT);
+ iowrite8(0, host->base + SECOINT);
+
+ irq_set_handler_data(res_irq->start, host);
+ irq_set_chained_handler(res_irq->start, lp8x4x_irq_handler);
+
+ return 0;
+}
+
+static struct platform_driver lp8x4x_irq_driver = {
+ .probe = lp8x4x_irq_probe,
+ .driver = {
+ .name = "irq-lp8x4x",
+ .of_match_table = lp8x4x_irq_dt_ids,
+ },
+};
+
+static int __init lp8x4x_irq_init(void)
+{
+ return platform_driver_register(&lp8x4x_irq_driver);
+}
+postcore_initcall(lp8x4x_irq_init);
--
2.6.2
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 148+ messages in thread
* Re: [PATCH v5 2/2] arm: pxa27x: support for ICP DAS LP-8x4x w/ DT
2015-12-15 19:21 ` Arnd Bergmann
@ 2015-12-15 20:01 ` Robert Jarzmik
2015-12-15 20:40 ` Arnd Bergmann
0 siblings, 1 reply; 148+ messages in thread
From: Robert Jarzmik @ 2015-12-15 20:01 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Sergei Ianovich, linux-kernel, Daniel Mack, Rob Herring,
Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala, Russell King,
Thierry Reding, Jonathan Cameron, Dmitry Torokhov, Philipp Zabel,
Arnaud Ebalard, Kuninori Morimoto,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
moderated list:ARM PORT
Arnd Bergmann <arnd@arndb.de> writes:
> On Tuesday 15 December 2015 21:50:13 Sergei Ianovich wrote:
>> On Tue, 2015-12-15 at 19:06 +0100, Robert Jarzmik wrote:
>> Updated plan:
>> 1. MACH_PXA27X_DT
>> 2. PXA_FB and 8250_PXA to enable console
What about gpio-pxa ? And maybe pinctrl-pxa27x (only in linux-next by now) ? Can
a pxafb work without gpio-pxa ? Also usually for pxafb you have pwm and pwm_bl
to see something.
>> 3. MMC, MMC_PXA and EXT4_FS to enable boot from MMC
>> 3.1. MTD, MTD_CFI, MTD_PHYSMAP_OF and JFFS2_FS to enable boot from MTD
Ok. Is pxa2xx-pcmcia out of scope ? I seem to remember we have several boards
where pcmcia is the rootfs (even if that is a small mess right now I still have
to work on). Or do we consider pcmcia as obsolete ?
>> 4. all optional pxa stuff as modules
>> 5. all stuff on supported pxa boards as modules
>> 6. supported boards should boot the kernel built with
>> `pxa27x-dt_defconfig` after `make olddefconfig`
>>
>> It is probably a good idea to put this plan somewhere in Documentation/
>> and to have a comment about that in the defconfig itself.
>>
>> Is the plan acceptable?
>
> Sounds good to me.
Sounds good to me too.
Cheers.
--
Robert
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH v5 2/2] arm: pxa27x: support for ICP DAS LP-8x4x w/ DT
2015-12-15 20:01 ` Robert Jarzmik
@ 2015-12-15 20:40 ` Arnd Bergmann
0 siblings, 0 replies; 148+ messages in thread
From: Arnd Bergmann @ 2015-12-15 20:40 UTC (permalink / raw)
To: linux-arm-kernel
Cc: Robert Jarzmik, Mark Rutland,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
Arnaud Ebalard, Russell King, Kuninori Morimoto, Pawel Moll,
Ian Campbell, Dmitry Torokhov, linux-kernel, Daniel Mack,
Sergei Ianovich, Rob Herring, Philipp Zabel, Kumar Gala,
Thierry Reding, Jonathan Cameron
On Tuesday 15 December 2015 21:01:35 Robert Jarzmik wrote:
> Arnd Bergmann <arnd@arndb.de> writes:
>
> > On Tuesday 15 December 2015 21:50:13 Sergei Ianovich wrote:
> >> On Tue, 2015-12-15 at 19:06 +0100, Robert Jarzmik wrote:
> >> Updated plan:
> >> 1. MACH_PXA27X_DT
> >> 2. PXA_FB and 8250_PXA to enable console
> What about gpio-pxa ? And maybe pinctrl-pxa27x (only in linux-next by now) ? Can
> a pxafb work without gpio-pxa ? Also usually for pxafb you have pwm and pwm_bl
> to see something.
>
> >> 3. MMC, MMC_PXA and EXT4_FS to enable boot from MMC
> >> 3.1. MTD, MTD_CFI, MTD_PHYSMAP_OF and JFFS2_FS to enable boot from MTD
> Ok. Is pxa2xx-pcmcia out of scope ? I seem to remember we have several boards
> where pcmcia is the rootfs (even if that is a small mess right now I still have
> to work on). Or do we consider pcmcia as obsolete ?
I'm definitely fine with tossing in everything that is PXA specific,
even if it's rarely used.
If someone wants a smaller kernel, they can still start out with the
defconfig and disable stuff they don't need, which tends to be easier
than the opposite, and it gives us compile-time coverage with the
autobuilders that compile every defconfig.
Arnd
^ permalink raw reply [flat|nested] 148+ messages in thread
* [PATCH v5] serial: support for 16550A serial ports on LP-8x4x
[not found] ` <1397668667-27328-1-git-send-email-ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2015-12-15 21:04 ` Sergei Ianovich
2015-12-15 21:51 ` Arnd Bergmann
` (2 more replies)
0 siblings, 3 replies; 148+ messages in thread
From: Sergei Ianovich @ 2015-12-15 21:04 UTC (permalink / raw)
To: linux-kernel-u79uwXL29TY76Z2rM5mHXA
Cc: Sergei Ianovich, Alan Cox, Rob Herring, Pawel Moll, Mark Rutland,
Ian Campbell, Kumar Gala, Greg Kroah-Hartman, Jiri Slaby,
Heikki Krogerus, Andy Shevchenko, Arnd Bergmann, Scott Wood,
Masahiro Yamada, Sebastian Andrzej Siewior, Paul Burton,
Joachim Eastwood, Mans Rullgard, Paul Gortmaker, Peter Hurley,
open list:OPEN FIRMWARE AND FLATTENED
The patch adds support for 3 additional LP-8x4x built-in serial
ports.
The device can also host up to 8 extension cards with 4 serial ports
on each card for a total of 35 ports. However, I don't have
the hardware to test extension cards, so they are not supported, yet.
Signed-off-by: Sergei Ianovich <ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Reviewed-by: Heikki Krogerus <heikki.krogerus-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
CC: Alan Cox <gnomes-qBU/x9rampVanCEyBjwyrvXRex20P6io@public.gmane.org>
---
v4..v5
* constify struct of_device_id
* drop .owner from struct platform_driver
* rewrite set_termios() baud rate hadnling as suggested by Alan Cox
v3..v4
* move DTS bindings to a different patch (8/21) as suggested by
Heikki Krogerus
v2..v3
* no changes (except number 10/16 -> 12/21)
v0..v2
* register platform driver instead of platform device
* use device tree
* use devm helpers where possible
.../devicetree/bindings/serial/lp8x4x-serial.txt | 35 +++++
drivers/tty/serial/8250/8250_lp8x4x.c | 168 +++++++++++++++++++++
drivers/tty/serial/8250/Kconfig | 12 ++
drivers/tty/serial/8250/Makefile | 1 +
4 files changed, 216 insertions(+)
create mode 100644 Documentation/devicetree/bindings/serial/lp8x4x-serial.txt
create mode 100644 drivers/tty/serial/8250/8250_lp8x4x.c
diff --git a/Documentation/devicetree/bindings/serial/lp8x4x-serial.txt b/Documentation/devicetree/bindings/serial/lp8x4x-serial.txt
new file mode 100644
index 0000000..5f9a4c1
--- /dev/null
+++ b/Documentation/devicetree/bindings/serial/lp8x4x-serial.txt
@@ -0,0 +1,35 @@
+UART ports on ICP DAS LP-8x4x
+
+ICP DAS LP-8x4x contains three additional serial ports interfaced via
+Analog Devices ADM213EA chips in addition to 3 serial ports on PXA CPU.
+
+Required properties:
+- compatible : should be "icpdas,uart-lp8x4x"
+
+- reg : should provide 16 byte man IO memory region and 1 byte region for
+ termios
+
+- interrupts : should provide interrupt
+
+- interrupt-parent : should provide a link to interrupt controller either
+ explicitly or implicitly from a parent node
+
+Examples (from pxa27x-lp8x4x.dts):
+
+ uart@9050 {
+ compatible = "icpdas,uart-lp8x4x";
+ reg = <0x9050 0x10
+ 0x9030 0x02>;
+ interrupt-parent = <&fpgairg>;
+ interrupts = <13>;
+ status = "okay";
+ };
+
+ uart@9060 {
+ compatible = "icpdas,uart-lp8x4x";
+ reg = <0x9060 0x10
+ 0x9032 0x02>;
+ interrupt-parent = <&fpgairg>;
+ interrupts = <14>;
+ status = "okay";
+ };
diff --git a/drivers/tty/serial/8250/8250_lp8x4x.c b/drivers/tty/serial/8250/8250_lp8x4x.c
new file mode 100644
index 0000000..0e07220
--- /dev/null
+++ b/drivers/tty/serial/8250/8250_lp8x4x.c
@@ -0,0 +1,168 @@
+/* linux/drivers/tty/serial/8250/8250_lp8x4x.c
+ *
+ * Support for 16550A serial ports on ICP DAS LP-8x4x
+ *
+ * Copyright (C) 2013 Sergei Ianovich <ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+#include <linux/serial_8250.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+
+struct lp8x4x_serial_data {
+ int line;
+ void *ios_mem;
+};
+
+static void lp8x4x_serial_set_termios(struct uart_port *port,
+ struct ktermios *termios, struct ktermios *old)
+{
+ unsigned int len;
+ unsigned int baud;
+ struct lp8x4x_serial_data *data = port->private_data;
+
+ serial8250_do_set_termios(port, termios, old);
+
+ switch (termios->c_cflag & CSIZE) {
+ case CS5:
+ len = 7;
+ break;
+ case CS6:
+ len = 8;
+ break;
+ case CS7:
+ len = 9;
+ break;
+ default:
+ case CS8:
+ len = 10;
+ break;
+ }
+
+ if (termios->c_cflag & CSTOPB)
+ len++;
+ if (termios->c_cflag & PARENB)
+ len++;
+ if (!(termios->c_cflag & PARODD))
+ len++;
+#ifdef CMSPAR
+ if (termios->c_cflag & CMSPAR)
+ len++;
+#endif
+
+ len -= 9;
+ len &= 3;
+ len <<= 3;
+ /*
+ * Ask the core to calculate the divisor for us.
+ */
+ baud = tty_termios_baud_rate(termios);
+
+ switch (baud) {
+ case 115200:
+ len |= 7;
+ break;
+ case 57600:
+ len |= 6;
+ break;
+ case 38400:
+ len |= 5;
+ break;
+ case 19200:
+ len |= 4;
+ break;
+ case 9600:
+ len |= 3;
+ break;
+ case 4800:
+ len |= 2;
+ break;
+ case 2400:
+ default:
+ len |= 1;
+ break;
+ };
+ iowrite8(len, data->ios_mem);
+
+}
+
+static const struct of_device_id lp8x4x_serial_dt_ids[] = {
+ { .compatible = "icpdas,uart-lp8x4x", },
+ {}
+};
+MODULE_DEVICE_TABLE(of, lp8x4x_serial_dt_ids);
+
+static int lp8x4x_serial_probe(struct platform_device *pdev)
+{
+ struct uart_8250_port uart = {};
+ struct lp8x4x_serial_data *data;
+ struct resource *mmres, *mires, *irqres;
+ int ret;
+
+ mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ mires = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ irqres = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (!mmres || !mires || !irqres)
+ return -ENODEV;
+
+ data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ data->ios_mem = devm_ioremap_resource(&pdev->dev, mires);
+ if (!data->ios_mem)
+ return -EFAULT;
+
+ uart.port.iotype = UPIO_MEM;
+ uart.port.mapbase = mmres->start;
+ uart.port.iobase = mmres->start;
+ uart.port.regshift = 1;
+ uart.port.irq = irqres->start;
+ uart.port.flags = UPF_IOREMAP;
+ uart.port.dev = &pdev->dev;
+ uart.port.uartclk = 14745600;
+ uart.port.set_termios = lp8x4x_serial_set_termios;
+ uart.port.private_data = data;
+
+ ret = serial8250_register_8250_port(&uart);
+ if (ret < 0)
+ return ret;
+
+ data->line = ret;
+
+ platform_set_drvdata(pdev, data);
+
+ return 0;
+}
+
+static int lp8x4x_serial_remove(struct platform_device *pdev)
+{
+ struct lp8x4x_serial_data *data = platform_get_drvdata(pdev);
+
+ serial8250_unregister_port(data->line);
+
+ return 0;
+}
+
+static struct platform_driver lp8x4x_serial_driver = {
+ .probe = lp8x4x_serial_probe,
+ .remove = lp8x4x_serial_remove,
+
+ .driver = {
+ .name = "uart-lp8x4x",
+ .of_match_table = lp8x4x_serial_dt_ids,
+ },
+};
+
+module_platform_driver(lp8x4x_serial_driver);
+
+MODULE_AUTHOR("Sergei Ianovich");
+MODULE_DESCRIPTION("8250 serial port module for LP-8x4x");
+MODULE_LICENSE("GPL");
diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig
index 48b6253..00eb6b0 100644
--- a/drivers/tty/serial/8250/Kconfig
+++ b/drivers/tty/serial/8250/Kconfig
@@ -387,3 +387,15 @@ config SERIAL_8250_PXA
can enable its onboard serial ports by enabling this option.
If you choose M here, the module name will be 8250_pxa.
+
+config SERIAL_8250_LP8X4X
+ tristate "Support 16550A ports on ICP DAS LP-8x4x"
+ depends on OF && SERIAL_8250 && SERIAL_8250_MANY_PORTS && ARCH_PXA
+ select LP8X4X_IRQ
+ help
+ In addition to serial ports on PXA270 SoC, LP-8x4x has 1 dual
+ RS232/RS485 port, 1 RS485 port and 1 RS232 port.
+
+ Say N here, unless you plan to run this kernel on a LP-8x4x system.
+
+ If you choose M here, the module name will be 8250_lp8x4x.
diff --git a/drivers/tty/serial/8250/Makefile b/drivers/tty/serial/8250/Makefile
index 7e54413..8bdbf40 100644
--- a/drivers/tty/serial/8250/Makefile
+++ b/drivers/tty/serial/8250/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_SERIAL_8250_ACCENT) += 8250_accent.o
obj-$(CONFIG_SERIAL_8250_BOCA) += 8250_boca.o
obj-$(CONFIG_SERIAL_8250_EXAR_ST16C554) += 8250_exar_st16c554.o
obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o
+obj-$(CONFIG_SERIAL_8250_LP8X4X) += 8250_lp8x4x.o
obj-$(CONFIG_SERIAL_8250_FSL) += 8250_fsl.o
obj-$(CONFIG_SERIAL_8250_DW) += 8250_dw.o
obj-$(CONFIG_SERIAL_8250_EM) += 8250_em.o
--
2.6.2
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 148+ messages in thread
* Re: [PATCH v5] serial: support for 16550A serial ports on LP-8x4x
2015-12-15 21:04 ` [PATCH v5] serial: support for 16550A serial ports on LP-8x4x Sergei Ianovich
@ 2015-12-15 21:51 ` Arnd Bergmann
2015-12-16 8:04 ` Sergei Ianovich
2015-12-19 21:42 ` Sergei Ianovich
2015-12-17 14:50 ` Andy Shevchenko
[not found] ` <1450213494-21884-1-git-send-email-ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2 siblings, 2 replies; 148+ messages in thread
From: Arnd Bergmann @ 2015-12-15 21:51 UTC (permalink / raw)
To: Sergei Ianovich
Cc: linux-kernel, Alan Cox, Rob Herring, Pawel Moll, Mark Rutland,
Ian Campbell, Kumar Gala, Greg Kroah-Hartman, Jiri Slaby,
Heikki Krogerus, Andy Shevchenko, Scott Wood, Masahiro Yamada,
Sebastian Andrzej Siewior, Paul Burton, Joachim Eastwood,
Mans Rullgard, Paul Gortmaker, Peter Hurley,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS
On Wednesday 16 December 2015 00:04:45 Sergei Ianovich wrote:
> index 0000000..5f9a4c1
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/serial/lp8x4x-serial.txt
> @@ -0,0 +1,35 @@
> +UART ports on ICP DAS LP-8x4x
> +
> +ICP DAS LP-8x4x contains three additional serial ports interfaced via
> +Analog Devices ADM213EA chips in addition to 3 serial ports on PXA CPU.
> +
> +Required properties:
> +- compatible : should be "icpdas,uart-lp8x4x"
Compatible strings should not include a 'x' wildcard like this, better use
the specific chip name.
Also, it sounds like you named them after the board vendor, which sounds
wrong as the vendor part of the compatible string should be the whoever
made that part (analog?)
> +- reg : should provide 16 byte man IO memory region and 1 byte region for
> + termios
> +
> +- interrupts : should provide interrupt
> +
> +- interrupt-parent : should provide a link to interrupt controller either
> + explicitly or implicitly from a parent node
interrupt-parent should be an optional property, or you can leave it out,
as this is a standard property that can always be there when there is
interrupts.
> +Examples (from pxa27x-lp8x4x.dts):
> +
> + uart@9050 {
By convention, the name should be 'serial', not 'uart'.
Arnd.
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH v5] serial: support for 16550A serial ports on LP-8x4x
2015-12-15 21:51 ` Arnd Bergmann
@ 2015-12-16 8:04 ` Sergei Ianovich
2015-12-16 10:26 ` Arnd Bergmann
2015-12-19 21:42 ` Sergei Ianovich
1 sibling, 1 reply; 148+ messages in thread
From: Sergei Ianovich @ 2015-12-16 8:04 UTC (permalink / raw)
To: Arnd Bergmann
Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA, Alan Cox, Rob Herring,
Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
Greg Kroah-Hartman, Jiri Slaby, Heikki Krogerus, Andy Shevchenko,
Scott Wood, Masahiro Yamada, Sebastian Andrzej Siewior,
Paul Burton, Joachim Eastwood, Mans Rullgard, Paul Gortmaker,
Peter Hurley,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS
On Tue, 2015-12-15 at 22:51 +0100, Arnd Bergmann wrote:
> On Wednesday 16 December 2015 00:04:45 Sergei Ianovich wrote:
> > index 0000000..5f9a4c1
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/serial/lp8x4x-serial.txt
> > @@ -0,0 +1,35 @@
> > +UART ports on ICP DAS LP-8x4x
> > +
> > +ICP DAS LP-8x4x contains three additional serial ports interfaced
> > via
> > +Analog Devices ADM213EA chips in addition to 3 serial ports on PXA
> > CPU.
> > +
> > +Required properties:
> > +- compatible : should be "icpdas,uart-lp8x4x"
>
> Compatible strings should not include a 'x' wildcard like this, better
> use
> the specific chip name.
>
> Also, it sounds like you named them after the board vendor, which
> sounds
> wrong as the vendor part of the compatible string should be the
> whoever
> made that part (analog?)
The chips themselves are standard, they would work with 8250_core if
properly connected. However, they are not connected normally. Al least
some of their config pins are wired to a different address region. So
the driver is board-specific.
'x' wildcards in the name of the board seem important. There are devices
made by the same vendor without 8 or 4 in their name. Those devices
either are not shipped with linux or are base on a x86 platform.
Does this justify the choice of the compatible string?
> > +- reg : should provide 16 byte man IO memory region and 1 byte
> > region for
> > + termios
> > +
> > +- interrupts : should provide interrupt
> > +
> > +- interrupt-parent : should provide a link to interrupt controller
> > either
> > + explicitly or implicitly from a parent node
>
> interrupt-parent should be an optional property, or you can leave it
> out,
> as this is a standard property that can always be there when there is
> interrupts.
ok
> > +Examples (from pxa27x-lp8x4x.dts):
> > +
> > + uart@9050 {
>
> By convention, the name should be 'serial', not 'uart'.
ok
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH v5] serial: support for 16550A serial ports on LP-8x4x
2015-12-16 8:04 ` Sergei Ianovich
@ 2015-12-16 10:26 ` Arnd Bergmann
2015-12-19 8:11 ` Sergei Ianovich
0 siblings, 1 reply; 148+ messages in thread
From: Arnd Bergmann @ 2015-12-16 10:26 UTC (permalink / raw)
To: Sergei Ianovich
Cc: linux-kernel, Alan Cox, Rob Herring, Pawel Moll, Mark Rutland,
Ian Campbell, Kumar Gala, Greg Kroah-Hartman, Jiri Slaby,
Heikki Krogerus, Andy Shevchenko, Scott Wood, Masahiro Yamada,
Sebastian Andrzej Siewior, Paul Burton, Joachim Eastwood,
Mans Rullgard, Paul Gortmaker, Peter Hurley,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS
On Wednesday 16 December 2015 11:04:57 Sergei Ianovich wrote:
> On Tue, 2015-12-15 at 22:51 +0100, Arnd Bergmann wrote:
> > On Wednesday 16 December 2015 00:04:45 Sergei Ianovich wrote:
> > > index 0000000..5f9a4c1
> > > --- /dev/null
> > > +++ b/Documentation/devicetree/bindings/serial/lp8x4x-serial.txt
> > > @@ -0,0 +1,35 @@
> > > +UART ports on ICP DAS LP-8x4x
> > > +
> > > +ICP DAS LP-8x4x contains three additional serial ports interfaced
> > > via
> > > +Analog Devices ADM213EA chips in addition to 3 serial ports on PXA
> > > CPU.
> > > +
> > > +Required properties:
> > > +- compatible : should be "icpdas,uart-lp8x4x"
> >
> > Compatible strings should not include a 'x' wildcard like this, better
> > use
> > the specific chip name.
> >
> > Also, it sounds like you named them after the board vendor, which
> > sounds
> > wrong as the vendor part of the compatible string should be the
> > whoever
> > made that part (analog?)
>
> The chips themselves are standard, they would work with 8250_core if
> properly connected. However, they are not connected normally. Al least
> some of their config pins are wired to a different address region. So
> the driver is board-specific.
Ok, I see.
> 'x' wildcards in the name of the board seem important. There are devices
> made by the same vendor without 8 or 4 in their name. Those devices
> either are not shipped with linux or are base on a x86 platform.
>
> Does this justify the choice of the compatible string?
What I meant was that you should use the specific numbers of one machine,
precisely for the reason you list above.
If there is e.g. a LP-8040 and a LP-8141 today, and you use lp8x4x in
the compatible string to cover both, this will no longer work when the
vendor comes out with a LP8047 that is completely different.
Instead, what you should do is to use the compatible string to identify
one particular board (e.g. the first one that used this setup), and
then list the other ones as compatible with this. You can also add the
other board names in addition, e.g.
compatible = "icpdas,uart-lp8041", "icpdas,uart-lp8040";
for a lp8041 that is compatible with the lp8040. If it turns out later
that they are not entirely compatible, we can work around this in the
driver by checking for the lp8041 string that will be matched first, while
the lp8040 can be used by the driver to match the entire family of
compatible machines (no need to list every one in the driver).
Arnd
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH v5] arm: pxa: support ICP DAS LP-8x4x FPGA irq
2015-12-15 19:26 ` [PATCH v5] arm: " Sergei Ianovich
@ 2015-12-16 11:54 ` Marc Zyngier
2015-12-19 4:20 ` Rob Herring
` (2 subsequent siblings)
3 siblings, 0 replies; 148+ messages in thread
From: Marc Zyngier @ 2015-12-16 11:54 UTC (permalink / raw)
To: Sergei Ianovich, linux-kernel
Cc: Linus Walleij, Arnd Bergmann, Thomas Gleixner, Jason Cooper,
Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
open, list, OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS
On 15/12/15 19:26, Sergei Ianovich wrote:
> ICP DAS LP-8x4x contains FPGA chip. The chip functions as an interrupt
> source providing 16 additional interrupts among other things. The
> interrupt lines are muxed to a GPIO pin of a 2nd level PXA-GPIO
> interrupt controller. GPIO pins of the 2nd level controller are in turn
> muxed to a CPU interrupt line.
>
> Until pxa is completely converted to device tree, it is impossible
> to use IRQCHIP_DECLARE() and the irqdomain needs to added manually.
> Drivers for the on-CPU IRQs and GPIO-IRQs are loaded using
> postcore_initcall(). We need to have all irq domain drivers loaded prior
> to DT parsing in order to allow normal initialization of IRQ resources
> with DT.
>
> Signed-off-by: Sergei Ianovich <ynvich@gmail.com>
> Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
> CC: Arnd Bergmann <arnd@arndb.de>
> ---
> v4..v5
> * constify struct of_device_id
> * drop irq number from handler signature
>
> v3.2..v4
> * move DTS binding to a different patch (8/21)
>
> v3.1..v3.2
> fixes to apply Linus Walleij's "Reviewed-by":
> * add kerneldoc comment for state container struct
> * rename irq -> hwirq for clarity
> * drop overzealous error checks from the hotpaths
>
> v3..v3.1
> fixes according to Linus Walleij review comments:
> * update commit message
> * use state container instead of global variables
> * get hardware irq nums from irq_data, don't calculate them
> * use BIT() macro
> * add defines for system irq register masks
> * replace cycle control variable with break
> * use better names for resource variables
> * add a linear domain instead of a legacy one
> * use irq_create_mapping() instead of irq_alloc_desc()
>
> v2..v3
> * no changes (except number 09/16 -> 11/21)
>
> v0..v2
> * extract irqchip and move to drivers/irqchip/
> * use device tree
> * use devm helpers where possible
>
> .../bindings/interrupt-controller/irq-lp8x4x.txt | 49 +++++
> drivers/irqchip/Kconfig | 5 +
> drivers/irqchip/Makefile | 1 +
> drivers/irqchip/irq-lp8x4x.c | 227 +++++++++++++++++++++
> 4 files changed, 282 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/interrupt-controller/irq-lp8x4x.txt
> create mode 100644 drivers/irqchip/irq-lp8x4x.c
>
> diff --git a/Documentation/devicetree/bindings/interrupt-controller/irq-lp8x4x.txt b/Documentation/devicetree/bindings/interrupt-controller/irq-lp8x4x.txt
> new file mode 100644
> index 0000000..c8940d2
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/interrupt-controller/irq-lp8x4x.txt
> @@ -0,0 +1,49 @@
> +ICP DAS LP-8x4x FPGA Interrupt Controller
> +
> +ICP DAS LP-8x4x contains FPGA chip. The chip functions as a interrupt
> +source providing 16 additional interrupts among other things.
> +
> +Required properties:
> +- compatible : should be "icpdas,irq-lp8x4x"
> +
> +- reg: physical base address of the controller and length of memory mapped
> + region.
> +
> +- interrupt-controller : identifies the node as an interrupt controller
> +
> +- #interrupt-cells : should be 1
> +
> +- interrupts : should provide interrupt
> +
> +- interrupt-parent : should provide a link to interrupt controller either
> + explicitly and implicitly from a parent node
> +
> +Example:
> +
> + fpga: fpga@17000006 {
> + compatible = "icpdas,irq-lp8x4x";
> + reg = <0x17000006 0x16>;
> + interrupt-parent = <&gpio>;
> + interrupts = <3 IRQ_TYPE_EDGE_RISING>;
> + #interrupt-cells = <1>;
> + interrupt-controller;
> + status = "okay";
> + };
> +
> + uart@17009050 {
> + compatible = "icpdas,uart-lp8x4x";
> + reg = <0x17009050 0x10
> + 0x17009030 0x02>;
> + interrupt-parent = <&fpga>;
> + interrupts = <13>;
> + status = "okay";
> + };
> +
> + uart@17009060 {
> + compatible = "icpdas,uart-lp8x4x";
> + reg = <0x17009060 0x10
> + 0x17009032 0x02>;
> + interrupt-parent = <&fpga>;
> + interrupts = <14>;
> + status = "okay";
> + };
> diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
> index 4d7294e..1de7361 100644
> --- a/drivers/irqchip/Kconfig
> +++ b/drivers/irqchip/Kconfig
> @@ -193,3 +193,8 @@ config IRQ_MXS
> def_bool y if MACH_ASM9260 || ARCH_MXS
> select IRQ_DOMAIN
> select STMP_DEVICE
> +
> +config LP8X4X_IRQ
> + bool
> + depends on OF && ARCH_PXA
> + select IRQ_DOMAIN
> diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
> index 177f78f..ab9ca67 100644
> --- a/drivers/irqchip/Makefile
> +++ b/drivers/irqchip/Makefile
> @@ -55,3 +55,4 @@ obj-$(CONFIG_RENESAS_H8S_INTC) += irq-renesas-h8s.o
> obj-$(CONFIG_ARCH_SA1100) += irq-sa11x0.o
> obj-$(CONFIG_INGENIC_IRQ) += irq-ingenic.o
> obj-$(CONFIG_IMX_GPCV2) += irq-imx-gpcv2.o
> +obj-$(CONFIG_LP8X4X_IRQ) += irq-lp8x4x.o
> diff --git a/drivers/irqchip/irq-lp8x4x.c b/drivers/irqchip/irq-lp8x4x.c
> new file mode 100644
> index 0000000..a03d925
> --- /dev/null
> +++ b/drivers/irqchip/irq-lp8x4x.c
> @@ -0,0 +1,227 @@
> +/*
> + * linux/drivers/irqchip/irq-lp8x4x.c
> + *
> + * Support for ICP DAS LP-8x4x FPGA irq
> + * Copyright (C) 2013 Sergei Ianovich <ynvich@gmail.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation or any later version.
> + */
> +#include <linux/interrupt.h>
> +#include <linux/io.h>
> +#include <linux/irq.h>
> +#include <linux/irqdomain.h>
> +#include <linux/irqchip/chained_irq.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +
> +#define EOI 0x00000000
> +#define INSINT 0x00000002
> +#define ENSYSINT 0x00000004
> +#define PRIMINT 0x00000006
> +#define PRIMINT_MASK 0xe0
> +#define SECOINT 0x00000008
> +#define SECOINT_MASK 0x1f
> +#define ENRISEINT 0x0000000A
> +#define CLRRISEINT 0x0000000C
> +#define ENHILVINT 0x0000000E
> +#define CLRHILVINT 0x00000010
> +#define ENFALLINT 0x00000012
> +#define CLRFALLINT 0x00000014
> +#define IRQ_MEM_SIZE 0x00000016
> +#define LP8X4X_NUM_IRQ_DEFAULT 16
> +
> +/**
> + * struct lp8x4x_irq_data - LP8X4X custom irq controller state container
> + * @base: base IO memory address
> + * @irq_domain: Interrupt translation domain; responsible for mapping
> + * between hwirq number and linux irq number
> + * @irq_sys_enabled: mask keeping track of interrupts enabled in the
> + * register which vendor calls 'system'
> + * @irq_high_enabled: mask keeping track of interrupts enabled in the
> + * register which vendor calls 'high'
> + *
> + * The structure implements State Container from
> + * Documentation/driver-model/design-patterns.txt
> + */
> +
> +struct lp8x4x_irq_data {
> + void *base;
> + struct irq_domain *domain;
> + unsigned char irq_sys_enabled;
> + unsigned char irq_high_enabled;
> +};
> +
> +static void lp8x4x_mask_irq(struct irq_data *d)
> +{
> + unsigned mask;
> + unsigned long hwirq = d->hwirq;
> + struct lp8x4x_irq_data *host = irq_data_get_irq_chip_data(d);
> +
> + if (hwirq < 8) {
> + host->irq_high_enabled &= ~BIT(hwirq);
> +
> + mask = ioread8(host->base + ENHILVINT);
> + mask &= ~BIT(hwirq);
> + iowrite8(mask, host->base + ENHILVINT);
> + } else {
> + hwirq -= 8;
> + host->irq_sys_enabled &= ~BIT(hwirq);
> +
> + mask = ioread8(host->base + ENSYSINT);
> + mask &= ~BIT(hwirq);
> + iowrite8(mask, host->base + ENSYSINT);
Any reason why this is using iowrite8/ioread8 instead of writeb/readb,
which are much more common on ARM?
> + }
> +}
> +
> +static void lp8x4x_unmask_irq(struct irq_data *d)
> +{
> + unsigned mask;
> + unsigned long hwirq = d->hwirq;
> + struct lp8x4x_irq_data *host = irq_data_get_irq_chip_data(d);
> +
> + if (hwirq < 8) {
> + host->irq_high_enabled |= BIT(hwirq);
> + mask = ioread8(host->base + CLRHILVINT);
> + mask |= BIT(hwirq);
> + iowrite8(mask, host->base + CLRHILVINT);
> +
> + mask = ioread8(host->base + ENHILVINT);
> + mask |= BIT(hwirq);
> + iowrite8(mask, host->base + ENHILVINT);
> + } else {
> + hwirq -= 8;
> + host->irq_sys_enabled |= BIT(hwirq);
> +
> + mask = ioread8(host->base + SECOINT);
> + mask |= BIT(hwirq);
> + iowrite8(mask, host->base + SECOINT);
> +
> + mask = ioread8(host->base + ENSYSINT);
> + mask |= BIT(hwirq);
> + iowrite8(mask, host->base + ENSYSINT);
> + }
> +}
> +
> +static struct irq_chip lp8x4x_irq_chip = {
> + .name = "FPGA",
> + .irq_ack = lp8x4x_mask_irq,
> + .irq_mask = lp8x4x_mask_irq,
> + .irq_mask_ack = lp8x4x_mask_irq,
> + .irq_unmask = lp8x4x_unmask_irq,
> +};
> +
> +static void lp8x4x_irq_handler(struct irq_desc *desc)
> +{
> + int n;
> + unsigned long mask;
> + struct irq_chip *chip = irq_desc_get_chip(desc);
> + struct lp8x4x_irq_data *host = irq_desc_get_handler_data(desc);
> +
> + chained_irq_enter(chip, desc);
> +
> + for (;;) {
> + mask = ioread8(host->base + CLRHILVINT) & 0xff;
> + mask |= (ioread8(host->base + SECOINT) & SECOINT_MASK) << 8;
> + mask |= (ioread8(host->base + PRIMINT) & PRIMINT_MASK) << 8;
Huh. Fancy. It would be nice if one of PRIMINT_MASK and SECOINT_MASK was
defined in terms of the other. Something like
#define SECOINT_MASK (~(u8)PRIMINT_MASK)
and a short comment so that I don't jump at seeing two "<< 8" in a row.
> + mask &= host->irq_high_enabled | (host->irq_sys_enabled << 8);
Is there any case where this actually filters pending interrupts? mask
and unmask seem to program a similar state in the HW...
> + if (mask == 0)
> + break;
> + for_each_set_bit(n, &mask, BITS_PER_LONG)
> + generic_handle_irq(irq_find_mapping(host->domain, n));
> + }
> +
> + iowrite8(0, host->base + EOI);
> + chained_irq_exit(chip, desc);
> +}
> +
> +static int lp8x4x_irq_domain_map(struct irq_domain *d, unsigned int irq,
> + irq_hw_number_t hw)
> +{
> + struct lp8x4x_irq_data *host = d->host_data;
> + int err;
> +
> + err = irq_set_chip_data(irq, host);
> + if (err < 0)
> + return err;
> +
> + irq_set_chip_and_handler(irq, &lp8x4x_irq_chip, handle_level_irq);
> + irq_set_probe(irq);
> + return 0;
> +}
> +
> +const struct irq_domain_ops lp8x4x_irq_domain_ops = {
> + .map = lp8x4x_irq_domain_map,
> + .xlate = irq_domain_xlate_onecell,
> +};
> +
> +static const struct of_device_id lp8x4x_irq_dt_ids[] = {
> + { .compatible = "icpdas,irq-lp8x4x", },
> + {}
> +};
> +
> +static int lp8x4x_irq_probe(struct platform_device *pdev)
> +{
> + struct resource *res_mem, *res_irq;
> + struct device_node *np = pdev->dev.of_node;
> + struct lp8x4x_irq_data *host;
> + int i, err;
> +
> + res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> + res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
> + if (!res_mem || !res_irq || resource_size(res_mem) < IRQ_MEM_SIZE)
> + return -ENODEV;
> +
> + host = devm_kzalloc(&pdev->dev, sizeof(*host), GFP_KERNEL);
> + if (!host)
> + return -ENODEV;
> +
> + host->base = devm_ioremap_resource(&pdev->dev, res_mem);
> + if (!host->base) {
> + dev_err(&pdev->dev, "Failed to ioremap %p\n", host->base);
> + return -EFAULT;
> + }
> +
> + host->domain = irq_domain_add_linear(np, LP8X4X_NUM_IRQ_DEFAULT,
> + &lp8x4x_irq_domain_ops, host);
> + if (!host->domain) {
> + dev_err(&pdev->dev, "Failed to add IRQ domain\n");
> + return -ENOMEM;
> + }
> +
> + for (i = 0; i < LP8X4X_NUM_IRQ_DEFAULT; i++) {
> + err = irq_create_mapping(host->domain, i);
> + if (err < 0)
> + dev_err(&pdev->dev, "Failed to map IRQ %i\n", i);
> + }
I'd expect a comment here, stating that this will need to be removed
once PXA is converted to DT.
> +
> + /* Initialize chip registers */
> + iowrite8(0, host->base + CLRRISEINT);
> + iowrite8(0, host->base + ENRISEINT);
> + iowrite8(0, host->base + CLRFALLINT);
> + iowrite8(0, host->base + ENFALLINT);
> + iowrite8(0, host->base + CLRHILVINT);
> + iowrite8(0, host->base + ENHILVINT);
> + iowrite8(0, host->base + ENSYSINT);
> + iowrite8(0, host->base + SECOINT);
> +
> + irq_set_handler_data(res_irq->start, host);
> + irq_set_chained_handler(res_irq->start, lp8x4x_irq_handler);
> +
> + return 0;
> +}
> +
> +static struct platform_driver lp8x4x_irq_driver = {
> + .probe = lp8x4x_irq_probe,
> + .driver = {
> + .name = "irq-lp8x4x",
> + .of_match_table = lp8x4x_irq_dt_ids,
> + },
> +};
> +
> +static int __init lp8x4x_irq_init(void)
> +{
> + return platform_driver_register(&lp8x4x_irq_driver);
> +}
> +postcore_initcall(lp8x4x_irq_init);
>
Thanks,
M.
--
Jazz is not dead. It just smells funny...
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH v5] serial: support for 16550A serial ports on LP-8x4x
2015-12-15 21:04 ` [PATCH v5] serial: support for 16550A serial ports on LP-8x4x Sergei Ianovich
2015-12-15 21:51 ` Arnd Bergmann
@ 2015-12-17 14:50 ` Andy Shevchenko
[not found] ` <1450213494-21884-1-git-send-email-ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2 siblings, 0 replies; 148+ messages in thread
From: Andy Shevchenko @ 2015-12-17 14:50 UTC (permalink / raw)
To: Sergei Ianovich, linux-kernel
Cc: Alan Cox, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell,
Kumar Gala, Greg Kroah-Hartman, Jiri Slaby, Heikki Krogerus,
Arnd Bergmann, Scott Wood, Masahiro Yamada,
Sebastian Andrzej Siewior, Paul Burton, Joachim Eastwood,
Mans Rullgard, Paul Gortmaker, Peter Hurley,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list:SERIAL DRIVERS
On Wed, 2015-12-16 at 00:04 +0300, Sergei Ianovich wrote:
> The patch adds support for 3 additional LP-8x4x built-in serial
> ports.
>
> The device can also host up to 8 extension cards with 4 serial ports
> on each card for a total of 35 ports. However, I don't have
> the hardware to test extension cards, so they are not supported, yet.
>
Few nitpicks, though everything looks okay.
> Signed-off-by: Sergei Ianovich <ynvich@gmail.com>
> Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
> CC: Alan Cox <gnomes@lxorguk.ukuu.org.uk>
> ---
> v4..v5
> * constify struct of_device_id
> * drop .owner from struct platform_driver
> * rewrite set_termios() baud rate hadnling as suggested by Alan
> Cox
>
> v3..v4
> * move DTS bindings to a different patch (8/21) as suggested by
> Heikki Krogerus
>
> v2..v3
> * no changes (except number 10/16 -> 12/21)
>
> v0..v2
> * register platform driver instead of platform device
> * use device tree
> * use devm helpers where possible
>
> .../devicetree/bindings/serial/lp8x4x-serial.txt | 35 +++++
> drivers/tty/serial/8250/8250_lp8x4x.c | 168
> +++++++++++++++++++++
> drivers/tty/serial/8250/Kconfig | 12 ++
> drivers/tty/serial/8250/Makefile | 1 +
> 4 files changed, 216 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/serial/lp8x4x-
> serial.txt
> create mode 100644 drivers/tty/serial/8250/8250_lp8x4x.c
>
> diff --git a/Documentation/devicetree/bindings/serial/lp8x4x-
> serial.txt b/Documentation/devicetree/bindings/serial/lp8x4x-
> serial.txt
> new file mode 100644
> index 0000000..5f9a4c1
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/serial/lp8x4x-serial.txt
> @@ -0,0 +1,35 @@
> +UART ports on ICP DAS LP-8x4x
> +
> +ICP DAS LP-8x4x contains three additional serial ports interfaced
> via
> +Analog Devices ADM213EA chips in addition to 3 serial ports on PXA
> CPU.
> +
> +Required properties:
> +- compatible : should be "icpdas,uart-lp8x4x"
> +
> +- reg : should provide 16 byte man IO memory region and 1 byte
> region for
> + termios
> +
> +- interrupts : should provide interrupt
> +
> +- interrupt-parent : should provide a link to interrupt controller
> either
> + explicitly or implicitly from a parent node
> +
> +Examples (from pxa27x-lp8x4x.dts):
> +
> + uart@9050 {
> + compatible = "icpdas,uart-lp8x4x";
> + reg = <0x9050 0x10
> + 0x9030 0x02>;
> + interrupt-parent = <&fpgairg>;
> + interrupts = <13>;
> + status = "okay";
> + };
> +
> + uart@9060 {
> + compatible = "icpdas,uart-lp8x4x";
> + reg = <0x9060 0x10
> + 0x9032 0x02>;
> + interrupt-parent = <&fpgairg>;
> + interrupts = <14>;
> + status = "okay";
> + };
> diff --git a/drivers/tty/serial/8250/8250_lp8x4x.c
> b/drivers/tty/serial/8250/8250_lp8x4x.c
> new file mode 100644
> index 0000000..0e07220
> --- /dev/null
> +++ b/drivers/tty/serial/8250/8250_lp8x4x.c
> @@ -0,0 +1,168 @@
> +/* linux/drivers/tty/serial/8250/8250_lp8x4x.c
> + *
> + * Support for 16550A serial ports on ICP DAS LP-8x4x
> + *
> + * Copyright (C) 2013 Sergei Ianovich <ynvich@gmail.com>
> + *
> + * This program is free software; you can redistribute it and/or
> modify
> + * it under the terms of the GNU General Public License version 2
> as
> + * published by the Free Software Foundation.
> + */
> +#include <linux/init.h>
> +#include <linux/io.h>
> +#include <linux/irq.h>
> +#include <linux/module.h>
> +#include <linux/serial_8250.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +
> +struct lp8x4x_serial_data {
> + int line;
> + void *ios_mem;
> +};
> +
> +static void lp8x4x_serial_set_termios(struct uart_port *port,
> + struct ktermios *termios, struct ktermios *old)
> +{
> + unsigned int len;
> + unsigned int baud;
> + struct lp8x4x_serial_data *data = port->private_data;
> +
> + serial8250_do_set_termios(port, termios, old);
> +
> + switch (termios->c_cflag & CSIZE) {
> + case CS5:
> + len = 7;
> + break;
> + case CS6:
> + len = 8;
> + break;
> + case CS7:
> + len = 9;
> + break;
> + default:
> + case CS8:
I would suggest to exchange those lines.
> + len = 10;
> + break;
> + }
> +
> + if (termios->c_cflag & CSTOPB)
> + len++;
> + if (termios->c_cflag & PARENB)
> + len++;
> + if (!(termios->c_cflag & PARODD))
> + len++;
> +#ifdef CMSPAR
> + if (termios->c_cflag & CMSPAR)
> + len++;
> +#endif
> +
> + len -= 9;
> + len &= 3;
> + len <<= 3;
> + /*
> + * Ask the core to calculate the divisor for us.
> + */
Can it be one line?
> + baud = tty_termios_baud_rate(termios);
> +
> + switch (baud) {
> + case 115200:
> + len |= 7;
> + break;
> + case 57600:
> + len |= 6;
> + break;
> + case 38400:
> + len |= 5;
> + break;
> + case 19200:
> + len |= 4;
> + break;
> + case 9600:
> + len |= 3;
> + break;
> + case 4800:
> + len |= 2;
> + break;
> + case 2400:
> + default:
> + len |= 1;
> + break;
> + };
> + iowrite8(len, data->ios_mem);
writeb() ?
> +
> +}
> +
> +static const struct of_device_id lp8x4x_serial_dt_ids[] = {
> + { .compatible = "icpdas,uart-lp8x4x", },
> + {}
> +};
> +MODULE_DEVICE_TABLE(of, lp8x4x_serial_dt_ids);
> +
> +static int lp8x4x_serial_probe(struct platform_device *pdev)
> +{
> + struct uart_8250_port uart = {};
> + struct lp8x4x_serial_data *data;
> + struct resource *mmres, *mires, *irqres;
> + int ret;
> +
> + mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> + mires = platform_get_resource(pdev, IORESOURCE_MEM, 1);
> + irqres = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
> + if (!mmres || !mires || !irqres)
> + return -ENODEV;
> +
> + data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
> + if (!data)
> + return -ENOMEM;
> +
> + data->ios_mem = devm_ioremap_resource(&pdev->dev, mires);
> + if (!data->ios_mem)
> + return -EFAULT;
> +
> + uart.port.iotype = UPIO_MEM;
> + uart.port.mapbase = mmres->start;
> + uart.port.iobase = mmres->start;
> + uart.port.regshift = 1;
> + uart.port.irq = irqres->start;
> + uart.port.flags = UPF_IOREMAP;
> + uart.port.dev = &pdev->dev;
> + uart.port.uartclk = 14745600;
> + uart.port.set_termios = lp8x4x_serial_set_termios;
> + uart.port.private_data = data;
> +
> + ret = serial8250_register_8250_port(&uart);
> + if (ret < 0)
> + return ret;
> +
> + data->line = ret;
> +
> + platform_set_drvdata(pdev, data);
> +
> + return 0;
> +}
> +
> +static int lp8x4x_serial_remove(struct platform_device *pdev)
> +{
> + struct lp8x4x_serial_data *data =
> platform_get_drvdata(pdev);
> +
> + serial8250_unregister_port(data->line);
> +
> + return 0;
> +}
> +
> +static struct platform_driver lp8x4x_serial_driver = {
> + .probe = lp8x4x_serial_probe,
> + .remove = lp8x4x_serial_remove,
> +
> + .driver = {
> + .name = "uart-lp8x4x",
> + .of_match_table = lp8x4x_serial_dt_ids,
> + },
> +};
> +
> +module_platform_driver(lp8x4x_serial_driver);
> +
> +MODULE_AUTHOR("Sergei Ianovich");
> +MODULE_DESCRIPTION("8250 serial port module for LP-8x4x");
> +MODULE_LICENSE("GPL");
> diff --git a/drivers/tty/serial/8250/Kconfig
> b/drivers/tty/serial/8250/Kconfig
> index 48b6253..00eb6b0 100644
> --- a/drivers/tty/serial/8250/Kconfig
> +++ b/drivers/tty/serial/8250/Kconfig
> @@ -387,3 +387,15 @@ config SERIAL_8250_PXA
> can enable its onboard serial ports by enabling this
> option.
>
> If you choose M here, the module name will be 8250_pxa.
> +
> +config SERIAL_8250_LP8X4X
> + tristate "Support 16550A ports on ICP DAS LP-8x4x"
> + depends on OF && SERIAL_8250 && SERIAL_8250_MANY_PORTS &&
> ARCH_PXA
> + select LP8X4X_IRQ
> + help
> + In addition to serial ports on PXA270 SoC, LP-8x4x has 1
> dual
> + RS232/RS485 port, 1 RS485 port and 1 RS232 port.
> +
> + Say N here, unless you plan to run this kernel on a LP-
> 8x4x system.
> +
> + If you choose M here, the module name will be 8250_lp8x4x.
> diff --git a/drivers/tty/serial/8250/Makefile
> b/drivers/tty/serial/8250/Makefile
> index 7e54413..8bdbf40 100644
> --- a/drivers/tty/serial/8250/Makefile
> +++ b/drivers/tty/serial/8250/Makefile
> @@ -18,6 +18,7 @@ obj-$(CONFIG_SERIAL_8250_ACCENT) +=
> 8250_accent.o
> obj-$(CONFIG_SERIAL_8250_BOCA) += 8250_boca.o
> obj-$(CONFIG_SERIAL_8250_EXAR_ST16C554) +=
> 8250_exar_st16c554.o
> obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o
> +obj-$(CONFIG_SERIAL_8250_LP8X4X) += 8250_lp8x4x.o
> obj-$(CONFIG_SERIAL_8250_FSL) += 8250_fsl.o
> obj-$(CONFIG_SERIAL_8250_DW) += 8250_dw.o
> obj-$(CONFIG_SERIAL_8250_EM) += 8250_em.o
--
Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Intel Finland Oy
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH v5] arm: pxa: support ICP DAS LP-8x4x FPGA irq
2015-12-15 19:26 ` [PATCH v5] arm: " Sergei Ianovich
2015-12-16 11:54 ` Marc Zyngier
@ 2015-12-19 4:20 ` Rob Herring
[not found] ` <20151219035802.GA28424@rob-hp-laptop>
2016-02-27 15:56 ` [PATCH v6] " Sergei Ianovich
3 siblings, 0 replies; 148+ messages in thread
From: Rob Herring @ 2015-12-19 4:20 UTC (permalink / raw)
To: Sergei Ianovich
Cc: linux-kernel, Linus Walleij, Arnd Bergmann, Thomas Gleixner,
Jason Cooper, Marc Zyngier, Pawel Moll, Mark Rutland,
Ian Campbell, Kumar Gala,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS
On Tue, Dec 15, 2015 at 10:26:21PM +0300, Sergei Ianovich wrote:
> ICP DAS LP-8x4x contains FPGA chip. The chip functions as an interrupt
> source providing 16 additional interrupts among other things. The
> interrupt lines are muxed to a GPIO pin of a 2nd level PXA-GPIO
> interrupt controller. GPIO pins of the 2nd level controller are in turn
> muxed to a CPU interrupt line.
>
> Until pxa is completely converted to device tree, it is impossible
> to use IRQCHIP_DECLARE() and the irqdomain needs to added manually.
> Drivers for the on-CPU IRQs and GPIO-IRQs are loaded using
> postcore_initcall(). We need to have all irq domain drivers loaded prior
> to DT parsing in order to allow normal initialization of IRQ resources
> with DT.
>
> Signed-off-by: Sergei Ianovich <ynvich@gmail.com>
> Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
> CC: Arnd Bergmann <arnd@arndb.de>
> ---
> v4..v5
> * constify struct of_device_id
> * drop irq number from handler signature
>
> v3.2..v4
> * move DTS binding to a different patch (8/21)
>
> v3.1..v3.2
> fixes to apply Linus Walleij's "Reviewed-by":
> * add kerneldoc comment for state container struct
> * rename irq -> hwirq for clarity
> * drop overzealous error checks from the hotpaths
>
> v3..v3.1
> fixes according to Linus Walleij review comments:
> * update commit message
> * use state container instead of global variables
> * get hardware irq nums from irq_data, don't calculate them
> * use BIT() macro
> * add defines for system irq register masks
> * replace cycle control variable with break
> * use better names for resource variables
> * add a linear domain instead of a legacy one
> * use irq_create_mapping() instead of irq_alloc_desc()
>
> v2..v3
> * no changes (except number 09/16 -> 11/21)
>
> v0..v2
> * extract irqchip and move to drivers/irqchip/
> * use device tree
> * use devm helpers where possible
>
> .../bindings/interrupt-controller/irq-lp8x4x.txt | 49 +++++
> drivers/irqchip/Kconfig | 5 +
> drivers/irqchip/Makefile | 1 +
> drivers/irqchip/irq-lp8x4x.c | 227 +++++++++++++++++++++
> 4 files changed, 282 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/interrupt-controller/irq-lp8x4x.txt
> create mode 100644 drivers/irqchip/irq-lp8x4x.c
>
> diff --git a/Documentation/devicetree/bindings/interrupt-controller/irq-lp8x4x.txt b/Documentation/devicetree/bindings/interrupt-controller/irq-lp8x4x.txt
> new file mode 100644
> index 0000000..c8940d2
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/interrupt-controller/irq-lp8x4x.txt
> @@ -0,0 +1,49 @@
> +ICP DAS LP-8x4x FPGA Interrupt Controller
> +
> +ICP DAS LP-8x4x contains FPGA chip. The chip functions as a interrupt
> +source providing 16 additional interrupts among other things.
> +
> +Required properties:
> +- compatible : should be "icpdas,irq-lp8x4x"
> +
> +- reg: physical base address of the controller and length of memory mapped
> + region.
> +
> +- interrupt-controller : identifies the node as an interrupt controller
> +
> +- #interrupt-cells : should be 1
> +
> +- interrupts : should provide interrupt
> +
> +- interrupt-parent : should provide a link to interrupt controller either
> + explicitly and implicitly from a parent node
> +
> +Example:
> +
> + fpga: fpga@17000006 {
Nothing else in the fpga? In any case, this node should be named
interrupt-controller@17000006.
> + compatible = "icpdas,irq-lp8x4x";
As pointed out in the uart binding, don't use wildcards here.
> + reg = <0x17000006 0x16>;
> + interrupt-parent = <&gpio>;
> + interrupts = <3 IRQ_TYPE_EDGE_RISING>;
> + #interrupt-cells = <1>;
> + interrupt-controller;
> + status = "okay";
> + };
> +
> + uart@17009050 {
> + compatible = "icpdas,uart-lp8x4x";
> + reg = <0x17009050 0x10
> + 0x17009030 0x02>;
> + interrupt-parent = <&fpga>;
> + interrupts = <13>;
> + status = "okay";
> + };
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH v5] arm: pxa: support ICP DAS LP-8x4x FPGA irq
[not found] ` <20151219035802.GA28424@rob-hp-laptop>
@ 2015-12-19 7:03 ` Sergei Ianovich
0 siblings, 0 replies; 148+ messages in thread
From: Sergei Ianovich @ 2015-12-19 7:03 UTC (permalink / raw)
To: Rob Herring
Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA, Linus Walleij, Arnd Bergmann,
Thomas Gleixner, Jason Cooper, Marc Zyngier, Pawel Moll,
Mark Rutland, Ian Campbell, Kumar Gala,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS
On Fri, 2015-12-18 at 21:58 -0600, Rob Herring wrote:
> On Tue, Dec 15, 2015 at 10:26:21PM +0300, Sergei Ianovich wrote:
> > +Example:
> > +
> > + fpga: fpga@17000006 {
>
> Nothing else in the fpga? In any case, this node should be named
> interrupt-controller@17000006.
>
> > + compatible = "icpdas,irq-lp8x4x";
>
> As pointed out in the uart binding, don't use wildcards here.
>
> > + reg = <0x17000006 0x16>;
> > + interrupt-parent = <&gpio>;
> > + interrupts = <3 IRQ_TYPE_EDGE_RISING>;
> > + #interrupt-cells = <1>;
> > + interrupt-controller;
> > + status = "okay";
> > + };
> > +
> > + uart@17009050 {
> > + compatible = "icpdas,uart-lp8x4x";
> > + reg = <0x17009050 0x10
> > + 0x17009030 0x02>;
> > + interrupt-parent = <&fpga>;
> > + interrupts = <13>;
> > + status = "okay";
> > + };
That was just an example. The actual binding in LP-8x4x is bigger:
fpga@5 {
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <1>;
ranges = <0 5 0x3000000 0x10000>;
interrupt-parent = <&fpgairq>;
rtc@901c {
compatible = "dallas,rtc-ds1302";
reg = <0x901c 0x1>;
status = "okay";
};
sram@a000 {
compatible = "icpdas,sram-lp8x4x";
reg = <0xa000 0x1000
0x901e 0x1>;
partitions {
#address-cells = <1>;
#size-cells = <1>;
};
};
fpgairq: irq@9006 {
compatible = "icpdas,irq-lp8x4x";
reg = <0x9006 0x16>;
interrupt-parent = <&gpio>;
interrupts = <3 IRQ_TYPE_EDGE_FALLING>;
#interrupt-cells = <1>;
interrupt-controller;
status = "okay";
};
uart@9050 {
compatible = "icpdas,uart-lp8x4x";
reg = <0x9050 0x10
0x9030 0x02>;
interrupts = <13>;
status = "okay";
};
uart@9060 {
compatible = "icpdas,uart-lp8x4x";
reg = <0x9060 0x10
0x9032 0x02>;
interrupts = <14>;
status = "okay";
};
uart@9070 {
compatible = "icpdas,uart-lp8x4x";
reg = <0x9070 0x10
0x9034 0x02>;
interrupts = <15>;
status = "okay";
};
backplane {
compatible = "icpdas,backplane-lp8x4x";
reg = <0x0 0x2
0x1000 0x10
0x2000 0x10
0x3000 0x10
0x4000 0x10
0x5000 0x10
0x6000 0x10
0x7000 0x10
0x8000 0x10
0x9002 0x2
0x9004 0x2
0x9046 0x2>;
eeprom-gpios = <&gpio 4 0>;
};
};
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH v5] serial: support for 16550A serial ports on LP-8x4x
2015-12-16 10:26 ` Arnd Bergmann
@ 2015-12-19 8:11 ` Sergei Ianovich
0 siblings, 0 replies; 148+ messages in thread
From: Sergei Ianovich @ 2015-12-19 8:11 UTC (permalink / raw)
To: Arnd Bergmann
Cc: linux-kernel, Alan Cox, Rob Herring, Pawel Moll, Mark Rutland,
Ian Campbell, Kumar Gala, Greg Kroah-Hartman, Jiri Slaby,
Heikki Krogerus, Andy Shevchenko, Scott Wood, Masahiro Yamada,
Sebastian Andrzej Siewior, Paul Burton, Joachim Eastwood,
Mans Rullgard, Paul Gortmaker, Peter Hurley,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS
On Wed, 2015-12-16 at 11:26 +0100, Arnd Bergmann wrote:
> On Wednesday 16 December 2015 11:04:57 Sergei Ianovich wrote:
> > On Tue, 2015-12-15 at 22:51 +0100, Arnd Bergmann wrote:
> > > 'x' wildcards in the name of the board seem important. There are
> > devices
> > made by the same vendor without 8 or 4 in their name. Those devices
> > either are not shipped with linux or are base on a x86 platform.
> >
> > Does this justify the choice of the compatible string?
>
> What I meant was that you should use the specific numbers of one
> machine,
> precisely for the reason you list above.
>
> If there is e.g. a LP-8040 and a LP-8141 today, and you use lp8x4x in
> the compatible string to cover both, this will no longer work when the
> vendor comes out with a LP8047 that is completely different.
>
> Instead, what you should do is to use the compatible string to
> identify
> one particular board (e.g. the first one that used this setup), and
> then list the other ones as compatible with this. You can also add the
> other board names in addition, e.g.
>
> compatible = "icpdas,uart-lp8041", "icpdas,uart-lp8040";
>
> for a lp8041 that is compatible with the lp8040. If it turns out later
> that they are not entirely compatible, we can work around this in the
> driver by checking for the lp8041 string that will be matched first,
> while
> the lp8040 can be used by the driver to match the entire family of
> compatible machines (no need to list every one in the driver).
I'll try to be more specific. This driver will support ports on LP-8081,
LP-8141, LP-8441, LP-8841. Last time I checked the vendor was announcing
a series with 3 as the last digit. They use lp8x4x name, eg. in
documentation like `LP-8x4x_ChangeLog.txt`. They ship their proprietary
SDK in `lp8x4x_sdk_for_linux.tar`. All of this implies that it is a
single board.
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH v5 2/2] arm: pxa27x: support for ICP DAS LP-8x4x w/ DT
2015-12-15 17:02 ` Arnd Bergmann
2015-12-15 17:24 ` Sergei Ianovich
@ 2015-12-19 12:27 ` Robert Jarzmik
1 sibling, 0 replies; 148+ messages in thread
From: Robert Jarzmik @ 2015-12-19 12:27 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Sergei Ianovich, linux-kernel, Daniel Mack, Rob Herring,
Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala, Russell King,
Thierry Reding, Jonathan Cameron, Dmitry Torokhov, Philipp Zabel,
Arnaud Ebalard, Kuninori Morimoto,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
moderated list:ARM PORT
Arnd Bergmann <arnd@arndb.de> writes:
> I would like those drivers to be enabled in some defconfig, so we get
> compile-time coverage, but we generally stopped having one-config-per-board
> files.
>
> Maybe we can have a pxa_defconfig file that enables lots of boards
> and then we remove the individual configs? We don't have to remove
> them all at once, but it would make me very happy if we could at
> least kill off some of the ones that are not used regularly.
I'll take that part, the pxa_defconfig which covers all pxa boards in
arch/arm/mach-pxa. I have a prototype, which of course doesn't boot on any of my
pxa platforms (breaks in the very early bootstrap code I think, DEBUG_LL is the
next stage).
Actually I've not even looked if a single kernel covering pxa2xx and pxa3xx is
possible (since recently clock handling was a blocker).
Once I have something that at least shows me a sign of life, I'll submit an RFC
patch. This work will be orthogonal to Sergei's one, as it is aimed at having
one defconfig compiling all mach-pxa/*.c files and the drivers referenced by
them. This won't allow removing defconfig files until I have a good idea why my
boards are not booting (lubbock, mainstone, mioa701, zylonite, cm-x300).
Cheers.
--
Robert
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH v5] serial: support for 16550A serial ports on LP-8x4x
2015-12-15 21:51 ` Arnd Bergmann
2015-12-16 8:04 ` Sergei Ianovich
@ 2015-12-19 21:42 ` Sergei Ianovich
1 sibling, 0 replies; 148+ messages in thread
From: Sergei Ianovich @ 2015-12-19 21:42 UTC (permalink / raw)
To: Arnd Bergmann
Cc: linux-kernel, Alan Cox, Rob Herring, Pawel Moll, Mark Rutland,
Ian Campbell, Kumar Gala, Greg Kroah-Hartman, Jiri Slaby,
Heikki Krogerus, Andy Shevchenko, Scott Wood, Masahiro Yamada,
Sebastian Andrzej Siewior, Paul Burton, Joachim Eastwood,
Mans Rullgard, Paul Gortmaker, Peter Hurley,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS
On Tue, 2015-12-15 at 22:51 +0100, Arnd Bergmann wrote:
> On Wednesday 16 December 2015 00:04:45 Sergei Ianovich wrote:
> > +Examples (from pxa27x-lp8x4x.dts):
> > +
> > + uart@9050 {
>
> By convention, the name should be 'serial', not 'uart'.
>
arch/arm/boot/dts/pxa2xx.dtsi uses 'uart'. Should I change the names in
the patch with dts file for LP-8xx?
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH v5] mtd: support BB SRAM on ICP DAS LP-8x4x
2015-12-15 18:58 ` [PATCH v5] " Sergei Ianovich
@ 2015-12-20 3:38 ` Rob Herring
2015-12-20 10:43 ` Sergei Ianovich
[not found] ` <1450205941-15593-1-git-send-email-ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
1 sibling, 1 reply; 148+ messages in thread
From: Rob Herring @ 2015-12-20 3:38 UTC (permalink / raw)
To: Sergei Ianovich
Cc: linux-kernel, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
David Woodhouse, Brian Norris, Jeremy Kerr, Cyril Bur,
Neelesh Gupta, Michael Ellerman, Joel Stanley,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list:MEMORY TECHNOLOGY DEVICES (MTD)
On Tue, Dec 15, 2015 at 09:58:53PM +0300, Sergei Ianovich wrote:
> This provides an MTD device driver for 512kB of battery backed up SRAM
> on ICPDAS LP-8X4X programmable automation controllers.
>
> SRAM chip is connected via FPGA and is not accessible without a driver,
> unlike flash memory which is wired to CPU MMU.
>
> This SRAM becomes an excellent persisent storage of volatile process
> data like counter values and sensor statuses. Storing those data in
> flash or mmc card is not a viable solution.
>
> Signed-off-by: Sergei Ianovich <ynvich@gmail.com>
> Reviewed-by: Brian Norris <computersforpeace@gmail.com>
> ---
> v4..v5
> * remove .owner from struct platform_driver
> * constify struct of_device_id
> for further Brian Norris comments:
> * drop unused property from doc file
> * move defconfig update to a different file
> * drop extra match w/ of_match_device()
>
> v3..v4 for Brian Norris 'Reviewed-by'
> * add doc file for DT binding
> * move DTS binding to a different patch (8/21)
> * drop unused include directive
> * drop safely unused callback
> * drop non-default partion probe types
> * drop duplicate error checks
> * drop duplicate error reporting
> * fixed error message on MTD registeration
> * fixed module removal routine
>
> v2..v3
> * no changes (except number 08/16 -> 10/21)
>
> v0..v2
> * use device tree
> * use devm helpers where possible
>
> .../devicetree/bindings/mtd/sram-lp8x4x.txt | 20 +++
> drivers/mtd/devices/Kconfig | 14 ++
> drivers/mtd/devices/Makefile | 1 +
> drivers/mtd/devices/sram_lp8x4x.c | 199 +++++++++++++++++++++
> 4 files changed, 234 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/mtd/sram-lp8x4x.txt
> create mode 100644 drivers/mtd/devices/sram_lp8x4x.c
>
> diff --git a/Documentation/devicetree/bindings/mtd/sram-lp8x4x.txt b/Documentation/devicetree/bindings/mtd/sram-lp8x4x.txt
> new file mode 100644
> index 0000000..476934f
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mtd/sram-lp8x4x.txt
> @@ -0,0 +1,20 @@
> +512kB battery backed up SRAM on LP-8x4x industrial computers
> +
> +Required properties:
> +- compatible : should be "icpdas,sram-lp8x4x"
No wildcards please. Otherwise looks fine.
> +
> +- reg: physical base addresses and region lengths of
> + * IO memory range
> + * SRAM page selector
> +
> +SRAM chip is connected via FPGA and is not accessible without a driver,
> +unlike flash memory which is wired to CPU MMU. Driver is essentially
> +an address translation routine.
> +
> +Example:
> +
> + sram@a000 {
> + compatible = "icpdas,sram-lp8x4x";
> + reg = <0xa000 0x1000
> + 0x901e 0x1>;
> + };
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH v5] mtd: support BB SRAM on ICP DAS LP-8x4x
2015-12-20 3:38 ` Rob Herring
@ 2015-12-20 10:43 ` Sergei Ianovich
[not found] ` <1450608238.15911.24.camel-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
0 siblings, 1 reply; 148+ messages in thread
From: Sergei Ianovich @ 2015-12-20 10:43 UTC (permalink / raw)
To: Rob Herring
Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA, Pawel Moll, Mark Rutland,
Ian Campbell, Kumar Gala, David Woodhouse, Brian Norris,
Jeremy Kerr, Cyril Bur, Neelesh Gupta, Michael Ellerman,
Joel Stanley,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list:MEMORY TECHNOLOGY DEVICES (MTD), Arnd Bergmann
On Sat, 2015-12-19 at 21:38 -0600, Rob Herring wrote:
> On Tue, Dec 15, 2015 at 09:58:53PM +0300, Sergei Ianovich wrote:
> > This provides an MTD device driver for 512kB of battery backed up
> > SRAM
> > on ICPDAS LP-8X4X programmable automation controllers.
> >
> > SRAM chip is connected via FPGA and is not accessible without a
> > driver,
> > unlike flash memory which is wired to CPU MMU.
> >
> > This SRAM becomes an excellent persisent storage of volatile process
> > data like counter values and sensor statuses. Storing those data in
> > flash or mmc card is not a viable solution.
> >
> > Signed-off-by: Sergei Ianovich <ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> > Reviewed-by: Brian Norris <computersforpeace-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> > ---
> > v4..v5
> > * remove .owner from struct platform_driver
> > * constify struct of_device_id
> > for further Brian Norris comments:
> > * drop unused property from doc file
> > * move defconfig update to a different file
> > * drop extra match w/ of_match_device()
> >
> > v3..v4 for Brian Norris 'Reviewed-by'
> > * add doc file for DT binding
> > * move DTS binding to a different patch (8/21)
> > * drop unused include directive
> > * drop safely unused callback
> > * drop non-default partion probe types
> > * drop duplicate error checks
> > * drop duplicate error reporting
> > * fixed error message on MTD registeration
> > * fixed module removal routine
> >
> > v2..v3
> > * no changes (except number 08/16 -> 10/21)
> >
> > v0..v2
> > * use device tree
> > * use devm helpers where possible
> >
> > .../devicetree/bindings/mtd/sram-lp8x4x.txt | 20 +++
> > drivers/mtd/devices/Kconfig | 14 ++
> > drivers/mtd/devices/Makefile | 1 +
> > drivers/mtd/devices/sram_lp8x4x.c | 199
> > +++++++++++++++++++++
> > 4 files changed, 234 insertions(+)
> > create mode 100644 Documentation/devicetree/bindings/mtd/sram-
> > lp8x4x.txt
> > create mode 100644 drivers/mtd/devices/sram_lp8x4x.c
> >
> > diff --git a/Documentation/devicetree/bindings/mtd/sram-lp8x4x.txt
> > b/Documentation/devicetree/bindings/mtd/sram-lp8x4x.txt
> > new file mode 100644
> > index 0000000..476934f
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/mtd/sram-lp8x4x.txt
> > @@ -0,0 +1,20 @@
> > +512kB battery backed up SRAM on LP-8x4x industrial computers
> > +
> > +Required properties:
> > +- compatible : should be "icpdas,sram-lp8x4x"
>
> No wildcards please. Otherwise looks fine.
There is a similar review comment from Arnd Bergmann in the discussion
of `[PATCH v5] serial: support for 16550A serial ports on LP-8x4x`.
I'll quote my latest clarification:
> ... This driver will support ports on LP-8081,
> LP-8141, LP-8441, LP-8841. Last time I checked the vendor was announcing
> a series with 3 as the last digit. They use lp8x4x name, eg. in
> documentation like `LP-8x4x_ChangeLog.txt`. They ship their proprietary
> SDK in `lp8x4x_sdk_for_linux.tar`. All of this implies that it is a
> single board.
I think the solution should be the same for all LP-8x4x drivers (IRQ,
SRAM, SERIAL, IIO).
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH v5] mtd: support BB SRAM on ICP DAS LP-8x4x
[not found] ` <1450608238.15911.24.camel-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2016-01-06 23:25 ` Brian Norris
0 siblings, 0 replies; 148+ messages in thread
From: Brian Norris @ 2016-01-06 23:25 UTC (permalink / raw)
To: Sergei Ianovich
Cc: Rob Herring, linux-kernel-u79uwXL29TY76Z2rM5mHXA, Pawel Moll,
Mark Rutland, Ian Campbell, Kumar Gala, David Woodhouse,
Jeremy Kerr, Cyril Bur, Neelesh Gupta, Michael Ellerman,
Joel Stanley,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list:MEMORY TECHNOLOGY DEVICES (MTD), Arnd Bergmann
On Sun, Dec 20, 2015 at 01:43:58PM +0300, Sergei Ianovich wrote:
> On Sat, 2015-12-19 at 21:38 -0600, Rob Herring wrote:
> > On Tue, Dec 15, 2015 at 09:58:53PM +0300, Sergei Ianovich wrote:
> > > +Required properties:
> > > +- compatible : should be "icpdas,sram-lp8x4x"
> >
> > No wildcards please. Otherwise looks fine.
>
> There is a similar review comment from Arnd Bergmann in the discussion
> of `[PATCH v5] serial: support for 16550A serial ports on LP-8x4x`.
>
> I'll quote my latest clarification:
> > ... This driver will support ports on LP-8081,
^^ So 8081 doesn't even match the wildcard scheme you give in the
compatible string, proving the point of the Conventional Wisdom
suggestion Rob gave...
> > LP-8141, LP-8441, LP-8841. Last time I checked the vendor was announcing
> > a series with 3 as the last digit. They use lp8x4x name, eg. in
> > documentation like `LP-8x4x_ChangeLog.txt`. They ship their proprietary
> > SDK in `lp8x4x_sdk_for_linux.tar`. All of this implies that it is a
> > single board.
>
> I think the solution should be the same for all LP-8x4x drivers (IRQ,
> SRAM, SERIAL, IIO).
The rationale is described here:
http://devicetree.org/Device_Tree_Usage#Understanding_the_compatible_Property
Quote:
> Warning: Don't use wildcard compatible values, like "fsl,mpc83xx-uart"
> or similar. Silicon vendors will invariably make a change that breaks
> your wildcard assumptions the moment it is too late to change it.
> Instead, choose a specific silicon implementations and make all
> subsequent silicon compatible with it.
I don't think your circumstance is anything unique.
Regards,
Brian
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 148+ messages in thread
* [PATCH v6] mtd: support BB SRAM on ICP DAS LP-8x4x
[not found] ` <1450205941-15593-1-git-send-email-ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2016-02-23 18:58 ` Sergei Ianovich
[not found] ` <1456253890-30825-1-git-send-email-ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
0 siblings, 1 reply; 148+ messages in thread
From: Sergei Ianovich @ 2016-02-23 18:58 UTC (permalink / raw)
To: linux-kernel-u79uwXL29TY76Z2rM5mHXA
Cc: Sergei Ianovich, Rob Herring, Rob Herring, Pawel Moll,
Mark Rutland, Ian Campbell, Kumar Gala, David Woodhouse,
Brian Norris, Jeremy Kerr, Neelesh Gupta, Michael Ellerman,
Cyril Bur, Joel Stanley,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list:MEMORY TECHNOLOGY DEVICES [MTD]
This provides an MTD device driver for 512kB of battery backed up SRAM
on ICPDAS LP-8X4X programmable automation controllers.
SRAM chip is connected via FPGA and is not accessible without a driver,
unlike flash memory which is wired to CPU MMU.
This SRAM becomes an excellent persisent storage of volatile process
data like counter values and sensor statuses. Storing those data in
flash or mmc card is not a viable solution.
Signed-off-by: Sergei Ianovich <ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Reviewed-by: Brian Norris <computersforpeace-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
CC: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
v5..v6
* replace wildcards in compatible and module name
* drop obsolete mtd_part_parser_data.of_node
v4..v5
* remove .owner from struct platform_driver
* constify struct of_device_id
for further Brian Norris comments:
* drop unused property from doc file
* move defconfig update to a different file
* drop extra match w/ of_match_device()
v3..v4 for Brian Norris 'Reviewed-by'
* add doc file for DT binding
* move DTS binding to a different patch (8/21)
* drop unused include directive
* drop safely unused callback
* drop non-default partion probe types
* drop duplicate error checks
* drop duplicate error reporting
* fixed error message on MTD registeration
* fixed module removal routine
v2..v3
* no changes (except number 08/16 -> 10/21)
v0..v2
* use device tree
* use devm helpers where possible
---
.../devicetree/bindings/mtd/icpdas-lp8841-sram.txt | 23 +++
drivers/mtd/devices/Kconfig | 14 ++
drivers/mtd/devices/Makefile | 1 +
drivers/mtd/devices/sram_lp8841.c | 198 +++++++++++++++++++++
4 files changed, 236 insertions(+)
create mode 100644 Documentation/devicetree/bindings/mtd/icpdas-lp8841-sram.txt
create mode 100644 drivers/mtd/devices/sram_lp8841.c
diff --git a/Documentation/devicetree/bindings/mtd/icpdas-lp8841-sram.txt b/Documentation/devicetree/bindings/mtd/icpdas-lp8841-sram.txt
new file mode 100644
index 0000000..3c1007a
--- /dev/null
+++ b/Documentation/devicetree/bindings/mtd/icpdas-lp8841-sram.txt
@@ -0,0 +1,23 @@
+512kB battery backed up SRAM on ICP DAS LP-8841 industrial computers
+
+LP-8441, LP-8141, and LP-8041 differ from LP-8841 only in expansion
+slot count.
+
+Required properties:
+- compatible : should be "icpdas,lp8841-sram"
+
+- reg: physical base addresses and region lengths of
+ * IO memory range
+ * SRAM page selector
+
+SRAM chip is connected via FPGA and is not accessible without a driver,
+unlike flash memory which is wired to CPU MMU. Driver is essentially
+an address translation routine.
+
+Example:
+
+ sram@a000 {
+ compatible = "icpdas,lp8841-sram";
+ reg = <0xa000 0x1000
+ 0x901e 0x1>;
+ };
diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig
index f73c416..ecf5733 100644
--- a/drivers/mtd/devices/Kconfig
+++ b/drivers/mtd/devices/Kconfig
@@ -233,4 +233,18 @@ config BCH_CONST_T
default 4
endif
+config MTD_SRAM_LP8841
+ tristate "SRAM on ICP DAS LP-8841"
+ depends on OF && ARCH_PXA
+ ---help---
+ This provides an MTD device driver for 512kiB of battery backed up SRAM
+ on ICPDAS LP-8X41 programmable automation controllers.
+
+ SRAM chip is connected via FPGA and is not accessible without a driver,
+ unlike flash memory which is wired to CPU MMU.
+
+ Say N, unless you plan to run this kernel on LP-8X41.
+
+ If you say M, the module will be called sram_lp8841.
+
endmenu
diff --git a/drivers/mtd/devices/Makefile b/drivers/mtd/devices/Makefile
index 7912d3a..46df5d6 100644
--- a/drivers/mtd/devices/Makefile
+++ b/drivers/mtd/devices/Makefile
@@ -17,6 +17,7 @@ obj-$(CONFIG_MTD_SST25L) += sst25l.o
obj-$(CONFIG_MTD_BCM47XXSFLASH) += bcm47xxsflash.o
obj-$(CONFIG_MTD_ST_SPI_FSM) += st_spi_fsm.o
obj-$(CONFIG_MTD_POWERNV_FLASH) += powernv_flash.o
+obj-$(CONFIG_MTD_SRAM_LP8841) += sram_lp8841.o
CFLAGS_docg3.o += -I$(src)
diff --git a/drivers/mtd/devices/sram_lp8841.c b/drivers/mtd/devices/sram_lp8841.c
new file mode 100644
index 0000000..5d5d942
--- /dev/null
+++ b/drivers/mtd/devices/sram_lp8841.c
@@ -0,0 +1,198 @@
+/*
+ * linux/drivers/mtd/devices/sram_lp8841.c
+ *
+ * MTD Driver for SRAM on ICP DAS LP-8841
+ * Copyright (C) 2013 Sergei Ianovich <ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation or any later version.
+ */
+
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/platform_device.h>
+#include <linux/of_device.h>
+#include <linux/slab.h>
+#include <linux/string_helpers.h>
+#include <linux/types.h>
+
+struct lp8841_sram_info {
+ void __iomem *bank;
+ void __iomem *virt;
+ struct mutex lock;
+ unsigned active_bank;
+ struct mtd_info mtd;
+};
+
+static int
+lp8841_sram_erase(struct mtd_info *mtd, struct erase_info *instr)
+{
+ struct lp8841_sram_info *info = mtd->priv;
+ unsigned bank = instr->addr >> 11;
+ unsigned offset = (instr->addr & 0x7ff) << 1;
+ loff_t i;
+
+ mutex_lock(&info->lock);
+ if (unlikely(bank != info->active_bank)) {
+ info->active_bank = bank;
+ iowrite8(bank, info->bank);
+ }
+ for (i = 0; i < instr->len; i++) {
+ iowrite8(0xff, info->virt + offset);
+ offset += 2;
+ if (unlikely(offset == 0)) {
+ info->active_bank++;
+ iowrite8(info->active_bank, info->bank);
+ }
+ }
+ mutex_unlock(&info->lock);
+ instr->state = MTD_ERASE_DONE;
+ mtd_erase_callback(instr);
+
+ return 0;
+}
+
+static int
+lp8841_sram_write(struct mtd_info *mtd, loff_t to, size_t len,
+ size_t *retlen, const u_char *b)
+{
+ struct lp8841_sram_info *info = mtd->priv;
+ unsigned bank = to >> 11;
+ unsigned offset = (to & 0x7ff) << 1;
+ loff_t i;
+
+ mutex_lock(&info->lock);
+ if (unlikely(bank != info->active_bank)) {
+ info->active_bank = bank;
+ iowrite8(bank, info->bank);
+ }
+ for (i = 0; i < len; i++) {
+ iowrite8(b[i], info->virt + offset);
+ offset += 2;
+ if (unlikely(offset == 0)) {
+ info->active_bank++;
+ iowrite8(info->active_bank, info->bank);
+ }
+ }
+ mutex_unlock(&info->lock);
+ *retlen = len;
+ return 0;
+}
+
+static int
+lp8841_sram_read(struct mtd_info *mtd, loff_t from, size_t len,
+ size_t *retlen, u_char *b)
+{
+ struct lp8841_sram_info *info = mtd->priv;
+ unsigned bank = from >> 11;
+ unsigned offset = (from & 0x7ff) << 1;
+ loff_t i;
+
+ mutex_lock(&info->lock);
+ if (unlikely(bank != info->active_bank)) {
+ info->active_bank = bank;
+ iowrite8(bank, info->bank);
+ }
+ for (i = 0; i < len; i++) {
+ b[i] = ioread8(info->virt + offset);
+ offset += 2;
+ if (unlikely(offset == 0)) {
+ info->active_bank++;
+ iowrite8(info->active_bank, info->bank);
+ }
+ }
+ mutex_unlock(&info->lock);
+ *retlen = len;
+ return 0;
+}
+
+static const struct of_device_id of_flash_match[] = {
+ {
+ .compatible = "icpdas,lp8841-sram",
+ },
+ { },
+};
+MODULE_DEVICE_TABLE(of, of_flash_match);
+
+static int
+lp8841_sram_probe(struct platform_device *pdev)
+{
+ struct lp8841_sram_info *info;
+ struct resource *res_virt, *res_bank;
+ char sz_str[16];
+ struct mtd_part_parser_data ppdata;
+ int err = 0;
+
+ info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
+ if (!info)
+ return -ENOMEM;
+
+ res_virt = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ info->virt = devm_ioremap_resource(&pdev->dev, res_virt);
+ if (IS_ERR(info->virt))
+ return PTR_ERR(info->virt);
+
+ res_bank = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ info->bank = devm_ioremap_resource(&pdev->dev, res_bank);
+ if (IS_ERR(info->bank))
+ return PTR_ERR(info->bank);
+
+ info->mtd.priv = info;
+ info->mtd.name = "SRAM";
+ info->mtd.type = MTD_RAM;
+ info->mtd.flags = MTD_CAP_RAM;
+ info->mtd.size = resource_size(res_virt) << 7;
+ info->mtd.erasesize = 512;
+ info->mtd.writesize = 4;
+ info->mtd._erase = lp8841_sram_erase;
+ info->mtd._write = lp8841_sram_write;
+ info->mtd._read = lp8841_sram_read;
+ info->mtd.owner = THIS_MODULE;
+
+ mutex_init(&info->lock);
+ iowrite8(info->active_bank, info->bank);
+ platform_set_drvdata(pdev, info);
+
+ err = mtd_device_parse_register(&info->mtd, NULL, &ppdata,
+ NULL, 0);
+
+ if (err < 0) {
+ dev_err(&pdev->dev, "failed to register MTD\n");
+ return err;
+ }
+
+ string_get_size(info->mtd.size, 1, STRING_UNITS_2, sz_str,
+ sizeof(sz_str));
+ dev_info(&pdev->dev, "using %s SRAM on LP-8X4X as %s\n", sz_str,
+ dev_name(&info->mtd.dev));
+ return 0;
+}
+
+static int
+lp8841_sram_remove(struct platform_device *dev)
+{
+ struct lp8841_sram_info *info = platform_get_drvdata(dev);
+
+ return mtd_device_unregister(&info->mtd);
+}
+
+static struct platform_driver lp8841_sram_driver = {
+ .driver = {
+ .name = "sram-lp8841",
+ .of_match_table = of_flash_match,
+ },
+ .probe = lp8841_sram_probe,
+ .remove = lp8841_sram_remove,
+};
+
+module_platform_driver(lp8841_sram_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Sergei Ianovich");
+MODULE_DESCRIPTION("MTD driver for SRAM on ICPDAS LP-8841");
--
2.7.0
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 148+ messages in thread
* Re: [PATCH v6] mtd: support BB SRAM on ICP DAS LP-8x4x
[not found] ` <1456253890-30825-1-git-send-email-ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2016-02-23 19:48 ` Rob Herring
2016-03-08 0:19 ` Brian Norris
1 sibling, 0 replies; 148+ messages in thread
From: Rob Herring @ 2016-02-23 19:48 UTC (permalink / raw)
To: Sergei Ianovich
Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA, Pawel Moll, Mark Rutland,
Ian Campbell, Kumar Gala, David Woodhouse, Brian Norris,
Jeremy Kerr, Neelesh Gupta, Michael Ellerman, Cyril Bur,
Joel Stanley,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list:MEMORY TECHNOLOGY DEVICES [MTD]
On Tue, Feb 23, 2016 at 09:58:01PM +0300, Sergei Ianovich wrote:
> This provides an MTD device driver for 512kB of battery backed up SRAM
> on ICPDAS LP-8X4X programmable automation controllers.
>
> SRAM chip is connected via FPGA and is not accessible without a driver,
> unlike flash memory which is wired to CPU MMU.
>
> This SRAM becomes an excellent persisent storage of volatile process
> data like counter values and sensor statuses. Storing those data in
> flash or mmc card is not a viable solution.
>
> Signed-off-by: Sergei Ianovich <ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> Reviewed-by: Brian Norris <computersforpeace-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> CC: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
>
> v5..v6
> * replace wildcards in compatible and module name
> * drop obsolete mtd_part_parser_data.of_node
>
> v4..v5
> * remove .owner from struct platform_driver
> * constify struct of_device_id
> for further Brian Norris comments:
> * drop unused property from doc file
> * move defconfig update to a different file
> * drop extra match w/ of_match_device()
>
> v3..v4 for Brian Norris 'Reviewed-by'
> * add doc file for DT binding
> * move DTS binding to a different patch (8/21)
> * drop unused include directive
> * drop safely unused callback
> * drop non-default partion probe types
> * drop duplicate error checks
> * drop duplicate error reporting
> * fixed error message on MTD registeration
> * fixed module removal routine
>
> v2..v3
> * no changes (except number 08/16 -> 10/21)
>
> v0..v2
> * use device tree
> * use devm helpers where possible
> ---
> .../devicetree/bindings/mtd/icpdas-lp8841-sram.txt | 23 +++
Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> drivers/mtd/devices/Kconfig | 14 ++
> drivers/mtd/devices/Makefile | 1 +
> drivers/mtd/devices/sram_lp8841.c | 198 +++++++++++++++++++++
> 4 files changed, 236 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/mtd/icpdas-lp8841-sram.txt
> create mode 100644 drivers/mtd/devices/sram_lp8841.c
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 148+ messages in thread
* [PATCH v6] arm: pxa: support ICP DAS LP-8x4x FPGA irq
2015-12-15 19:26 ` [PATCH v5] arm: " Sergei Ianovich
` (2 preceding siblings ...)
[not found] ` <20151219035802.GA28424@rob-hp-laptop>
@ 2016-02-27 15:56 ` Sergei Ianovich
[not found] ` <1456588562-24715-1-git-send-email-ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
3 siblings, 1 reply; 148+ messages in thread
From: Sergei Ianovich @ 2016-02-27 15:56 UTC (permalink / raw)
To: linux-kernel
Cc: Sergei Ianovich, Arnd Bergmann, Rob Herring, Marc Zyngier,
Thomas Gleixner, Jason Cooper, Rob Herring, Pawel Moll,
Mark Rutland, Ian Campbell, Kumar Gala,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS
ICP DAS LP-8x4x contains FPGA chip. The chip functions as an interrupt
source providing 16 additional interrupts among other things. The
interrupt lines are muxed to a GPIO pin of a 2nd level PXA-GPIO
interrupt controller. GPIO pins of the 2nd level controller are in turn
muxed to a CPU interrupt line.
Until pxa is completely converted to device tree, it is impossible
to use IRQCHIP_DECLARE() and the irqdomain needs to added manually.
Drivers for the on-CPU IRQs and GPIO-IRQs are loaded using
postcore_initcall(). We need to have all irq domain drivers loaded prior
to DT parsing in order to allow normal initialization of IRQ resources
with DT.
Signed-off-by: Sergei Ianovich <ynvich@gmail.com>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
CC: Arnd Bergmann <arnd@arndb.de>
CC: Rob Herring <robh@kernel.org>
CC: Marc Zyngier <marc.zyngier@arm.com>
v5..v6
fixes according to Rob Herring review comments:
* drop wildcards in binding and file names
* rename alias 'fpga'->'fpga_irq'
fixes according to Marc Zyngier review comments:
* use writeb/readb not iowrite8/ioread8
* redefine 2nd mask using inversion on 1st
* add comments
v4..v5
* constify struct of_device_id
* drop irq number from handler signature
v3.2..v4
* move DTS binding to a different patch (8/21)
v3.1..v3.2
fixes to apply Linus Walleij's "Reviewed-by":
* add kerneldoc comment for state container struct
* rename irq -> hwirq for clarity
* drop overzealous error checks from the hotpaths
v3..v3.1
fixes according to Linus Walleij review comments:
* update commit message
* use state container instead of global variables
* get hardware irq nums from irq_data, don't calculate them
* use BIT() macro
* add defines for system irq register masks
* replace cycle control variable with break
* use better names for resource variables
* add a linear domain instead of a legacy one
* use irq_create_mapping() instead of irq_alloc_desc()
v2..v3
* no changes (except number 09/16 -> 11/21)
v0..v2
* extract irqchip and move to drivers/irqchip/
* use device tree
* use devm helpers where possible
---
.../interrupt-controller/icpdas-lp8x4x-irq.txt | 49 ++++
drivers/irqchip/Kconfig | 5 +
drivers/irqchip/Makefile | 1 +
drivers/irqchip/irq-lp8841.c | 246 +++++++++++++++++++++
4 files changed, 301 insertions(+)
create mode 100644 Documentation/devicetree/bindings/interrupt-controller/icpdas-lp8x4x-irq.txt
create mode 100644 drivers/irqchip/irq-lp8841.c
diff --git a/Documentation/devicetree/bindings/interrupt-controller/icpdas-lp8x4x-irq.txt b/Documentation/devicetree/bindings/interrupt-controller/icpdas-lp8x4x-irq.txt
new file mode 100644
index 0000000..a72109b
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/icpdas-lp8x4x-irq.txt
@@ -0,0 +1,49 @@
+ICP DAS LP-8841 FPGA Interrupt Controller
+
+ICP DAS LP-8841 contains FPGA chip. The chip functions as a interrupt
+source providing 16 additional interrupts among other things.
+
+Required properties:
+- compatible : should be "icpdas,lp8x4x-irq"
+
+- reg: physical base address of the controller and length of memory mapped
+ region.
+
+- interrupt-controller : identifies the node as an interrupt controller
+
+- #interrupt-cells : should be 1
+
+- interrupts : should provide interrupt
+
+Optional properties:
+
+- interrupt-parent : should provide a link to interrupt controller either
+ explicitly and implicitly from a parent node
+
+Example:
+
+fpgairq: irq@9006 {
+ compatible = "icpdas,lp8841-irq";
+ reg = <0x9006 0x16>;
+ interrupt-parent = <&gpio>;
+ interrupts = <3 IRQ_TYPE_EDGE_FALLING>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ status = "okay";
+};
+
+serial@9050 {
+ compatible = "icpdas,lp8841-uart";
+ reg = <0x9050 0x10
+ 0x9030 0x02>;
+ interrupts = <13>;
+ status = "okay";
+};
+
+serial@9060 {
+ compatible = "icpdas,lp8841-uart";
+ reg = <0x9060 0x10
+ 0x9032 0x02>;
+ interrupts = <14>;
+ status = "okay";
+};
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index fb50911..786073b 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -218,3 +218,8 @@ config IRQ_MXS
def_bool y if MACH_ASM9260 || ARCH_MXS
select IRQ_DOMAIN
select STMP_DEVICE
+
+config LP8841_IRQ
+ bool
+ def_bool y if MACH_PXA27X_DT
+ select IRQ_DOMAIN
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index 18caacb..05313d1 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -59,3 +59,4 @@ obj-$(CONFIG_ARCH_SA1100) += irq-sa11x0.o
obj-$(CONFIG_INGENIC_IRQ) += irq-ingenic.o
obj-$(CONFIG_IMX_GPCV2) += irq-imx-gpcv2.o
obj-$(CONFIG_PIC32_EVIC) += irq-pic32-evic.o
+obj-$(CONFIG_LP8841_IRQ) += irq-lp8841.o
diff --git a/drivers/irqchip/irq-lp8841.c b/drivers/irqchip/irq-lp8841.c
new file mode 100644
index 0000000..6a019f0
--- /dev/null
+++ b/drivers/irqchip/irq-lp8841.c
@@ -0,0 +1,246 @@
+/*
+ * linux/drivers/irqchip/irq-lp8841.c
+ *
+ * Support for ICP DAS LP-8841 FPGA irq
+ * Copyright (C) 2013 Sergei Ianovich <ynvich@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation or any later version.
+ */
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+
+#define MODULE_NAME "irq-lp8841"
+
+#define EOI 0x00000000
+#define INSINT 0x00000002
+#define ENSYSINT 0x00000004
+#define PRIMINT 0x00000006
+#define PRIMINT_MASK 0xe0
+#define SECOINT 0x00000008
+#define SECOINT_MASK (~(u8)PRIMINT_MASK)
+#define ENRISEINT 0x0000000A
+#define CLRRISEINT 0x0000000C
+#define ENHILVINT 0x0000000E
+#define CLRHILVINT 0x00000010
+#define ENFALLINT 0x00000012
+#define CLRFALLINT 0x00000014
+#define IRQ_MEM_SIZE 0x00000016
+#define LP8841_NUM_IRQ_DEFAULT 16
+
+/**
+ * struct lp8841_irq_data - LP8841 custom irq controller state container
+ * @base: base IO memory address
+ * @irq_domain: Interrupt translation domain; responsible for mapping
+ * between hwirq number and linux irq number
+ * @irq_sys_enabled: mask keeping track of interrupts enabled in the
+ * register which vendor calls 'system'
+ * @irq_high_enabled: mask keeping track of interrupts enabled in the
+ * register which vendor calls 'high'
+ *
+ * The structure implements State Container from
+ * Documentation/driver-model/design-patterns.txt
+ */
+
+struct lp8841_irq_data {
+ void *base;
+ struct irq_domain *domain;
+ unsigned char irq_sys_enabled;
+ unsigned char irq_high_enabled;
+};
+
+static void lp8841_mask_irq(struct irq_data *d)
+{
+ unsigned mask;
+ unsigned long hwirq = d->hwirq;
+ struct lp8841_irq_data *host = irq_data_get_irq_chip_data(d);
+
+ if (hwirq < 8) {
+ host->irq_high_enabled &= ~BIT(hwirq);
+
+ mask = readb(host->base + ENHILVINT);
+ mask &= ~BIT(hwirq);
+ writeb(mask, host->base + ENHILVINT);
+ } else {
+ hwirq -= 8;
+ host->irq_sys_enabled &= ~BIT(hwirq);
+
+ mask = readb(host->base + ENSYSINT);
+ mask &= ~BIT(hwirq);
+ writeb(mask, host->base + ENSYSINT);
+ }
+}
+
+static void lp8841_unmask_irq(struct irq_data *d)
+{
+ unsigned mask;
+ unsigned long hwirq = d->hwirq;
+ struct lp8841_irq_data *host = irq_data_get_irq_chip_data(d);
+
+ if (hwirq < 8) {
+ host->irq_high_enabled |= BIT(hwirq);
+ mask = readb(host->base + CLRHILVINT);
+ mask |= BIT(hwirq);
+ writeb(mask, host->base + CLRHILVINT);
+
+ mask = readb(host->base + ENHILVINT);
+ mask |= BIT(hwirq);
+ writeb(mask, host->base + ENHILVINT);
+ } else {
+ hwirq -= 8;
+ host->irq_sys_enabled |= BIT(hwirq);
+
+ mask = readb(host->base + SECOINT);
+ mask |= BIT(hwirq);
+ writeb(mask, host->base + SECOINT);
+
+ mask = readb(host->base + ENSYSINT);
+ mask |= BIT(hwirq);
+ writeb(mask, host->base + ENSYSINT);
+ }
+}
+
+static struct irq_chip lp8841_irq_chip = {
+ .name = "FPGA",
+ .irq_ack = lp8841_mask_irq,
+ .irq_mask = lp8841_mask_irq,
+ .irq_mask_ack = lp8841_mask_irq,
+ .irq_unmask = lp8841_unmask_irq,
+};
+
+static void lp8841_irq_handler(struct irq_desc *desc)
+{
+ int n;
+ unsigned long mask;
+ struct irq_chip *chip = irq_desc_get_chip(desc);
+ struct lp8841_irq_data *host = irq_desc_get_handler_data(desc);
+
+ chained_irq_enter(chip, desc);
+
+ for (;;) {
+ mask = readb(host->base + CLRHILVINT) & 0xff;
+ /* load two registers into a single byte */
+ mask |= (readb(host->base + SECOINT) & SECOINT_MASK) << 8;
+ mask |= (readb(host->base + PRIMINT) & PRIMINT_MASK) << 8;
+ if (mask == 0)
+ break;
+ for_each_set_bit(n, &mask, BITS_PER_LONG)
+ generic_handle_irq(irq_find_mapping(host->domain, n));
+ }
+
+ writeb(0, host->base + EOI);
+ chained_irq_exit(chip, desc);
+}
+
+static int lp8841_irq_domain_map(struct irq_domain *d, unsigned int irq,
+ irq_hw_number_t hw)
+{
+ struct lp8841_irq_data *host = d->host_data;
+ int err;
+
+ err = irq_set_chip_data(irq, host);
+ if (err < 0)
+ return err;
+
+ irq_set_chip_and_handler(irq, &lp8841_irq_chip, handle_level_irq);
+ irq_set_probe(irq);
+ return 0;
+}
+
+const struct irq_domain_ops lp8841_irq_domain_ops = {
+ .map = lp8841_irq_domain_map,
+ .xlate = irq_domain_xlate_onecell,
+};
+
+static const struct of_device_id lp8841_irq_dt_ids[] = {
+ { .compatible = "icpdas,lp8841-irq", },
+ {}
+};
+
+/*
+ * REVISIT probing will need to rewritten when PXA is converted to DT
+ */
+
+static int lp8841_irq_probe(struct platform_device *pdev)
+{
+ struct resource *res_mem;
+ int irq;
+ struct device_node *np = pdev->dev.of_node;
+ struct lp8841_irq_data *host;
+ int i, err;
+
+ irq = platform_get_irq(pdev, 0);
+ if (IS_ERR_VALUE(irq)) {
+ dev_err(&pdev->dev, "bad irq %i\n", irq);
+ return irq;
+ }
+
+ res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res_mem || resource_size(res_mem) < IRQ_MEM_SIZE) {
+ dev_err(&pdev->dev, "bad IOmem %p\n", res_mem);
+ if (res_mem)
+ dev_err(&pdev->dev, "bad start %p or size %u\n",
+ (void *) res_mem->start,
+ resource_size(res_mem));
+ return -ENODEV;
+ }
+
+ host = devm_kzalloc(&pdev->dev, sizeof(*host), GFP_KERNEL);
+ if (!host)
+ return -ENOMEM;
+
+ host->base = devm_ioremap_resource(&pdev->dev, res_mem);
+ if (!host->base) {
+ dev_err(&pdev->dev, "Failed to ioremap %p\n", host->base);
+ return -EFAULT;
+ }
+
+ host->domain = irq_domain_add_linear(np, LP8841_NUM_IRQ_DEFAULT,
+ &lp8841_irq_domain_ops, host);
+ if (!host->domain) {
+ dev_err(&pdev->dev, "Failed to add IRQ domain\n");
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < LP8841_NUM_IRQ_DEFAULT; i++) {
+ err = irq_create_mapping(host->domain, i);
+ if (err < 0)
+ dev_err(&pdev->dev, "Failed to map IRQ %i\n", i);
+ }
+
+ /* Initialize chip registers */
+ writeb(0, host->base + CLRRISEINT);
+ writeb(0, host->base + ENRISEINT);
+ writeb(0, host->base + CLRFALLINT);
+ writeb(0, host->base + ENFALLINT);
+ writeb(0, host->base + CLRHILVINT);
+ writeb(0, host->base + ENHILVINT);
+ writeb(0, host->base + ENSYSINT);
+ writeb(0, host->base + SECOINT);
+
+ irq_set_handler_data(irq, host);
+ irq_set_chained_handler(irq, lp8841_irq_handler);
+
+ pr_info(MODULE_NAME ": %i IRQs\n", LP8841_NUM_IRQ_DEFAULT);
+ return 0;
+}
+
+static struct platform_driver lp8841_irq_driver = {
+ .probe = lp8841_irq_probe,
+ .driver = {
+ .name = MODULE_NAME,
+ .of_match_table = lp8841_irq_dt_ids,
+ },
+};
+
+static int __init lp8841_irq_init(void)
+{
+ return platform_driver_register(&lp8841_irq_driver);
+}
+device_initcall(lp8841_irq_init);
--
2.7.0
^ permalink raw reply related [flat|nested] 148+ messages in thread
* [PATCH v6] serial: support for 16550A serial ports on LP-8x4x
[not found] ` <1450213494-21884-1-git-send-email-ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2016-02-27 16:14 ` Sergei Ianovich
[not found] ` <1456589675-25377-1-git-send-email-ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2016-02-29 21:26 ` [PATCH v7] " Sergei Ianovich
0 siblings, 2 replies; 148+ messages in thread
From: Sergei Ianovich @ 2016-02-27 16:14 UTC (permalink / raw)
To: linux-kernel-u79uwXL29TY76Z2rM5mHXA
Cc: Sergei Ianovich, Alan Cox, Andy Shevchenko, Arnd Bergmann,
Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
Greg Kroah-Hartman, Jiri Slaby, Heikki Krogerus, Masahiro Yamada,
Paul Burton, Paul Gortmaker, Mans Rullgard, Scott Wood,
Joachim Eastwood, Peter Ujfalusi, Peter Hurley,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE
The patch adds support for 3 additional LP-8x4x built-in serial
ports.
The device can also host up to 8 extension cards with 4 serial ports
on each card for a total of 35 ports. However, I don't have
the hardware to test extension cards, so they are not supported, yet.
Signed-off-by: Sergei Ianovich <ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Reviewed-by: Heikki Krogerus <heikki.krogerus-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
CC: Alan Cox <gnomes-qBU/x9rampVanCEyBjwyrvXRex20P6io@public.gmane.org>
CC: Andy Shevchenko <andriy.shevchenko-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
CC: Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org>
---
v5..v6
fix review comments by Arnd Bergmann
* remove wildcards from compatible
* update doc file
* drop interrupt parent from doc file
* replace uart w/ serial in device names in doc file
fix review comments by Andy Shevchenko
* exchange labels in switch block
* replace iowrite8() with writeb()
* compact comment to one line
v4..v5
* constify struct of_device_id
* drop .owner from struct platform_driver
* rewrite set_termios() baud rate hadnling as suggested by Alan Cox
v3..v4
* move DTS bindings to a different patch (8/21) as suggested by
Heikki Krogerus
v2..v3
* no changes (except number 10/16 -> 12/21)
v0..v2
* register platform driver instead of platform device
* use device tree
* use devm helpers where possible
.../bindings/serial/icpdas-lp8841-uart.txt | 41 +++++
drivers/tty/serial/8250/8250_lp8841.c | 166 +++++++++++++++++++++
drivers/tty/serial/8250/Kconfig | 14 ++
drivers/tty/serial/8250/Makefile | 2 +
4 files changed, 223 insertions(+)
create mode 100644 Documentation/devicetree/bindings/serial/icpdas-lp8841-uart.txt
create mode 100644 drivers/tty/serial/8250/8250_lp8841.c
diff --git a/Documentation/devicetree/bindings/serial/icpdas-lp8841-uart.txt b/Documentation/devicetree/bindings/serial/icpdas-lp8841-uart.txt
new file mode 100644
index 0000000..d6acd22
--- /dev/null
+++ b/Documentation/devicetree/bindings/serial/icpdas-lp8841-uart.txt
@@ -0,0 +1,41 @@
+* UART ports on ICP DAS LP-8841
+
+LP-8441, LP-8141 and LP-8041 are fully compatible.
+
+ICP DAS LP-8841 contains three additional serial ports interfaced via
+Analog Devices ADM213EA chips in addition to 3 serial ports on PXA CPU.
+
+The chips themselves are standard, they would work with 8250_core if
+properly connected. However, they are not connected normally. Al least
+some of their config pins are wired to a different address region. So
+the driver is board-specific.
+
+Required properties:
+- compatible : should be "icpdas,uart-lp8841"
+
+- reg : should provide 16 byte man IO memory region and 1 byte region for
+ termios
+
+- interrupts : should provide interrupt
+
+Optional property:
+- interrupt-parent : should provide a link to interrupt controller either
+ explicitly or implicitly from a parent node
+
+Examples (from pxa27x-lp8x4x.dts):
+
+ serial@9050 {
+ compatible = "icpdas,uart-lp8841";
+ reg = <0x9050 0x10
+ 0x9030 0x02>;
+ interrupts = <13>;
+ status = "okay";
+ };
+
+ serial@9060 {
+ compatible = "icpdas,uart-lp8841";
+ reg = <0x9060 0x10
+ 0x9032 0x02>;
+ interrupts = <14>;
+ status = "okay";
+ };
diff --git a/drivers/tty/serial/8250/8250_lp8841.c b/drivers/tty/serial/8250/8250_lp8841.c
new file mode 100644
index 0000000..6fef37f
--- /dev/null
+++ b/drivers/tty/serial/8250/8250_lp8841.c
@@ -0,0 +1,166 @@
+/* linux/drivers/tty/serial/8250/8250_lp8841.c
+ *
+ * Support for 16550A serial ports on ICP DAS LP-8841
+ *
+ * Copyright (C) 2013 Sergei Ianovich <ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+#include <linux/serial_8250.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+
+struct lp8841_serial_data {
+ int line;
+ void *ios_mem;
+};
+
+static void lp8841_serial_set_termios(struct uart_port *port,
+ struct ktermios *termios, struct ktermios *old)
+{
+ unsigned int len;
+ unsigned int baud;
+ struct lp8841_serial_data *data = port->private_data;
+
+ serial8250_do_set_termios(port, termios, old);
+
+ switch (termios->c_cflag & CSIZE) {
+ case CS5:
+ len = 7;
+ break;
+ case CS6:
+ len = 8;
+ break;
+ case CS7:
+ len = 9;
+ break;
+ case CS8:
+ default:
+ len = 10;
+ break;
+ }
+
+ if (termios->c_cflag & CSTOPB)
+ len++;
+ if (termios->c_cflag & PARENB)
+ len++;
+ if (!(termios->c_cflag & PARODD))
+ len++;
+#ifdef CMSPAR
+ if (termios->c_cflag & CMSPAR)
+ len++;
+#endif
+
+ len -= 9;
+ len &= 3;
+ len <<= 3;
+
+ /* Ask the core to calculate the divisor for us. */
+ baud = tty_termios_baud_rate(termios);
+
+ switch (baud) {
+ case 115200:
+ len |= 7;
+ break;
+ case 57600:
+ len |= 6;
+ break;
+ case 38400:
+ len |= 5;
+ break;
+ case 19200:
+ len |= 4;
+ break;
+ case 9600:
+ len |= 3;
+ break;
+ case 4800:
+ len |= 2;
+ break;
+ case 2400:
+ default:
+ len |= 1;
+ break;
+ };
+ writeb(len, data->ios_mem);
+
+}
+
+static const struct of_device_id lp8841_serial_dt_ids[] = {
+ { .compatible = "icpdas,lp8841-uart", },
+ {}
+};
+MODULE_DEVICE_TABLE(of, lp8841_serial_dt_ids);
+
+static int lp8841_serial_probe(struct platform_device *pdev)
+{
+ struct uart_8250_port uart = {};
+ struct lp8841_serial_data *data;
+ struct resource *mmres, *mires;
+ int ret;
+
+ mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ mires = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (!mmres || !mires)
+ return -ENODEV;
+
+ data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ data->ios_mem = devm_ioremap_resource(&pdev->dev, mires);
+ if (!data->ios_mem)
+ return -EFAULT;
+
+ uart.port.iotype = UPIO_MEM;
+ uart.port.mapbase = mmres->start;
+ uart.port.iobase = mmres->start;
+ uart.port.regshift = 1;
+ uart.port.irq = platform_get_irq(pdev, 0);
+ uart.port.flags = UPF_IOREMAP;
+ uart.port.dev = &pdev->dev;
+ uart.port.uartclk = 14745600;
+ uart.port.set_termios = lp8841_serial_set_termios;
+ uart.port.private_data = data;
+
+ ret = serial8250_register_8250_port(&uart);
+ if (ret < 0)
+ return ret;
+
+ data->line = ret;
+
+ platform_set_drvdata(pdev, data);
+
+ return 0;
+}
+
+static int lp8841_serial_remove(struct platform_device *pdev)
+{
+ struct lp8841_serial_data *data = platform_get_drvdata(pdev);
+
+ serial8250_unregister_port(data->line);
+
+ return 0;
+}
+
+static struct platform_driver lp8841_serial_driver = {
+ .probe = lp8841_serial_probe,
+ .remove = lp8841_serial_remove,
+
+ .driver = {
+ .name = "uart-lp8841",
+ .of_match_table = lp8841_serial_dt_ids,
+ },
+};
+
+module_platform_driver(lp8841_serial_driver);
+
+MODULE_AUTHOR("Sergei Ianovich");
+MODULE_DESCRIPTION("8250 serial port module for LP-8841");
+MODULE_LICENSE("GPL");
diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig
index 3b5cf9c..68640c1 100644
--- a/drivers/tty/serial/8250/Kconfig
+++ b/drivers/tty/serial/8250/Kconfig
@@ -394,3 +394,17 @@ config SERIAL_8250_PXA
help
If you have a machine based on an Intel XScale PXA2xx CPU you
can enable its onboard serial ports by enabling this option.
+
+ If you choose M here, the module name will be 8250_pxa.
+
+config SERIAL_8250_LP8841
+ tristate "Support 16550A ports on ICP DAS LP-8841"
+ depends on SERIAL_8250 && MACH_PXA27X_DT
+ select LP8841_IRQ
+ help
+ In addition to serial ports on PXA270 SoC, LP-8841 has 1 dual
+ RS232/RS485 port, 1 RS485 port and 1 RS232 port.
+
+ Say N here, unless you plan to run this kernel on a LP-8841 system.
+
+ If you choose M here, the module name will be 8250_lp8841.
diff --git a/drivers/tty/serial/8250/Makefile b/drivers/tty/serial/8250/Makefile
index d1e2f2d..10b4bf0 100644
--- a/drivers/tty/serial/8250/Makefile
+++ b/drivers/tty/serial/8250/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_SERIAL_8250_ACCENT) += 8250_accent.o
obj-$(CONFIG_SERIAL_8250_BOCA) += 8250_boca.o
obj-$(CONFIG_SERIAL_8250_EXAR_ST16C554) += 8250_exar_st16c554.o
obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o
+obj-$(CONFIG_SERIAL_8250_LP8X4X) += 8250_lp8x4x.o
obj-$(CONFIG_SERIAL_8250_FSL) += 8250_fsl.o
obj-$(CONFIG_SERIAL_8250_DW) += 8250_dw.o
obj-$(CONFIG_SERIAL_8250_EM) += 8250_em.o
@@ -30,5 +31,6 @@ obj-$(CONFIG_SERIAL_8250_INGENIC) += 8250_ingenic.o
obj-$(CONFIG_SERIAL_8250_MID) += 8250_mid.o
obj-$(CONFIG_SERIAL_OF_PLATFORM) += 8250_of.o
obj-$(CONFIG_SERIAL_8250_PXA) += 8250_pxa.o
+obj-$(CONFIG_SERIAL_8250_LP8841) += 8250_lp8841.o
CFLAGS_8250_ingenic.o += -I$(srctree)/scripts/dtc/libfdt
--
2.7.0
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 148+ messages in thread
* Re: [PATCH v6] arm: pxa: support ICP DAS LP-8x4x FPGA irq
[not found] ` <1456588562-24715-1-git-send-email-ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2016-02-27 17:41 ` Jason Cooper
[not found] ` <20160227174100.GG7219-fahSIxCzskDQ+YiMSub0/l6hYfS7NtTn@public.gmane.org>
2016-03-03 22:12 ` Rob Herring
1 sibling, 1 reply; 148+ messages in thread
From: Jason Cooper @ 2016-02-27 17:41 UTC (permalink / raw)
To: Sergei Ianovich
Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA, Arnd Bergmann, Rob Herring,
Marc Zyngier, Thomas Gleixner, Rob Herring, Pawel Moll,
Mark Rutland, Ian Campbell, Kumar Gala,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS
Hi Sergei,
Marc, Rob, please see below.
On Sat, Feb 27, 2016 at 06:56:01PM +0300, Sergei Ianovich wrote:
>
nit: Subject line of the patch should match 'irqchip/lp8841: [A-Z].*'
> ICP DAS LP-8x4x contains FPGA chip. The chip functions as an interrupt
> source providing 16 additional interrupts among other things. The
> interrupt lines are muxed to a GPIO pin of a 2nd level PXA-GPIO
> interrupt controller. GPIO pins of the 2nd level controller are in turn
> muxed to a CPU interrupt line.
>
> Until pxa is completely converted to device tree, it is impossible
> to use IRQCHIP_DECLARE() and the irqdomain needs to added manually.
> Drivers for the on-CPU IRQs and GPIO-IRQs are loaded using
> postcore_initcall(). We need to have all irq domain drivers loaded prior
> to DT parsing in order to allow normal initialization of IRQ resources
> with DT.
>
> Signed-off-by: Sergei Ianovich <ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> Reviewed-by: Linus Walleij <linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
nit: From here, down should be below the '---' so that it isn't a part
of the commit log. We add a link to the commit log that points to the
patch submission in the mailinglist archives. So curious folks have
quick access to this info.
> CC: Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org>
> CC: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> CC: Marc Zyngier <marc.zyngier-5wv7dgnIgG8@public.gmane.org>
>
> v5..v6
> fixes according to Rob Herring review comments:
> * drop wildcards in binding and file names
> * rename alias 'fpga'->'fpga_irq'
>
> fixes according to Marc Zyngier review comments:
> * use writeb/readb not iowrite8/ioread8
> * redefine 2nd mask using inversion on 1st
> * add comments
>
> v4..v5
> * constify struct of_device_id
> * drop irq number from handler signature
>
> v3.2..v4
> * move DTS binding to a different patch (8/21)
>
> v3.1..v3.2
> fixes to apply Linus Walleij's "Reviewed-by":
> * add kerneldoc comment for state container struct
> * rename irq -> hwirq for clarity
> * drop overzealous error checks from the hotpaths
>
> v3..v3.1
> fixes according to Linus Walleij review comments:
> * update commit message
> * use state container instead of global variables
> * get hardware irq nums from irq_data, don't calculate them
> * use BIT() macro
> * add defines for system irq register masks
> * replace cycle control variable with break
> * use better names for resource variables
> * add a linear domain instead of a legacy one
> * use irq_create_mapping() instead of irq_alloc_desc()
>
> v2..v3
> * no changes (except number 09/16 -> 11/21)
>
> v0..v2
> * extract irqchip and move to drivers/irqchip/
> * use device tree
> * use devm helpers where possible
> ---
iow, it should be moved here.
> .../interrupt-controller/icpdas-lp8x4x-irq.txt | 49 ++++
> drivers/irqchip/Kconfig | 5 +
> drivers/irqchip/Makefile | 1 +
> drivers/irqchip/irq-lp8841.c | 246 +++++++++++++++++++++
> 4 files changed, 301 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/interrupt-controller/icpdas-lp8x4x-irq.txt
> create mode 100644 drivers/irqchip/irq-lp8841.c
I don't seem to have the previous versions, and their threads, in my
email archive. From the changelog, it looks like Marc and Rob have been
reviewing this most recently.
If you guys could give me an Acked-by/Reviewed-by, I'll go ahead and
queue this up for v4.6.
I'll fix up the Subject line and the commit log when I bring it in.
I'll be adding the tags anyway. No need to resubmit.
thx,
Jason.
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH v6] arm: pxa: support ICP DAS LP-8x4x FPGA irq
[not found] ` <20160227174100.GG7219-fahSIxCzskDQ+YiMSub0/l6hYfS7NtTn@public.gmane.org>
@ 2016-02-29 8:29 ` Marc Zyngier
0 siblings, 0 replies; 148+ messages in thread
From: Marc Zyngier @ 2016-02-29 8:29 UTC (permalink / raw)
To: Jason Cooper, Sergei Ianovich
Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA, Arnd Bergmann, Rob Herring,
Thomas Gleixner, Rob Herring, Pawel Moll, Mark Rutland,
Ian Campbell, Kumar Gala,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS
On 27/02/16 17:41, Jason Cooper wrote:
> Hi Sergei,
>
> Marc, Rob, please see below.
>
> On Sat, Feb 27, 2016 at 06:56:01PM +0300, Sergei Ianovich wrote:
>>
>
> nit: Subject line of the patch should match 'irqchip/lp8841: [A-Z].*'
>
>> ICP DAS LP-8x4x contains FPGA chip. The chip functions as an interrupt
>> source providing 16 additional interrupts among other things. The
>> interrupt lines are muxed to a GPIO pin of a 2nd level PXA-GPIO
>> interrupt controller. GPIO pins of the 2nd level controller are in turn
>> muxed to a CPU interrupt line.
>>
>> Until pxa is completely converted to device tree, it is impossible
>> to use IRQCHIP_DECLARE() and the irqdomain needs to added manually.
>> Drivers for the on-CPU IRQs and GPIO-IRQs are loaded using
>> postcore_initcall(). We need to have all irq domain drivers loaded prior
>> to DT parsing in order to allow normal initialization of IRQ resources
>> with DT.
>>
>> Signed-off-by: Sergei Ianovich <ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
>> Reviewed-by: Linus Walleij <linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
>
> nit: From here, down should be below the '---' so that it isn't a part
> of the commit log. We add a link to the commit log that points to the
> patch submission in the mailinglist archives. So curious folks have
> quick access to this info.
>
>> CC: Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org>
>> CC: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
>> CC: Marc Zyngier <marc.zyngier-5wv7dgnIgG8@public.gmane.org>
>>
>> v5..v6
>> fixes according to Rob Herring review comments:
>> * drop wildcards in binding and file names
>> * rename alias 'fpga'->'fpga_irq'
>>
>> fixes according to Marc Zyngier review comments:
>> * use writeb/readb not iowrite8/ioread8
>> * redefine 2nd mask using inversion on 1st
>> * add comments
>>
>> v4..v5
>> * constify struct of_device_id
>> * drop irq number from handler signature
>>
>> v3.2..v4
>> * move DTS binding to a different patch (8/21)
>>
>> v3.1..v3.2
>> fixes to apply Linus Walleij's "Reviewed-by":
>> * add kerneldoc comment for state container struct
>> * rename irq -> hwirq for clarity
>> * drop overzealous error checks from the hotpaths
>>
>> v3..v3.1
>> fixes according to Linus Walleij review comments:
>> * update commit message
>> * use state container instead of global variables
>> * get hardware irq nums from irq_data, don't calculate them
>> * use BIT() macro
>> * add defines for system irq register masks
>> * replace cycle control variable with break
>> * use better names for resource variables
>> * add a linear domain instead of a legacy one
>> * use irq_create_mapping() instead of irq_alloc_desc()
>>
>> v2..v3
>> * no changes (except number 09/16 -> 11/21)
>>
>> v0..v2
>> * extract irqchip and move to drivers/irqchip/
>> * use device tree
>> * use devm helpers where possible
>
>
>> ---
>
> iow, it should be moved here.
>
>> .../interrupt-controller/icpdas-lp8x4x-irq.txt | 49 ++++
>> drivers/irqchip/Kconfig | 5 +
>> drivers/irqchip/Makefile | 1 +
>> drivers/irqchip/irq-lp8841.c | 246 +++++++++++++++++++++
>> 4 files changed, 301 insertions(+)
>> create mode 100644 Documentation/devicetree/bindings/interrupt-controller/icpdas-lp8x4x-irq.txt
>> create mode 100644 drivers/irqchip/irq-lp8841.c
>
> I don't seem to have the previous versions, and their threads, in my
> email archive. From the changelog, it looks like Marc and Rob have been
> reviewing this most recently.
>
> If you guys could give me an Acked-by/Reviewed-by, I'll go ahead and
> queue this up for v4.6.
>
> I'll fix up the Subject line and the commit log when I bring it in.
> I'll be adding the tags anyway. No need to resubmit.
Looks OK to me:
Acked-by: Marc Zyngier <marc.zyngier-5wv7dgnIgG8@public.gmane.org>
M.
--
Jazz is not dead. It just smells funny...
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH v6] serial: support for 16550A serial ports on LP-8x4x
[not found] ` <1456589675-25377-1-git-send-email-ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2016-02-29 10:29 ` Andy Shevchenko
2016-02-29 13:03 ` Sergei Ianovich
0 siblings, 1 reply; 148+ messages in thread
From: Andy Shevchenko @ 2016-02-29 10:29 UTC (permalink / raw)
To: Sergei Ianovich, linux-kernel-u79uwXL29TY76Z2rM5mHXA
Cc: Alan Cox, Arnd Bergmann, Rob Herring, Pawel Moll, Mark Rutland,
Ian Campbell, Kumar Gala, Greg Kroah-Hartman, Jiri Slaby,
Heikki Krogerus, Masahiro Yamada, Paul Burton, Paul Gortmaker,
Mans Rullgard, Scott Wood, Joachim Eastwood, Peter Ujfalusi,
Peter Hurley,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list:SERIAL DRIVERS
On Sat, 2016-02-27 at 19:14 +0300, Sergei Ianovich wrote:
> The patch adds support for 3 additional LP-8x4x built-in serial
> ports.
>
> The device can also host up to 8 extension cards with 4 serial ports
> on each card for a total of 35 ports. However, I don't have
> the hardware to test extension cards, so they are not supported, yet.
My comments below.
After addressing them:
Reviewed-by: Andy Shevchenko <andriy.shevchenko-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
> +++ b/drivers/tty/serial/8250/8250_lp8841.c
> @@ -0,0 +1,166 @@
> +/* linux/drivers/tty/serial/8250/8250_lp8841.c
> + *
> + * Support for 16550A serial ports on ICP DAS LP-8841
> + *
> + * Copyright (C) 2013 Sergei Ianovich <ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> + *
> + * This program is free software; you can redistribute it and/or
> modify
> + * it under the terms of the GNU General Public License version 2
> as
> + * published by the Free Software Foundation.
> + */
> +#include <linux/init.h>
> +#include <linux/io.h>
> +#include <linux/irq.h>
> +#include <linux/module.h>
> +#include <linux/serial_8250.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +
> +struct lp8841_serial_data {
> + int line;
> + void *ios_mem;
__iomem
> +};
> + if (termios->c_cflag & CSTOPB)
> + len++;
> + if (termios->c_cflag & PARENB)
> + len++;
> + if (!(termios->c_cflag & PARODD))
> + len++;
> +#ifdef CMSPAR
> + if (termios->c_cflag & CMSPAR)
> + len++;
> +#endif
> +
> + len -= 9;
If you have 5 bit mode, no parity, 1/1.5 stop bits, you may end up with
negative value here. Am I right? If so, is it expected?
> + len &= 3;
> + len <<= 3;
> + writeb(len, data->ios_mem);
> +
> +}
> +static int lp8841_serial_probe(struct platform_device *pdev)
> +{
> + struct uart_8250_port uart = {};
> + struct lp8841_serial_data *data;
> + struct resource *mmres, *mires;
> + int ret;
> +
> + mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> + mires = platform_get_resource(pdev, IORESOURCE_MEM, 1);
> + if (!mmres || !mires)
> + return -ENODEV;
No need to check mires here, devm_ioremap_resource() will take care
about.
> +
> + data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
> + if (!data)
> + return -ENOMEM;
> +
> + data->ios_mem = devm_ioremap_resource(&pdev->dev, mires);
> + if (!data->ios_mem)
> + return -EFAULT;
You have to propagate the actual error code from
devm_ioremap_resource().
> +
> + uart.port.iotype = UPIO_MEM;
>
> + uart.port.mapbase = mmres->start;
> + uart.port.iobase = mmres->start;
I'm not sure about this. If you ask for UPIO_MEM why do you need to
fill iobase?
And I suppose iobase can't hold (at the end inb/outb calls) big port
numbers anyway (16 bit on x86, for example).
> + uart.port.regshift = 1;
> + uart.port.irq = platform_get_irq(pdev, 0);
> + uart.port.flags = UPF_IOREMAP;
> + uart.port.dev = &pdev->dev;
> + uart.port.uartclk = 14745600;
> + uart.port.set_termios = lp8841_serial_set_termios;
> + uart.port.private_data = data;
> +
> + ret = serial8250_register_8250_port(&uart);
> + if (ret < 0)
> + return ret;
> +
> + data->line = ret;
> +
> + platform_set_drvdata(pdev, data);
> +
> + return 0;
> +}
> +
> +static int lp8841_serial_remove(struct platform_device *pdev)
> +{
> + struct lp8841_serial_data *data =
> platform_get_drvdata(pdev);
> +
> + serial8250_unregister_port(data->line);
> +
> + return 0;
> +}
> +
> +static struct platform_driver lp8841_serial_driver = {
> + .probe = lp8841_serial_probe,
> + .remove = lp8841_serial_remove,
> +
> + .driver = {
> + .name = "uart-lp8841",
> + .of_match_table = lp8841_serial_dt_ids,
> + },
> +};
--
Andy Shevchenko <andriy.shevchenko-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
Intel Finland Oy
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH v6] serial: support for 16550A serial ports on LP-8x4x
2016-02-29 10:29 ` Andy Shevchenko
@ 2016-02-29 13:03 ` Sergei Ianovich
[not found] ` <1456750995.23036.87.camel-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
0 siblings, 1 reply; 148+ messages in thread
From: Sergei Ianovich @ 2016-02-29 13:03 UTC (permalink / raw)
To: Andy Shevchenko, linux-kernel
Cc: Alan Cox, Arnd Bergmann, Rob Herring, Pawel Moll, Mark Rutland,
Ian Campbell, Kumar Gala, Greg Kroah-Hartman, Jiri Slaby,
Heikki Krogerus, Masahiro Yamada, Paul Burton, Paul Gortmaker,
Mans Rullgard, Scott Wood, Joachim Eastwood, Peter Ujfalusi,
Peter Hurley,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list:SERIAL DRIVERS
On Mon, 2016-02-29 at 12:29 +0200, Andy Shevchenko wrote:
> On Sat, 2016-02-27 at 19:14 +0300, Sergei Ianovich wrote:
> > +struct lp8841_serial_data {
> > + int line;
> > + void *ios_mem;
>
> __iomem
OK
> > +};
>
> > + if (termios->c_cflag & CSTOPB)
> > + len++;
> > + if (termios->c_cflag & PARENB)
> > + len++;
> > + if (!(termios->c_cflag & PARODD))
> > + len++;
> > +#ifdef CMSPAR
> > + if (termios->c_cflag & CMSPAR)
> > + len++;
> > +#endif
> > +
> > + len -= 9;
>
> If you have 5 bit mode, no parity, 1/1.5 stop bits, you may end up
> with
> negative value here. Am I right? If so, is it expected?
>
> > + len &= 3;
> > + len <<= 3;
I haven't tested this mode. I am pretty sure it will fail. There is
also no support for speeds higher than 115200.
CS7 and CS8 at speeds up to 115200 work well.
However, there is no way to report errors from set_termios(). Should
anything be done about those limitations?
> + mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > + mires = platform_get_resource(pdev, IORESOURCE_MEM, 1);
> > + if (!mmres || !mires)
> > + return -ENODEV;
>
> No need to check mires here, devm_ioremap_resource() will take care
> about.
OK
> > + data->ios_mem = devm_ioremap_resource(&pdev->dev,
> > > > mires);
> > + if (!data->ios_mem)
> > + return -EFAULT;
>
> You have to propagate the actual error code from
> devm_ioremap_resource().
OK
> > +
> > + uart.port.iotype = UPIO_MEM;
> >
>
> > + uart.port.mapbase = mmres->start;
> > + uart.port.iobase = mmres->start;
>
> I'm not sure about this. If you ask for UPIO_MEM why do you need to
> fill iobase?
> And I suppose iobase can't hold (at the end inb/outb calls) big port
> numbers anyway (16 bit on x86, for example).
There is no need for iobase. I'll remove that line.
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH v6] serial: support for 16550A serial ports on LP-8x4x
[not found] ` <1456750995.23036.87.camel-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2016-02-29 14:45 ` One Thousand Gnomes
0 siblings, 0 replies; 148+ messages in thread
From: One Thousand Gnomes @ 2016-02-29 14:45 UTC (permalink / raw)
To: Sergei Ianovich
Cc: Andy Shevchenko, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
Arnd Bergmann, Rob Herring, Pawel Moll, Mark Rutland,
Ian Campbell, Kumar Gala, Greg Kroah-Hartman, Jiri Slaby,
Heikki Krogerus, Masahiro Yamada, Paul Burton, Paul Gortmaker,
Mans Rullgard, Scott Wood, Joachim Eastwood, Peter Ujfalusi,
Peter Hurley,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS
> I haven't tested this mode. I am pretty sure it will fail. There is
> also no support for speeds higher than 115200.
>
> CS7 and CS8 at speeds up to 115200 work well.
>
> However, there is no way to report errors from set_termios(). Should
> anything be done about those limitations?
You report back by setting the termios fields to the values actually
selected. Eg if you can't do CS5/CS6 you'd pick CS7 or CS8 and write that
back into tty->termios so the caller knows what they actually got. Ditto
for speed (see the 16550A core driver for the speed write backs).
Alan
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 148+ messages in thread
* [PATCH v7] serial: support for 16550A serial ports on LP-8x4x
2016-02-27 16:14 ` [PATCH v6] " Sergei Ianovich
[not found] ` <1456589675-25377-1-git-send-email-ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2016-02-29 21:26 ` Sergei Ianovich
[not found] ` <1456781209-11390-1-git-send-email-ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2016-03-01 19:54 ` [PATCH v8] " Sergei Ianovich
1 sibling, 2 replies; 148+ messages in thread
From: Sergei Ianovich @ 2016-02-29 21:26 UTC (permalink / raw)
To: linux-kernel
Cc: Sergei Ianovich, Alan Cox, Andy Shevchenko, Arnd Bergmann,
Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
Greg Kroah-Hartman, Jiri Slaby, Heikki Krogerus, Peter Hurley,
Masahiro Yamada, Paul Burton, Mans Rullgard, Joachim Eastwood,
Scott Wood, Paul Gortmaker, Peter Ujfalusi,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE
The patch adds support for 3 additional LP-8x4x built-in serial
ports.
The device can also host up to 8 extension cards with 4 serial ports
on each card for a total of 35 ports. However, I don't have
the hardware to test extension cards, so they are not supported, yet.
Signed-off-by: Sergei Ianovich <ynvich@gmail.com>
Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
---
CC: Alan Cox <gnomes@lxorguk.ukuu.org.uk>
CC: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
CC: Arnd Bergmann <arnd@arndb.de>
v6..v7
fix review comments by Andy Shevchenko
not applying Acked-by as the 1st change is big
* handle unsupported tty modes correctly as suggested by Alan Cox
* remove extra check of platform_get_resource() result
* propagate error code from devm_ioremap_resource()
* drop uart.port.iobase for UPIO_MEM device
v5..v6
fix review comments by Arnd Bergmann
* remove wildcards from compatible
* update doc file
* drop interrupt parent from doc file
* replace uart w/ serial in device names in doc file
fix review comments by Andy Shevchenko
* exchange labels in switch block
* replace iowrite8() with writeb()
* compact comment to one line
v4..v5
* constify struct of_device_id
* drop .owner from struct platform_driver
* rewrite set_termios() baud rate hadnling as suggested by Alan Cox
v3..v4
* move DTS bindings to a different patch (8/21) as suggested by
Heikki Krogerus
v2..v3
* no changes (except number 10/16 -> 12/21)
v0..v2
* register platform driver instead of platform device
* use device tree
* use devm helpers where possible
.../bindings/serial/icpdas-lp8841-uart.txt | 41 +++++
drivers/tty/serial/8250/8250_lp8841.c | 193 +++++++++++++++++++++
drivers/tty/serial/8250/Kconfig | 14 ++
drivers/tty/serial/8250/Makefile | 2 +
4 files changed, 250 insertions(+)
create mode 100644 Documentation/devicetree/bindings/serial/icpdas-lp8841-uart.txt
create mode 100644 drivers/tty/serial/8250/8250_lp8841.c
diff --git a/Documentation/devicetree/bindings/serial/icpdas-lp8841-uart.txt b/Documentation/devicetree/bindings/serial/icpdas-lp8841-uart.txt
new file mode 100644
index 0000000..d6acd22
--- /dev/null
+++ b/Documentation/devicetree/bindings/serial/icpdas-lp8841-uart.txt
@@ -0,0 +1,41 @@
+* UART ports on ICP DAS LP-8841
+
+LP-8441, LP-8141 and LP-8041 are fully compatible.
+
+ICP DAS LP-8841 contains three additional serial ports interfaced via
+Analog Devices ADM213EA chips in addition to 3 serial ports on PXA CPU.
+
+The chips themselves are standard, they would work with 8250_core if
+properly connected. However, they are not connected normally. Al least
+some of their config pins are wired to a different address region. So
+the driver is board-specific.
+
+Required properties:
+- compatible : should be "icpdas,uart-lp8841"
+
+- reg : should provide 16 byte man IO memory region and 1 byte region for
+ termios
+
+- interrupts : should provide interrupt
+
+Optional property:
+- interrupt-parent : should provide a link to interrupt controller either
+ explicitly or implicitly from a parent node
+
+Examples (from pxa27x-lp8x4x.dts):
+
+ serial@9050 {
+ compatible = "icpdas,uart-lp8841";
+ reg = <0x9050 0x10
+ 0x9030 0x02>;
+ interrupts = <13>;
+ status = "okay";
+ };
+
+ serial@9060 {
+ compatible = "icpdas,uart-lp8841";
+ reg = <0x9060 0x10
+ 0x9032 0x02>;
+ interrupts = <14>;
+ status = "okay";
+ };
diff --git a/drivers/tty/serial/8250/8250_lp8841.c b/drivers/tty/serial/8250/8250_lp8841.c
new file mode 100644
index 0000000..e92c01c
--- /dev/null
+++ b/drivers/tty/serial/8250/8250_lp8841.c
@@ -0,0 +1,193 @@
+/* linux/drivers/tty/serial/8250/8250_lp8841.c
+ *
+ * Support for 16550A serial ports on ICP DAS LP-8841
+ *
+ * Copyright (C) 2013 Sergei Ianovich <ynvich@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+#include <linux/serial_8250.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+
+struct lp8841_serial_data {
+ int line;
+ void __iomem *ios_mem;
+};
+
+static void lp8841_serial_set_termios(struct uart_port *port,
+ struct ktermios *termios, struct ktermios *old)
+{
+#ifdef BOTHER
+ unsigned int cbaud;
+#endif
+ unsigned int baud;
+ unsigned int len;
+ unsigned int old_csize = old ? old->c_cflag & CSIZE : CS8;
+ struct lp8841_serial_data *data = port->private_data;
+
+ /* We only support CS7 and CS8 */
+ while ((termios->c_cflag & CSIZE) != CS7 &&
+ (termios->c_cflag & CSIZE) != CS8) {
+ termios->c_cflag &= ~CSIZE;
+ termios->c_cflag |= old_csize;
+ old_csize = CS8;
+ }
+
+ serial8250_do_set_termios(port, termios, old);
+
+ if ((termios->c_cflag & CSIZE) == CS7)
+ len = 9;
+ else
+ len = 10;
+
+ if (termios->c_cflag & CSTOPB)
+ len++;
+ if (termios->c_cflag & PARENB)
+ len++;
+ if (!(termios->c_cflag & PARODD))
+ len++;
+#ifdef CMSPAR
+ if (termios->c_cflag & CMSPAR)
+ len++;
+#endif
+
+ len -= 9;
+ len &= 3;
+ len <<= 3;
+
+ baud = tty_termios_baud_rate(termios);
+
+#ifdef BOTHER
+ /* We only support fixed rates */
+ cbaud = termios->c_cflag & CBAUD;
+
+ if (cbaud == BOTHER) {
+ termios->c_cflag &= ~BOTHER;
+
+ /* Don't rewrite B0 */
+ if (baud) {
+ tty_termios_encode_baud_rate(termios, baud, baud);
+ baud = tty_termios_baud_rate(termios);
+
+ /* Set sane default speed if we get 0 */
+ if (!baud) {
+ baud = 9600;
+ tty_termios_encode_baud_rate(termios,
+ baud, baud);
+ }
+ }
+ }
+#endif
+
+ /* We only support up to 115200 */
+ if (baud > 115200) {
+ baud = 115200;
+ tty_termios_encode_baud_rate(termios, baud, baud);
+ }
+
+ switch (baud) {
+ case 115200:
+ len |= 7;
+ break;
+ case 57600:
+ len |= 6;
+ break;
+ case 38400:
+ len |= 5;
+ break;
+ case 19200:
+ len |= 4;
+ break;
+ case 9600:
+ len |= 3;
+ break;
+ case 4800:
+ len |= 2;
+ break;
+ case 2400:
+ default:
+ len |= 1;
+ break;
+ };
+ writeb(len, data->ios_mem);
+
+}
+
+static const struct of_device_id lp8841_serial_dt_ids[] = {
+ { .compatible = "icpdas,lp8841-uart", },
+ {}
+};
+MODULE_DEVICE_TABLE(of, lp8841_serial_dt_ids);
+
+static int lp8841_serial_probe(struct platform_device *pdev)
+{
+ struct uart_8250_port uart = {};
+ struct lp8841_serial_data *data;
+ struct resource *mmres, *mires;
+ int ret;
+
+ mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ mires = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (!mmres)
+ return -ENODEV;
+
+ data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ data->ios_mem = devm_ioremap_resource(&pdev->dev, mires);
+ if (IS_ERR(data->ios_mem))
+ return PTR_ERR(data->ios_mem);
+
+ uart.port.iotype = UPIO_MEM;
+ uart.port.mapbase = mmres->start;
+ uart.port.regshift = 1;
+ uart.port.irq = platform_get_irq(pdev, 0);
+ uart.port.flags = UPF_IOREMAP;
+ uart.port.dev = &pdev->dev;
+ uart.port.uartclk = 14745600;
+ uart.port.set_termios = lp8841_serial_set_termios;
+ uart.port.private_data = data;
+
+ ret = serial8250_register_8250_port(&uart);
+ if (ret < 0)
+ return ret;
+
+ data->line = ret;
+
+ platform_set_drvdata(pdev, data);
+
+ return 0;
+}
+
+static int lp8841_serial_remove(struct platform_device *pdev)
+{
+ struct lp8841_serial_data *data = platform_get_drvdata(pdev);
+
+ serial8250_unregister_port(data->line);
+
+ return 0;
+}
+
+static struct platform_driver lp8841_serial_driver = {
+ .probe = lp8841_serial_probe,
+ .remove = lp8841_serial_remove,
+
+ .driver = {
+ .name = "uart-lp8841",
+ .of_match_table = lp8841_serial_dt_ids,
+ },
+};
+
+module_platform_driver(lp8841_serial_driver);
+
+MODULE_AUTHOR("Sergei Ianovich");
+MODULE_DESCRIPTION("8250 serial port module for LP-8841");
+MODULE_LICENSE("GPL");
diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig
index 3b5cf9c..68640c1 100644
--- a/drivers/tty/serial/8250/Kconfig
+++ b/drivers/tty/serial/8250/Kconfig
@@ -394,3 +394,17 @@ config SERIAL_8250_PXA
help
If you have a machine based on an Intel XScale PXA2xx CPU you
can enable its onboard serial ports by enabling this option.
+
+ If you choose M here, the module name will be 8250_pxa.
+
+config SERIAL_8250_LP8841
+ tristate "Support 16550A ports on ICP DAS LP-8841"
+ depends on SERIAL_8250 && MACH_PXA27X_DT
+ select LP8841_IRQ
+ help
+ In addition to serial ports on PXA270 SoC, LP-8841 has 1 dual
+ RS232/RS485 port, 1 RS485 port and 1 RS232 port.
+
+ Say N here, unless you plan to run this kernel on a LP-8841 system.
+
+ If you choose M here, the module name will be 8250_lp8841.
diff --git a/drivers/tty/serial/8250/Makefile b/drivers/tty/serial/8250/Makefile
index d1e2f2d..10b4bf0 100644
--- a/drivers/tty/serial/8250/Makefile
+++ b/drivers/tty/serial/8250/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_SERIAL_8250_ACCENT) += 8250_accent.o
obj-$(CONFIG_SERIAL_8250_BOCA) += 8250_boca.o
obj-$(CONFIG_SERIAL_8250_EXAR_ST16C554) += 8250_exar_st16c554.o
obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o
+obj-$(CONFIG_SERIAL_8250_LP8X4X) += 8250_lp8x4x.o
obj-$(CONFIG_SERIAL_8250_FSL) += 8250_fsl.o
obj-$(CONFIG_SERIAL_8250_DW) += 8250_dw.o
obj-$(CONFIG_SERIAL_8250_EM) += 8250_em.o
@@ -30,5 +31,6 @@ obj-$(CONFIG_SERIAL_8250_INGENIC) += 8250_ingenic.o
obj-$(CONFIG_SERIAL_8250_MID) += 8250_mid.o
obj-$(CONFIG_SERIAL_OF_PLATFORM) += 8250_of.o
obj-$(CONFIG_SERIAL_8250_PXA) += 8250_pxa.o
+obj-$(CONFIG_SERIAL_8250_LP8841) += 8250_lp8841.o
CFLAGS_8250_ingenic.o += -I$(srctree)/scripts/dtc/libfdt
--
2.7.0
^ permalink raw reply related [flat|nested] 148+ messages in thread
* Re: [PATCH v7] serial: support for 16550A serial ports on LP-8x4x
[not found] ` <1456781209-11390-1-git-send-email-ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2016-03-01 11:06 ` Andy Shevchenko
[not found] ` <1456830401.13244.189.camel-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
0 siblings, 1 reply; 148+ messages in thread
From: Andy Shevchenko @ 2016-03-01 11:06 UTC (permalink / raw)
To: Sergei Ianovich, linux-kernel-u79uwXL29TY76Z2rM5mHXA
Cc: Alan Cox, Arnd Bergmann, Rob Herring, Pawel Moll, Mark Rutland,
Ian Campbell, Kumar Gala, Greg Kroah-Hartman, Jiri Slaby,
Heikki Krogerus, Peter Hurley, Masahiro Yamada, Paul Burton,
Mans Rullgard, Joachim Eastwood, Scott Wood, Paul Gortmaker,
Peter Ujfalusi,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list:SERIAL DRIVERS
On Tue, 2016-03-01 at 00:26 +0300, Sergei Ianovich wrote:
> The patch adds support for 3 additional LP-8x4x built-in serial
> ports.
>
> The device can also host up to 8 extension cards with 4 serial ports
> on each card for a total of 35 ports. However, I don't have
> the hardware to test extension cards, so they are not supported, yet.
>
> Signed-off-by: Sergei Ianovich <ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> Reviewed-by: Heikki Krogerus <heikki.krogerus-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
Few more comments, mostly about style.
> +static void lp8841_serial_set_termios(struct uart_port *port,
> + struct ktermios *termios, struct ktermios *old)
> +{
> +#ifdef BOTHER
> + unsigned int cbaud;
> +#endif
> + unsigned int baud;
> + unsigned int len;
Since you are writing this to the register at the end maybe
- unsigned int -> u8 (write*b* — exactly one byte)
- len -> value (it's not only about data length)
> + unsigned int old_csize = old ? old->c_cflag & CSIZE : CS8;
> + struct lp8841_serial_data *data = port->private_data;
> +
> + /* We only support CS7 and CS8 */
> + while ((termios->c_cflag & CSIZE) != CS7 &&
> + (termios->c_cflag & CSIZE) != CS8) {
> + termios->c_cflag &= ~CSIZE;
> + termios->c_cflag |= old_csize;
> + old_csize = CS8;
> + }
> +
> + serial8250_do_set_termios(port, termios, old);
> +
> + if ((termios->c_cflag & CSIZE) == CS7)
> + len = 9;
> + else
> + len = 10;
> +
> + if (termios->c_cflag & CSTOPB)
> + len++;
> + if (termios->c_cflag & PARENB)
> + len++;
> + if (!(termios->c_cflag & PARODD))
> + len++;
> +#ifdef CMSPAR
> + if (termios->c_cflag & CMSPAR)
> + len++;
> +#endif
I don't know if someone likes it or not (up to you), but for me looks
better to have ternary operators here:
value += (termios->c_cflag & CSTOPB) ? 1 : 0;
value += (termios->c_cflag & PARENB) ? 1 : 0;
value += (termios->c_cflag & PARODD) ? 0 : 1;
#ifdef CMSPAR
value += (termios->c_cflag & CMSPAR) ? 1 : 0;
#endif
> + len -= 9;
This one could be part of previous evaluation:
value = (termios->c_cflag & CSIZE) == CS7 ? 0 : 1;
> + len &= 3;
> + len <<= 3;
Perhaps to define magic number (e.g. LP8841_DATA_LEN_SHIFT).
> +
> + baud = tty_termios_baud_rate(termios);
> +
> +#ifdef BOTHER
> + /* We only support fixed rates */
> + cbaud = termios->c_cflag & CBAUD;
> +
> + if (cbaud == BOTHER) {
> + termios->c_cflag &= ~BOTHER;
> +
> + /* Don't rewrite B0 */
> + if (baud) {
> + tty_termios_encode_baud_rate(termios, baud,
> baud);
> + baud = tty_termios_baud_rate(termios);
> +
> + /* Set sane default speed if we get 0 */
> + if (!baud) {
> + baud = 9600;
> + tty_termios_encode_baud_rate(termios
> ,
> + baud, baud);
I think you can call this unconditionally together with case > 115200.
> + }
> + }
> + }
> +#endif
> +
> + /* We only support up to 115200 */
> + if (baud > 115200) {
> + baud = 115200;
> + tty_termios_encode_baud_rate(termios, baud, baud);
> + }
Btw, can we use uart_get_baud_rate() here?
> + writeb(len, data->ios_mem);
> +
> +}
> +static int lp8841_serial_probe(struct platform_device *pdev)
> +{
> + struct uart_8250_port uart = {};
{0}
> + struct lp8841_serial_data *data;
> + struct resource *mmres, *mires;
> + int ret;
> +
> + mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> + mires = platform_get_resource(pdev, IORESOURCE_MEM, 1);
Perhaps move it down to be closer to devm_ioremap_resource() call.
> + if (!mmres)
> + return -ENODEV;
> +
> + data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
> + if (!data)
> + return -ENOMEM;
> +
+ mires = platform_get_resource(pdev, IORESOURCE_MEM, 1);
> + data->ios_mem = devm_ioremap_resource(&pdev->dev, mires);
> + if (IS_ERR(data->ios_mem))
> + return PTR_ERR(data->ios_mem);
--
Andy Shevchenko <andriy.shevchenko-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
Intel Finland Oy
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH v7] serial: support for 16550A serial ports on LP-8x4x
[not found] ` <1456830401.13244.189.camel-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
@ 2016-03-01 16:25 ` Sergei Ianovich
2016-03-01 16:46 ` Andy Shevchenko
0 siblings, 1 reply; 148+ messages in thread
From: Sergei Ianovich @ 2016-03-01 16:25 UTC (permalink / raw)
To: Andy Shevchenko, linux-kernel-u79uwXL29TY76Z2rM5mHXA
Cc: Alan Cox, Arnd Bergmann, Rob Herring, Pawel Moll, Mark Rutland,
Ian Campbell, Kumar Gala, Greg Kroah-Hartman, Jiri Slaby,
Heikki Krogerus, Peter Hurley, Masahiro Yamada, Paul Burton,
Mans Rullgard, Joachim Eastwood, Scott Wood, Paul Gortmaker,
Peter Ujfalusi,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list:SERIAL DRIVERS
On Tue, 2016-03-01 at 13:06 +0200, Andy Shevchenko wrote:
> On Tue, 2016-03-01 at 00:26 +0300, Sergei Ianovich wrote:
> > The patch adds support for 3 additional LP-8x4x built-in serial
> > ports.
> >
> > The device can also host up to 8 extension cards with 4 serial
> > ports
> > on each card for a total of 35 ports. However, I don't have
> > the hardware to test extension cards, so they are not supported,
> > yet.
> >
> > Signed-off-by: Sergei Ianovich <ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> > Reviewed-by: Heikki Krogerus <heikki.krogerus-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
>
> Few more comments, mostly about style.
>
> > +static void lp8841_serial_set_termios(struct uart_port *port,
> > + struct ktermios *termios, struct ktermios *old)
> > +{
> > +#ifdef BOTHER
> > + unsigned int cbaud;
> > +#endif
> > + unsigned int baud;
> > + unsigned int len;
>
> Since you are writing this to the register at the end maybe
> - unsigned int -> u8 (write*b* — exactly one byte)
> - len -> value (it's not only about data length)
>
> > + unsigned int old_csize = old ? old->c_cflag & CSIZE : CS8;
> > + struct lp8841_serial_data *data = port->private_data;
> > +
> > + /* We only support CS7 and CS8 */
> > + while ((termios->c_cflag & CSIZE) != CS7 &&
> > + (termios->c_cflag & CSIZE) != CS8) {
> > + termios->c_cflag &= ~CSIZE;
> > + termios->c_cflag |= old_csize;
> > + old_csize = CS8;
> > + }
> > +
> > + serial8250_do_set_termios(port, termios, old);
> > +
> > + if ((termios->c_cflag & CSIZE) == CS7)
> > + len = 9;
> > + else
> > + len = 10;
> > +
> > + if (termios->c_cflag & CSTOPB)
> > + len++;
>
> > + if (termios->c_cflag & PARENB)
> > + len++;
> > + if (!(termios->c_cflag & PARODD))
> > + len++;
> > +#ifdef CMSPAR
> > + if (termios->c_cflag & CMSPAR)
> > + len++;
> > +#endif
>
> I don't know if someone likes it or not (up to you), but for me looks
> better to have ternary operators here:
>
> value += (termios->c_cflag & CSTOPB) ? 1 : 0;
> value += (termios->c_cflag & PARENB) ? 1 : 0;
> value += (termios->c_cflag & PARODD) ? 0 : 1;
>
> #ifdef CMSPAR
> value += (termios->c_cflag & CMSPAR) ? 1 : 0;
> #endif
>
> > + len -= 9;
>
> This one could be part of previous evaluation:
> value = (termios->c_cflag & CSIZE) == CS7 ? 0 : 1;
Great point.
> > + len &= 3;
> > + len <<= 3;
>
> Perhaps to define magic number (e.g. LP8841_DATA_LEN_SHIFT).
OK
> > +
> > + baud = tty_termios_baud_rate(termios);
> > +
> > +#ifdef BOTHER
> > + /* We only support fixed rates */
> > + cbaud = termios->c_cflag & CBAUD;
> > +
> > + if (cbaud == BOTHER) {
> > + termios->c_cflag &= ~BOTHER;
> > +
> > + /* Don't rewrite B0 */
> > + if (baud) {
> > + tty_termios_encode_baud_rate(termios,
> > baud,
> > baud);
> > + baud = tty_termios_baud_rate(termios);
> > +
> > + /* Set sane default speed if we get 0 */
> > + if (!baud) {
> > + baud = 9600;
>
> > + tty_termios_encode_baud_rate(termi
> > os
> > ,
> > + baud, baud);
>
> I think you can call this unconditionally together with case >
> 115200.
The calls are orthogonal. This one deals with the case when BOTHER is
defined and set, and we have non-zero rate with BOTHER, but we have
zero rate after BOTHER is cleared. So we set 9600 as a sane default
speed.
> > + }
> > + }
> > + }
> > +#endif
> > +
> > + /* We only support up to 115200 */
> > + if (baud > 115200) {
> > + baud = 115200;
> > + tty_termios_encode_baud_rate(termios, baud, baud);
> > + }
This one deals with the case when the rate is over 115200. If the
previous case has been triggered, this one won't be.
> Btw, can we use uart_get_baud_rate() here?
uart_get_baud_rate() has already been called
in serial8250_do_set_termios(). uart_get_baud_rate()
calls tty_termios_encode_baud_rate(). uart_get_baud_rate() won't help
us if BOTHER is set. Once BOTHER is cleared, we don't need any special
processing of uart_get_baud_rate().
> > +static int lp8841_serial_probe(struct platform_device *pdev)
> > +{
> > + struct uart_8250_port uart = {};
>
> {0}
---
drivers/tty/serial/8250/8250_lp8841.c: In function 'lp8841_serial_probe':
drivers/tty/serial/8250/8250_lp8841.c:124:32: warning: excess elements in struct initializer
struct uart_8250_port uart = {0};
^
drivers/tty/serial/8250/8250_lp8841.c:124:32: note: (near initialization for 'uart.port.lock.<anonymous>.rlock.raw_lock')
---
Zero triggers a warning. I'll use memset().
> > + struct lp8841_serial_data *data;
> > + struct resource *mmres, *mires;
> > + int ret;
> > +
> > + mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>
> > + mires = platform_get_resource(pdev, IORESOURCE_MEM, 1);
>
> Perhaps move it down to be closer to devm_ioremap_resource() call.
OK
Thanks for lightning fast reviews. I'll resubmit v8 if there is no
objections to the points above.
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH v7] serial: support for 16550A serial ports on LP-8x4x
2016-03-01 16:25 ` Sergei Ianovich
@ 2016-03-01 16:46 ` Andy Shevchenko
[not found] ` <1456850782.13244.208.camel-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
0 siblings, 1 reply; 148+ messages in thread
From: Andy Shevchenko @ 2016-03-01 16:46 UTC (permalink / raw)
To: Sergei Ianovich, linux-kernel
Cc: Alan Cox, Arnd Bergmann, Rob Herring, Pawel Moll, Mark Rutland,
Ian Campbell, Kumar Gala, Greg Kroah-Hartman, Jiri Slaby,
Heikki Krogerus, Peter Hurley, Masahiro Yamada, Paul Burton,
Mans Rullgard, Joachim Eastwood, Scott Wood, Paul Gortmaker,
Peter Ujfalusi,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list:SERIAL DRIVERS
On Tue, 2016-03-01 at 19:25 +0300, Sergei Ianovich wrote:
> On Tue, 2016-03-01 at 13:06 +0200, Andy Shevchenko wrote:
> > On Tue, 2016-03-01 at 00:26 +0300, Sergei Ianovich wrote:
> > > + len &= 3;
Mask as well to be defined.
> > > + len <<= 3;
> >
> > Perhaps to define magic number (e.g. LP8841_DATA_LEN_SHIFT).
>
> OK
> + baud = tty_termios_baud_rate(termios);
> > > +
> > > +#ifdef BOTHER
> > > + /* We only support fixed rates */
So, but if you support only fixed rates, why do you care about BOTHER
at all?
> > >
> > I think you can call this unconditionally together with case >
> > 115200.
>
> The calls are orthogonal. This one deals with the case when BOTHER is
> defined and set, and we have non-zero rate with BOTHER, but we have
> zero rate after BOTHER is cleared. So we set 9600 as a sane default
> speed.
> +
> > > + /* We only support up to 115200 */
> > > + if (baud > 115200) {
> > > + baud = 115200;
> > > + tty_termios_encode_baud_rate(termios, baud,
> > > baud);
> > > + }
>
> This one deals with the case when the rate is over 115200. If the
> previous case has been triggered, this one won't be.
Yeah, but I meant to unconditionally call it just once here every time.
tty_termios_encode_baud_rate(termios, baud, baud);
> +static int lp8841_serial_probe(struct platform_device *pdev)
> > > +{
> > > + struct uart_8250_port uart = {};
> >
> > {0}
>
> ---
> drivers/tty/serial/8250/8250_lp8841.c: In function
> 'lp8841_serial_probe':
> drivers/tty/serial/8250/8250_lp8841.c:124:32: warning: excess
> elements in struct initializer
> struct uart_8250_port uart = {0};
> ^
> drivers/tty/serial/8250/8250_lp8841.c:124:32: note: (near
> initialization for 'uart.port.lock.<anonymous>.rlock.raw_lock')
Do you have any warning verbosity enabled? I see a lot of stuff like
this in the code
$ git grep -n 'struct .* = {0};' | wc -l
338
$ git grep -n 'struct .* = { \?0 \?};' | wc -l
550
( '… = { 0 };' included)
> ---
>
> Zero triggers a warning. I'll use memset().
Either will work.
> Thanks for lightning fast reviews. I'll resubmit v8 if there is no
> objections to the points above.
See above.
--
Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Intel Finland Oy
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH v7] serial: support for 16550A serial ports on LP-8x4x
[not found] ` <1456850782.13244.208.camel-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
@ 2016-03-01 17:14 ` Sergei Ianovich
[not found] ` <1456852472.23036.124.camel-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
0 siblings, 1 reply; 148+ messages in thread
From: Sergei Ianovich @ 2016-03-01 17:14 UTC (permalink / raw)
To: Andy Shevchenko, linux-kernel-u79uwXL29TY76Z2rM5mHXA
Cc: Alan Cox, Arnd Bergmann, Rob Herring, Pawel Moll, Mark Rutland,
Ian Campbell, Kumar Gala, Greg Kroah-Hartman, Jiri Slaby,
Heikki Krogerus, Peter Hurley, Masahiro Yamada, Paul Burton,
Mans Rullgard, Joachim Eastwood, Scott Wood, Paul Gortmaker,
Peter Ujfalusi,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list:SERIAL DRIVERS
On Tue, 2016-03-01 at 18:46 +0200, Andy Shevchenko wrote:
> On Tue, 2016-03-01 at 19:25 +0300, Sergei Ianovich wrote:
> > On Tue, 2016-03-01 at 13:06 +0200, Andy Shevchenko wrote:
> > > On Tue, 2016-03-01 at 00:26 +0300, Sergei Ianovich wrote:
>
> > > > + len &= 3;
>
> Mask as well to be defined.
Sure.
> So, but if you support only fixed rates, why do you care about BOTHER
> at all?
If BOTHER is defined, tty_termios_baud_rate()
and tty_termios_encode_baud_rate() allow non-standard baud rates. I
should clear it from c_cflag to indicate I don't support it.
> > > >
> > > I think you can call this unconditionally together with case >
> > > 115200.
> >
> > The calls are orthogonal. This one deals with the case when BOTHER
> > is
> > defined and set, and we have non-zero rate with BOTHER, but we have
> > zero rate after BOTHER is cleared. So we set 9600 as a sane default
> > speed.
> >
> > This one deals with the case when the rate is over 115200. If the
> > previous case has been triggered, this one won't be.
>
> Yeah, but I meant to unconditionally call it just once here every
> time.
I see. It saves a few lines.
> > ---
> > drivers/tty/serial/8250/8250_lp8841.c: In function
> > 'lp8841_serial_probe':
> > drivers/tty/serial/8250/8250_lp8841.c:124:32: warning: excess
> > elements in struct initializer
> > struct uart_8250_port uart = {0};
> > ^
> > drivers/tty/serial/8250/8250_lp8841.c:124:32: note: (near
> > initialization for 'uart.port.lock.<anonymous>.rlock.raw_lock')
>
> Do you have any warning verbosity enabled? I see a lot of stuff like
> this in the code
Plain `make`.
The warning seems to be the result of initializing a spinlock with
zero. Spinlocks are intentionally obfuscated, but I didn't investigate
further.
> $ git grep -n 'struct .* = {0};' | wc -l
> 338
>
> $ git grep -n 'struct .* = { \?0 \?};' | wc -l
> 550
>
> ( '… = { 0 };' included)
The first structure member is most likely not a spinlock in those
cases.
> > ---
> >
> > Zero triggers a warning. I'll use memset().
>
> Either will work.
OK
The only remaining open point is BOTHER handling.
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH v7] serial: support for 16550A serial ports on LP-8x4x
[not found] ` <1456852472.23036.124.camel-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2016-03-01 17:48 ` Andy Shevchenko
2016-03-01 18:43 ` One Thousand Gnomes
[not found] ` <1456854532.13244.215.camel-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
0 siblings, 2 replies; 148+ messages in thread
From: Andy Shevchenko @ 2016-03-01 17:48 UTC (permalink / raw)
To: Sergei Ianovich, linux-kernel-u79uwXL29TY76Z2rM5mHXA
Cc: Alan Cox, Arnd Bergmann, Rob Herring, Pawel Moll, Mark Rutland,
Ian Campbell, Kumar Gala, Greg Kroah-Hartman, Jiri Slaby,
Heikki Krogerus, Peter Hurley, Masahiro Yamada, Paul Burton,
Mans Rullgard, Joachim Eastwood, Scott Wood, Paul Gortmaker,
Peter Ujfalusi,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list:SERIAL DRIVERS
On Tue, 2016-03-01 at 20:14 +0300, Sergei Ianovich wrote:
> On Tue, 2016-03-01 at 18:46 +0200, Andy Shevchenko wrote:
> > On Tue, 2016-03-01 at 19:25 +0300, Sergei Ianovich wrote:
> > > On Tue, 2016-03-01 at 13:06 +0200, Andy Shevchenko wrote:
> > > > On Tue, 2016-03-01 at 00:26 +0300, Sergei Ianovich wrote:
> > So, but if you support only fixed rates, why do you care about
> > BOTHER
> > at all?
>
> If BOTHER is defined, tty_termios_baud_rate()
> and tty_termios_encode_baud_rate() allow non-standard baud rates. I
> should clear it from c_cflag to indicate I don't support it.
>
> > > > >
> > > > I think you can call this unconditionally together with case >
> > > > 115200.
> > >
> > > The calls are orthogonal. This one deals with the case when
> > > BOTHER
> > > is
> > > defined and set, and we have non-zero rate with BOTHER, but we
> > > have
> > > zero rate after BOTHER is cleared. So we set 9600 as a sane
> > > default
> > > speed.
Maybe you just set a baud rate nearest to the one from the table in
case of BOTHER?
In that case perhaps you have to supply +-1 to the range. That's why I
asked about uart_get_baud_rate().
Maybe this flow will work for you
if (BOTHER)
clear BOTHER
call uart_get_baud_rate()
?
> The warning seems to be the result of initializing a spinlock with
> zero. Spinlocks are intentionally obfuscated, but I didn't
> investigate
> further.
>
> > $ git grep -n 'struct .* = {0};' | wc -l
> > 338
> >
> > $ git grep -n 'struct .* = { \?0 \?};' | wc -l
> > 550
> >
> > ( '… = { 0 };' included)
>
> The first structure member is most likely not a spinlock in those
> cases.
Hmm... Interesting. On one hand the poison is reasonable, on the other
we often do a memset() or {0} on structures, i.o.w. assign 0 as initial
value until spinlock_init().
Arnd, what do you think about this (and similar) case(s)?
--
Andy Shevchenko <andriy.shevchenko-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
Intel Finland Oy
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH v7] serial: support for 16550A serial ports on LP-8x4x
2016-03-01 17:48 ` Andy Shevchenko
@ 2016-03-01 18:43 ` One Thousand Gnomes
[not found] ` <1456854532.13244.215.camel-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
1 sibling, 0 replies; 148+ messages in thread
From: One Thousand Gnomes @ 2016-03-01 18:43 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Sergei Ianovich, linux-kernel, Arnd Bergmann, Rob Herring,
Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
Greg Kroah-Hartman, Jiri Slaby, Heikki Krogerus, Peter Hurley,
Masahiro Yamada, Paul Burton, Mans Rullgard, Joachim Eastwood,
Scott Wood, Paul Gortmaker, Peter Ujfalusi,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list:SERIAL DRIVERS
> Maybe you just set a baud rate nearest to the one from the table in
> case of BOTHER?
This is broken. BOTHER can be set with a perfectly valid baud rate that
could equally be represented by B9600 say.
If you are stuck with limited ranges then
switch(baud) {
case 9600:
case 4800:
etc
and don't worry about BOTHER, it's entirely transparent to you. The core
kernel code will provide you with a baud rate number, the re-encoder will
always do the right thing.
A driver should never care about BOTHER or any of the baud bits in the
termios structure directly.
Alan
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH v7] serial: support for 16550A serial ports on LP-8x4x
[not found] ` <1456854532.13244.215.camel-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
@ 2016-03-01 19:28 ` Sergei Ianovich
[not found] ` <1456860493.23036.133.camel-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
0 siblings, 1 reply; 148+ messages in thread
From: Sergei Ianovich @ 2016-03-01 19:28 UTC (permalink / raw)
To: Andy Shevchenko, linux-kernel-u79uwXL29TY76Z2rM5mHXA
Cc: Alan Cox, Arnd Bergmann, Rob Herring, Pawel Moll, Mark Rutland,
Ian Campbell, Kumar Gala, Greg Kroah-Hartman, Jiri Slaby,
Heikki Krogerus, Peter Hurley, Masahiro Yamada, Paul Burton,
Mans Rullgard, Joachim Eastwood, Scott Wood, Paul Gortmaker,
Peter Ujfalusi,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list:SERIAL DRIVERS
On Tue, 2016-03-01 at 19:48 +0200, Andy Shevchenko wrote:
> On Tue, 2016-03-01 at 20:14 +0300, Sergei Ianovich wrote:
> > On Tue, 2016-03-01 at 18:46 +0200, Andy Shevchenko wrote:
> > > On Tue, 2016-03-01 at 19:25 +0300, Sergei Ianovich wrote:
> > > > On Tue, 2016-03-01 at 13:06 +0200, Andy Shevchenko wrote:
> > > > > On Tue, 2016-03-01 at 00:26 +0300, Sergei Ianovich wrote:
>
> > > So, but if you support only fixed rates, why do you care about
> > > BOTHER
> > > at all?
> >
> > If BOTHER is defined, tty_termios_baud_rate()
> > and tty_termios_encode_baud_rate() allow non-standard baud rates. I
> > should clear it from c_cflag to indicate I don't support it.
> >
> > > > > >
> > > > > I think you can call this unconditionally together with case
> > > > > >
> > > > > 115200.
> > > >
> > > > The calls are orthogonal. This one deals with the case when
> > > > BOTHER
> > > > is
> > > > defined and set, and we have non-zero rate with BOTHER, but we
> > > > have
> > > > zero rate after BOTHER is cleared. So we set 9600 as a sane
> > > > default
> > > > speed.
>
> Maybe you just set a baud rate nearest to the one from the table in
> case of BOTHER?
>
> In that case perhaps you have to supply +-1 to the range. That's why
> I
> asked about uart_get_baud_rate().
>
> Maybe this flow will work for you
>
> if (BOTHER)
> clear BOTHER
> call uart_get_baud_rate()
>
> ?
It works well for standard rates, let it be so. If there ever is a
problem, we can fix it.
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH v7] serial: support for 16550A serial ports on LP-8x4x
[not found] ` <1456860493.23036.133.camel-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2016-03-01 19:53 ` One Thousand Gnomes
0 siblings, 0 replies; 148+ messages in thread
From: One Thousand Gnomes @ 2016-03-01 19:53 UTC (permalink / raw)
To: Sergei Ianovich
Cc: Andy Shevchenko, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
Arnd Bergmann, Rob Herring, Pawel Moll, Mark Rutland,
Ian Campbell, Kumar Gala, Greg Kroah-Hartman, Jiri Slaby,
Heikki Krogerus, Peter Hurley, Masahiro Yamada, Paul Burton,
Mans Rullgard, Joachim Eastwood, Scott Wood, Paul Gortmaker,
Peter Ujfalusi,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS
> > Maybe this flow will work for you
> >
> > if (BOTHER)
> > clear BOTHER
> > call uart_get_baud_rate()
> >
> > ?
>
> It works well for standard rates, let it be so. If there ever is a
> problem, we can fix it.
I'm NAKking the v7 PATCH because we spent ages getting all the drivers to
use tty_termios_get_baud_rate() cleanly.
Get rid of everything in the ifdef BOTHER
Remove the if baud > 115200 stuff
For the default: entry in the case add
tty_termios_encode_baud_rate(termios, 2400, 2400);
and all will be good. Anything not a standard rate will get 2400 baud and
reported back to the user properly as that rate.
You could do matches for "within 10%" but really I don't think it matters
and other drivers don't bother either when they have such fixed clocks.
Alan
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 148+ messages in thread
* [PATCH v8] serial: support for 16550A serial ports on LP-8x4x
2016-02-29 21:26 ` [PATCH v7] " Sergei Ianovich
[not found] ` <1456781209-11390-1-git-send-email-ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2016-03-01 19:54 ` Sergei Ianovich
[not found] ` <1456862078-11795-1-git-send-email-ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
1 sibling, 1 reply; 148+ messages in thread
From: Sergei Ianovich @ 2016-03-01 19:54 UTC (permalink / raw)
To: linux-kernel
Cc: Sergei Ianovich, Alan Cox, Andy Shevchenko, Arnd Bergmann,
Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
Greg Kroah-Hartman, Jiri Slaby, Heikki Krogerus, Peter Hurley,
Masahiro Yamada, Paul Gortmaker, Paul Burton, Joachim Eastwood,
Mans Rullgard, Scott Wood, Matthias Brugger, Peter Ujfalusi,
open l
The patch adds support for 3 additional LP-8x4x built-in serial
ports.
The device can also host up to 8 extension cards with 4 serial ports
on each card for a total of 35 ports. However, I don't have
the hardware to test extension cards, so they are not supported, yet.
Signed-off-by: Sergei Ianovich <ynvich@gmail.com>
Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
---
CC: Alan Cox <gnomes@lxorguk.ukuu.org.uk>
CC: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
CC: Arnd Bergmann <arnd@arndb.de>
v7..v8
* call serial8250_do_set_termios() after speed check, not before.
This way clock divisor is properly inited for the new baud rate,
if any
fix review comments by Andy Shevchenko
* change board variable name and type
* use ternary operators
* use #defines instead of magic numbers
* simplify speed check and use uart_get_baud_rate()
* zero-init uart structure
* re-organized probing calls
v6..v7
fix review comments by Andy Shevchenko
not applying Acked-by as the 1st change is big
* handle unsupported tty modes correctly
* remove extra check of platform_get_resource() result
* propagate error code from devm_ioremap_resource()
* drop uart.port.iobase for UPIO_MEM device
v5..v6
fix review comments by Arnd Bergmann
* remove wildcards from compatible
* update doc file
* drop interrupt parent from doc file
* replace uart w/ serial in device names in doc file
fix review comments by Andy Shevchenko
* exchange labels in switch block
* replace iowrite8() with writeb()
* compact comment to one line
v4..v5
* constify struct of_device_id
* drop .owner from struct platform_driver
* rewrite set_termios() baud rate hadnling as suggested by Alan Cox
v3..v4
* move DTS bindings to a different patch (8/21) as suggested by
Heikki Krogerus
v2..v3
* no changes (except number 10/16 -> 12/21)
v0..v2
* register platform driver instead of platform device
* use device tree
* use devm helpers where possible
.../bindings/serial/icpdas-lp8841-uart.txt | 41 +++++
drivers/tty/serial/8250/8250_lp8841.c | 173 +++++++++++++++++++++
drivers/tty/serial/8250/Kconfig | 14 ++
drivers/tty/serial/8250/Makefile | 2 +
4 files changed, 230 insertions(+)
create mode 100644 Documentation/devicetree/bindings/serial/icpdas-lp8841-uart.txt
create mode 100644 drivers/tty/serial/8250/8250_lp8841.c
diff --git a/Documentation/devicetree/bindings/serial/icpdas-lp8841-uart.txt b/Documentation/devicetree/bindings/serial/icpdas-lp8841-uart.txt
new file mode 100644
index 0000000..d6acd22
--- /dev/null
+++ b/Documentation/devicetree/bindings/serial/icpdas-lp8841-uart.txt
@@ -0,0 +1,41 @@
+* UART ports on ICP DAS LP-8841
+
+LP-8441, LP-8141 and LP-8041 are fully compatible.
+
+ICP DAS LP-8841 contains three additional serial ports interfaced via
+Analog Devices ADM213EA chips in addition to 3 serial ports on PXA CPU.
+
+The chips themselves are standard, they would work with 8250_core if
+properly connected. However, they are not connected normally. Al least
+some of their config pins are wired to a different address region. So
+the driver is board-specific.
+
+Required properties:
+- compatible : should be "icpdas,uart-lp8841"
+
+- reg : should provide 16 byte man IO memory region and 1 byte region for
+ termios
+
+- interrupts : should provide interrupt
+
+Optional property:
+- interrupt-parent : should provide a link to interrupt controller either
+ explicitly or implicitly from a parent node
+
+Examples (from pxa27x-lp8x4x.dts):
+
+ serial@9050 {
+ compatible = "icpdas,uart-lp8841";
+ reg = <0x9050 0x10
+ 0x9030 0x02>;
+ interrupts = <13>;
+ status = "okay";
+ };
+
+ serial@9060 {
+ compatible = "icpdas,uart-lp8841";
+ reg = <0x9060 0x10
+ 0x9032 0x02>;
+ interrupts = <14>;
+ status = "okay";
+ };
diff --git a/drivers/tty/serial/8250/8250_lp8841.c b/drivers/tty/serial/8250/8250_lp8841.c
new file mode 100644
index 0000000..d80e218
--- /dev/null
+++ b/drivers/tty/serial/8250/8250_lp8841.c
@@ -0,0 +1,173 @@
+/* linux/drivers/tty/serial/8250/8250_lp8841.c
+ *
+ * Support for 16550A serial ports on ICP DAS LP-8841
+ *
+ * Copyright (C) 2013 Sergei Ianovich <ynvich@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+#include <linux/serial_8250.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+
+struct lp8841_serial_data {
+ int line;
+ void __iomem *ios_mem;
+};
+
+#define LP8841_DATA_LEN_MASK 0x3
+#define LP8841_DATA_LEN_SHIFT_OFFSET 3
+
+static void lp8841_serial_set_termios(struct uart_port *port,
+ struct ktermios *termios, struct ktermios *old)
+{
+#ifdef BOTHER
+ unsigned int cbaud;
+#endif
+ unsigned int baud;
+ u8 value;
+ unsigned int old_csize = old ? old->c_cflag & CSIZE : CS8;
+ struct lp8841_serial_data *data = port->private_data;
+
+ /* We only support CS7 and CS8 */
+ while ((termios->c_cflag & CSIZE) != CS7 &&
+ (termios->c_cflag & CSIZE) != CS8) {
+ termios->c_cflag &= ~CSIZE;
+ termios->c_cflag |= old_csize;
+ old_csize = CS8;
+ }
+
+ value = (termios->c_cflag & CSIZE) == CS7 ? 0 : 1;
+ value += (termios->c_cflag & CSTOPB) ? 1 : 0;
+ value += (termios->c_cflag & PARENB) ? 1 : 0;
+ value += (termios->c_cflag & PARODD) ? 0 : 1;
+#ifdef CMSPAR
+ value += (termios->c_cflag & CMSPAR) ? 1 : 0;
+#endif
+
+ value &= LP8841_DATA_LEN_MASK;
+ value <<= LP8841_DATA_LEN_SHIFT_OFFSET;
+
+ baud = tty_termios_baud_rate(termios);
+
+#ifdef BOTHER
+ /* We only support fixed rates */
+ cbaud = termios->c_cflag & CBAUD;
+
+ if (cbaud == BOTHER)
+ termios->c_cflag &= ~BOTHER;
+#endif
+
+ /* We only support up to 115200 */
+ if (baud > 115200)
+ baud = 115200;
+
+ baud = uart_get_baud_rate(port, termios, old, baud, baud);
+
+ serial8250_do_set_termios(port, termios, old);
+
+ switch (baud) {
+ case 115200:
+ value |= 7;
+ break;
+ case 57600:
+ value |= 6;
+ break;
+ case 38400:
+ value |= 5;
+ break;
+ case 19200:
+ value |= 4;
+ break;
+ case 9600:
+ value |= 3;
+ break;
+ case 4800:
+ value |= 2;
+ break;
+ case 2400:
+ default:
+ value |= 1;
+ break;
+ };
+ writeb(value, data->ios_mem);
+}
+
+static const struct of_device_id lp8841_serial_dt_ids[] = {
+ { .compatible = "icpdas,lp8841-uart", },
+ {}
+};
+MODULE_DEVICE_TABLE(of, lp8841_serial_dt_ids);
+
+static int lp8841_serial_probe(struct platform_device *pdev)
+{
+ struct uart_8250_port uart = {};
+ struct lp8841_serial_data *data;
+ struct resource *mmres, *mires;
+ int ret;
+
+ memset(&uart, 0, sizeof(uart));
+
+ mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!mmres)
+ return -ENODEV;
+
+ data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ mires = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ data->ios_mem = devm_ioremap_resource(&pdev->dev, mires);
+ if (IS_ERR(data->ios_mem))
+ return PTR_ERR(data->ios_mem);
+
+ uart.port.iotype = UPIO_MEM;
+ uart.port.mapbase = mmres->start;
+ uart.port.regshift = 1;
+ uart.port.irq = platform_get_irq(pdev, 0);
+ uart.port.flags = UPF_IOREMAP;
+ uart.port.dev = &pdev->dev;
+ uart.port.uartclk = 14745600;
+ uart.port.set_termios = lp8841_serial_set_termios;
+ uart.port.private_data = data;
+
+ ret = serial8250_register_8250_port(&uart);
+ if (ret < 0)
+ return ret;
+
+ data->line = ret;
+
+ platform_set_drvdata(pdev, data);
+
+ return 0;
+}
+
+static int lp8841_serial_remove(struct platform_device *pdev)
+{
+ struct lp8841_serial_data *data = platform_get_drvdata(pdev);
+
+ serial8250_unregister_port(data->line);
+
+ return 0;
+}
+
+static struct platform_driver lp8841_serial_driver = {
+ .probe = lp8841_serial_probe,
+ .remove = lp8841_serial_remove,
+ .driver = {
+ .name = "uart-lp8841",
+ .of_match_table = lp8841_serial_dt_ids,
+ },
+};
+
+module_platform_driver(lp8841_serial_driver);
+
+MODULE_AUTHOR("Sergei Ianovich");
+MODULE_DESCRIPTION("8250 serial port module for LP-8841");
+MODULE_LICENSE("GPL");
diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig
index 3b5cf9c..68640c1 100644
--- a/drivers/tty/serial/8250/Kconfig
+++ b/drivers/tty/serial/8250/Kconfig
@@ -394,3 +394,17 @@ config SERIAL_8250_PXA
help
If you have a machine based on an Intel XScale PXA2xx CPU you
can enable its onboard serial ports by enabling this option.
+
+ If you choose M here, the module name will be 8250_pxa.
+
+config SERIAL_8250_LP8841
+ tristate "Support 16550A ports on ICP DAS LP-8841"
+ depends on SERIAL_8250 && MACH_PXA27X_DT
+ select LP8841_IRQ
+ help
+ In addition to serial ports on PXA270 SoC, LP-8841 has 1 dual
+ RS232/RS485 port, 1 RS485 port and 1 RS232 port.
+
+ Say N here, unless you plan to run this kernel on a LP-8841 system.
+
+ If you choose M here, the module name will be 8250_lp8841.
diff --git a/drivers/tty/serial/8250/Makefile b/drivers/tty/serial/8250/Makefile
index d1e2f2d..10b4bf0 100644
--- a/drivers/tty/serial/8250/Makefile
+++ b/drivers/tty/serial/8250/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_SERIAL_8250_ACCENT) += 8250_accent.o
obj-$(CONFIG_SERIAL_8250_BOCA) += 8250_boca.o
obj-$(CONFIG_SERIAL_8250_EXAR_ST16C554) += 8250_exar_st16c554.o
obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o
+obj-$(CONFIG_SERIAL_8250_LP8X4X) += 8250_lp8x4x.o
obj-$(CONFIG_SERIAL_8250_FSL) += 8250_fsl.o
obj-$(CONFIG_SERIAL_8250_DW) += 8250_dw.o
obj-$(CONFIG_SERIAL_8250_EM) += 8250_em.o
@@ -30,5 +31,6 @@ obj-$(CONFIG_SERIAL_8250_INGENIC) += 8250_ingenic.o
obj-$(CONFIG_SERIAL_8250_MID) += 8250_mid.o
obj-$(CONFIG_SERIAL_OF_PLATFORM) += 8250_of.o
obj-$(CONFIG_SERIAL_8250_PXA) += 8250_pxa.o
+obj-$(CONFIG_SERIAL_8250_LP8841) += 8250_lp8841.o
CFLAGS_8250_ingenic.o += -I$(srctree)/scripts/dtc/libfdt
--
2.7.0
^ permalink raw reply related [flat|nested] 148+ messages in thread
* [PATCH v9] serial: support for 16550A serial ports on LP-8x4x
[not found] ` <1456862078-11795-1-git-send-email-ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2016-03-01 20:08 ` Sergei Ianovich
[not found] ` <1456862903-12392-1-git-send-email-ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2016-03-01 21:25 ` [PATCH v10] " Sergei Ianovich
0 siblings, 2 replies; 148+ messages in thread
From: Sergei Ianovich @ 2016-03-01 20:08 UTC (permalink / raw)
To: linux-kernel-u79uwXL29TY76Z2rM5mHXA
Cc: Sergei Ianovich, Alan Cox, Andy Shevchenko, Arnd Bergmann,
Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
Greg Kroah-Hartman, Jiri Slaby, Heikki Krogerus, Masahiro Yamada,
Joachim Eastwood, Paul Burton, Mans Rullgard, Scott Wood,
Paul Gortmaker, Peter Ujfalusi, Peter Hurley,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE
The patch adds support for 3 additional LP-8x4x built-in serial
ports.
The device can also host up to 8 extension cards with 4 serial ports
on each card for a total of 35 ports. However, I don't have
the hardware to test extension cards, so they are not supported, yet.
Signed-off-by: Sergei Ianovich <ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Reviewed-by: Heikki Krogerus <heikki.krogerus-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
---
CC: Alan Cox <gnomes-qBU/x9rampVanCEyBjwyrvXRex20P6io@public.gmane.org>
CC: Andy Shevchenko <andriy.shevchenko-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
CC: Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org>
v8..v9
fix review comments by Alan Cox
* further simplify speed check
v7..v8
* call serial8250_do_set_termios() after speed check, not before.
This way clock divisor is properly inited for the new baud rate,
if any
fix review comments by Andy Shevchenko
* change board variable name and type
* use ternary operators
* use #defines instead of magic numbers
* simplify speed check and use uart_get_baud_rate()
* zero-init uart structure
* re-organized probing calls
v6..v7
fix review comments by Andy Shevchenko
not applying Acked-by as the 1st change is big
* handle unsupported tty modes correctly
* remove extra check of platform_get_resource() result
* propagate error code from devm_ioremap_resource()
* drop uart.port.iobase for UPIO_MEM device
v5..v6
fix review comments by Arnd Bergmann
* remove wildcards from compatible
* update doc file
* drop interrupt parent from doc file
* replace uart w/ serial in device names in doc file
fix review comments by Andy Shevchenko
* exchange labels in switch block
* replace iowrite8() with writeb()
* compact comment to one line
v4..v5
* constify struct of_device_id
* drop .owner from struct platform_driver
* rewrite set_termios() baud rate hadnling as suggested by Alan Cox
v3..v4
* move DTS bindings to a different patch (8/21) as suggested by
Heikki Krogerus
v2..v3
* no changes (except number 10/16 -> 12/21)
v0..v2
* register platform driver instead of platform device
* use device tree
* use devm helpers where possible
.../bindings/serial/icpdas-lp8841-uart.txt | 41 ++++++
drivers/tty/serial/8250/8250_lp8841.c | 159 +++++++++++++++++++++
drivers/tty/serial/8250/Kconfig | 14 ++
drivers/tty/serial/8250/Makefile | 2 +
4 files changed, 216 insertions(+)
create mode 100644 Documentation/devicetree/bindings/serial/icpdas-lp8841-uart.txt
create mode 100644 drivers/tty/serial/8250/8250_lp8841.c
diff --git a/Documentation/devicetree/bindings/serial/icpdas-lp8841-uart.txt b/Documentation/devicetree/bindings/serial/icpdas-lp8841-uart.txt
new file mode 100644
index 0000000..d6acd22
--- /dev/null
+++ b/Documentation/devicetree/bindings/serial/icpdas-lp8841-uart.txt
@@ -0,0 +1,41 @@
+* UART ports on ICP DAS LP-8841
+
+LP-8441, LP-8141 and LP-8041 are fully compatible.
+
+ICP DAS LP-8841 contains three additional serial ports interfaced via
+Analog Devices ADM213EA chips in addition to 3 serial ports on PXA CPU.
+
+The chips themselves are standard, they would work with 8250_core if
+properly connected. However, they are not connected normally. Al least
+some of their config pins are wired to a different address region. So
+the driver is board-specific.
+
+Required properties:
+- compatible : should be "icpdas,uart-lp8841"
+
+- reg : should provide 16 byte man IO memory region and 1 byte region for
+ termios
+
+- interrupts : should provide interrupt
+
+Optional property:
+- interrupt-parent : should provide a link to interrupt controller either
+ explicitly or implicitly from a parent node
+
+Examples (from pxa27x-lp8x4x.dts):
+
+ serial@9050 {
+ compatible = "icpdas,uart-lp8841";
+ reg = <0x9050 0x10
+ 0x9030 0x02>;
+ interrupts = <13>;
+ status = "okay";
+ };
+
+ serial@9060 {
+ compatible = "icpdas,uart-lp8841";
+ reg = <0x9060 0x10
+ 0x9032 0x02>;
+ interrupts = <14>;
+ status = "okay";
+ };
diff --git a/drivers/tty/serial/8250/8250_lp8841.c b/drivers/tty/serial/8250/8250_lp8841.c
new file mode 100644
index 0000000..548f382
--- /dev/null
+++ b/drivers/tty/serial/8250/8250_lp8841.c
@@ -0,0 +1,159 @@
+/* linux/drivers/tty/serial/8250/8250_lp8841.c
+ *
+ * Support for 16550A serial ports on ICP DAS LP-8841
+ *
+ * Copyright (C) 2013 Sergei Ianovich <ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+#include <linux/serial_8250.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+
+struct lp8841_serial_data {
+ int line;
+ void __iomem *ios_mem;
+};
+
+#define LP8841_DATA_LEN_MASK 0x3
+#define LP8841_DATA_LEN_SHIFT_OFFSET 3
+
+static void lp8841_serial_set_termios(struct uart_port *port,
+ struct ktermios *termios, struct ktermios *old)
+{
+ unsigned int baud;
+ u8 value;
+ unsigned int old_csize = old ? old->c_cflag & CSIZE : CS8;
+ struct lp8841_serial_data *data = port->private_data;
+
+ /* We only support CS7 and CS8 */
+ while ((termios->c_cflag & CSIZE) != CS7 &&
+ (termios->c_cflag & CSIZE) != CS8) {
+ termios->c_cflag &= ~CSIZE;
+ termios->c_cflag |= old_csize;
+ old_csize = CS8;
+ }
+
+ value = (termios->c_cflag & CSIZE) == CS7 ? 0 : 1;
+ value += (termios->c_cflag & CSTOPB) ? 1 : 0;
+ value += (termios->c_cflag & PARENB) ? 1 : 0;
+ value += (termios->c_cflag & PARODD) ? 0 : 1;
+#ifdef CMSPAR
+ value += (termios->c_cflag & CMSPAR) ? 1 : 0;
+#endif
+
+ value &= LP8841_DATA_LEN_MASK;
+ value <<= LP8841_DATA_LEN_SHIFT_OFFSET;
+
+ baud = tty_termios_baud_rate(termios);
+
+ switch (baud) {
+ case 115200:
+ value |= 7;
+ break;
+ case 57600:
+ value |= 6;
+ break;
+ case 38400:
+ value |= 5;
+ break;
+ case 19200:
+ value |= 4;
+ break;
+ case 9600:
+ value |= 3;
+ break;
+ case 4800:
+ value |= 2;
+ break;
+ case 2400:
+ value |= 1;
+ break;
+ default:
+ value |= 1;
+ tty_termios_encode_baud_rate(termios, 2400, 2400);
+ break;
+ };
+ writeb(value, data->ios_mem);
+
+ serial8250_do_set_termios(port, termios, old);
+}
+
+static const struct of_device_id lp8841_serial_dt_ids[] = {
+ { .compatible = "icpdas,lp8841-uart", },
+ {}
+};
+MODULE_DEVICE_TABLE(of, lp8841_serial_dt_ids);
+
+static int lp8841_serial_probe(struct platform_device *pdev)
+{
+ struct uart_8250_port uart = {};
+ struct lp8841_serial_data *data;
+ struct resource *mmres, *mires;
+ int ret;
+
+ memset(&uart, 0, sizeof(uart));
+
+ mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!mmres)
+ return -ENODEV;
+
+ data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ mires = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ data->ios_mem = devm_ioremap_resource(&pdev->dev, mires);
+ if (IS_ERR(data->ios_mem))
+ return PTR_ERR(data->ios_mem);
+
+ uart.port.iotype = UPIO_MEM;
+ uart.port.mapbase = mmres->start;
+ uart.port.regshift = 1;
+ uart.port.irq = platform_get_irq(pdev, 0);
+ uart.port.flags = UPF_IOREMAP;
+ uart.port.dev = &pdev->dev;
+ uart.port.uartclk = 14745600;
+ uart.port.set_termios = lp8841_serial_set_termios;
+ uart.port.private_data = data;
+
+ ret = serial8250_register_8250_port(&uart);
+ if (ret < 0)
+ return ret;
+
+ data->line = ret;
+
+ platform_set_drvdata(pdev, data);
+
+ return 0;
+}
+
+static int lp8841_serial_remove(struct platform_device *pdev)
+{
+ struct lp8841_serial_data *data = platform_get_drvdata(pdev);
+
+ serial8250_unregister_port(data->line);
+
+ return 0;
+}
+
+static struct platform_driver lp8841_serial_driver = {
+ .probe = lp8841_serial_probe,
+ .remove = lp8841_serial_remove,
+ .driver = {
+ .name = "uart-lp8841",
+ .of_match_table = lp8841_serial_dt_ids,
+ },
+};
+
+module_platform_driver(lp8841_serial_driver);
+
+MODULE_AUTHOR("Sergei Ianovich");
+MODULE_DESCRIPTION("8250 serial port module for LP-8841");
+MODULE_LICENSE("GPL");
diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig
index 3b5cf9c..68640c1 100644
--- a/drivers/tty/serial/8250/Kconfig
+++ b/drivers/tty/serial/8250/Kconfig
@@ -394,3 +394,17 @@ config SERIAL_8250_PXA
help
If you have a machine based on an Intel XScale PXA2xx CPU you
can enable its onboard serial ports by enabling this option.
+
+ If you choose M here, the module name will be 8250_pxa.
+
+config SERIAL_8250_LP8841
+ tristate "Support 16550A ports on ICP DAS LP-8841"
+ depends on SERIAL_8250 && MACH_PXA27X_DT
+ select LP8841_IRQ
+ help
+ In addition to serial ports on PXA270 SoC, LP-8841 has 1 dual
+ RS232/RS485 port, 1 RS485 port and 1 RS232 port.
+
+ Say N here, unless you plan to run this kernel on a LP-8841 system.
+
+ If you choose M here, the module name will be 8250_lp8841.
diff --git a/drivers/tty/serial/8250/Makefile b/drivers/tty/serial/8250/Makefile
index d1e2f2d..10b4bf0 100644
--- a/drivers/tty/serial/8250/Makefile
+++ b/drivers/tty/serial/8250/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_SERIAL_8250_ACCENT) += 8250_accent.o
obj-$(CONFIG_SERIAL_8250_BOCA) += 8250_boca.o
obj-$(CONFIG_SERIAL_8250_EXAR_ST16C554) += 8250_exar_st16c554.o
obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o
+obj-$(CONFIG_SERIAL_8250_LP8X4X) += 8250_lp8x4x.o
obj-$(CONFIG_SERIAL_8250_FSL) += 8250_fsl.o
obj-$(CONFIG_SERIAL_8250_DW) += 8250_dw.o
obj-$(CONFIG_SERIAL_8250_EM) += 8250_em.o
@@ -30,5 +31,6 @@ obj-$(CONFIG_SERIAL_8250_INGENIC) += 8250_ingenic.o
obj-$(CONFIG_SERIAL_8250_MID) += 8250_mid.o
obj-$(CONFIG_SERIAL_OF_PLATFORM) += 8250_of.o
obj-$(CONFIG_SERIAL_8250_PXA) += 8250_pxa.o
+obj-$(CONFIG_SERIAL_8250_LP8841) += 8250_lp8841.o
CFLAGS_8250_ingenic.o += -I$(srctree)/scripts/dtc/libfdt
--
2.7.0
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 148+ messages in thread
* Re: [PATCH v9] serial: support for 16550A serial ports on LP-8x4x
[not found] ` <1456862903-12392-1-git-send-email-ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2016-03-01 20:23 ` Andy Shevchenko
0 siblings, 0 replies; 148+ messages in thread
From: Andy Shevchenko @ 2016-03-01 20:23 UTC (permalink / raw)
To: Sergei Ianovich
Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Alan Cox,
Andy Shevchenko, Arnd Bergmann, Rob Herring, Pawel Moll,
Mark Rutland, Ian Campbell, Kumar Gala, Greg Kroah-Hartman,
Jiri Slaby, Heikki Krogerus, Masahiro Yamada, Joachim Eastwood,
Paul Burton, Mans Rullgard, Scott Wood, Paul Gortmaker,
Peter Ujfalusi, Peter Hurley, OPEN
On Tue, Mar 1, 2016 at 10:08 PM, Sergei Ianovich <ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> The patch adds support for 3 additional LP-8x4x built-in serial
> ports.
>
> The device can also host up to 8 extension cards with 4 serial ports
> on each card for a total of 35 ports. However, I don't have
> the hardware to test extension cards, so they are not supported, yet.
>
> Signed-off-by: Sergei Ianovich <ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> Reviewed-by: Heikki Krogerus <heikki.krogerus-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
Sorry, but still few nitpicks and then
Reviewed-by: Andy Shevchenko <andriy.shevchenko-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
> +#define LP8841_DATA_LEN_MASK 0x3
> +#define LP8841_DATA_LEN_SHIFT_OFFSET 3
No need to have _OFFSET suffix.
> +
> +static void lp8841_serial_set_termios(struct uart_port *port,
> + struct ktermios *termios, struct ktermios *old)
> +{
> + unsigned int baud;
> + u8 value;
> + unsigned int old_csize = old ? old->c_cflag & CSIZE : CS8;
> + struct lp8841_serial_data *data = port->private_data;
I would rearrange to have assignments first in the definition block.
Code duplication (no idea if it worth to fix):
+ case 2400:
+ value |= 1;
+ break;
+ default:
+ value |= 1;
+ tty_termios_encode_baud_rate(termios, 2400, 2400);
+ break;
> +static int lp8841_serial_probe(struct platform_device *pdev)
> +{
> + struct uart_8250_port uart = {};
No need {} since memset().
> + struct lp8841_serial_data *data;
> + struct resource *mmres, *mires;
> + int ret;
> +
> + memset(&uart, 0, sizeof(uart));
Move this closer to the first assignment of a field.
> +
> + mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> + if (!mmres)
> + return -ENODEV;
> +
> + data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
> + if (!data)
> + return -ENOMEM;
> +
> + mires = platform_get_resource(pdev, IORESOURCE_MEM, 1);
> + data->ios_mem = devm_ioremap_resource(&pdev->dev, mires);
> + if (IS_ERR(data->ios_mem))
> + return PTR_ERR(data->ios_mem);
> +
+ memset(&uart, 0, sizeof(uart));
> + uart.port.iotype = UPIO_MEM;
> + uart.port.mapbase = mmres->start;
> + uart.port.regshift = 1;
> + uart.port.irq = platform_get_irq(pdev, 0);
> + uart.port.flags = UPF_IOREMAP;
> + uart.port.dev = &pdev->dev;
> + uart.port.uartclk = 14745600;
> + uart.port.set_termios = lp8841_serial_set_termios;
> + uart.port.private_data = data;
--
With Best Regards,
Andy Shevchenko
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 148+ messages in thread
* [PATCH v10] serial: support for 16550A serial ports on LP-8x4x
2016-03-01 20:08 ` [PATCH v9] " Sergei Ianovich
[not found] ` <1456862903-12392-1-git-send-email-ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2016-03-01 21:25 ` Sergei Ianovich
2016-03-05 4:26 ` Rob Herring
1 sibling, 1 reply; 148+ messages in thread
From: Sergei Ianovich @ 2016-03-01 21:25 UTC (permalink / raw)
To: linux-kernel
Cc: Sergei Ianovich, Alan Cox, Arnd Bergmann, Rob Herring, Pawel Moll,
Mark Rutland, Ian Campbell, Kumar Gala, Greg Kroah-Hartman,
Jiri Slaby, Heikki Krogerus, Andy Shevchenko, Masahiro Yamada,
Peter Hurley, Paul Burton, Mans Rullgard, Scott Wood,
Paul Gortmaker, Joachim Eastwood, Peter Ujfalusi,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE
The patch adds support for 3 additional LP-8x4x built-in serial
ports.
The device can also host up to 8 extension cards with 4 serial ports
on each card for a total of 35 ports. However, I don't have
the hardware to test extension cards, so they are not supported, yet.
Signed-off-by: Sergei Ianovich <ynvich@gmail.com>
Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
CC: Alan Cox <gnomes@lxorguk.ukuu.org.uk>
CC: Arnd Bergmann <arnd@arndb.de>
v9..v10
fix review comments by Andy Shevchenko
* fix code styling
v8..v9
fix review comments by Alan Cox
* further simplify speed check
v7..v8
* call serial8250_do_set_termios() after speed check, not before.
This way clock divisor is properly inited for the new baud rate,
if any
fix review comments by Andy Shevchenko
* change board variable name and type
* use ternary operators
* use #defines instead of magic numbers
* simplify speed check and use uart_get_baud_rate()
* zero-init uart structure
* re-organized probing calls
v6..v7
fix review comments by Andy Shevchenko
not applying Acked-by as the 1st change is big
* handle unsupported tty modes correctly
* remove extra check of platform_get_resource() result
* propagate error code from devm_ioremap_resource()
* drop uart.port.iobase for UPIO_MEM device
v5..v6
fix review comments by Arnd Bergmann
* remove wildcards from compatible
* update doc file
* drop interrupt parent from doc file
* replace uart w/ serial in device names in doc file
fix review comments by Andy Shevchenko
* exchange labels in switch block
* replace iowrite8() with writeb()
* compact comment to one line
v4..v5
* constify struct of_device_id
* drop .owner from struct platform_driver
* rewrite set_termios() baud rate hadnling as suggested by Alan Cox
v3..v4
* move DTS bindings to a different patch (8/21) as suggested by
Heikki Krogerus
v2..v3
* no changes (except number 10/16 -> 12/21)
v0..v2
* register platform driver instead of platform device
* use device tree
* use devm helpers where possible
.../bindings/serial/icpdas-lp8841-uart.txt | 41 ++++++
drivers/tty/serial/8250/8250_lp8841.c | 156 +++++++++++++++++++++
drivers/tty/serial/8250/Kconfig | 14 ++
drivers/tty/serial/8250/Makefile | 2 +
4 files changed, 213 insertions(+)
create mode 100644 Documentation/devicetree/bindings/serial/icpdas-lp8841-uart.txt
create mode 100644 drivers/tty/serial/8250/8250_lp8841.c
diff --git a/Documentation/devicetree/bindings/serial/icpdas-lp8841-uart.txt b/Documentation/devicetree/bindings/serial/icpdas-lp8841-uart.txt
new file mode 100644
index 0000000..d6acd22
--- /dev/null
+++ b/Documentation/devicetree/bindings/serial/icpdas-lp8841-uart.txt
@@ -0,0 +1,41 @@
+* UART ports on ICP DAS LP-8841
+
+LP-8441, LP-8141 and LP-8041 are fully compatible.
+
+ICP DAS LP-8841 contains three additional serial ports interfaced via
+Analog Devices ADM213EA chips in addition to 3 serial ports on PXA CPU.
+
+The chips themselves are standard, they would work with 8250_core if
+properly connected. However, they are not connected normally. Al least
+some of their config pins are wired to a different address region. So
+the driver is board-specific.
+
+Required properties:
+- compatible : should be "icpdas,uart-lp8841"
+
+- reg : should provide 16 byte man IO memory region and 1 byte region for
+ termios
+
+- interrupts : should provide interrupt
+
+Optional property:
+- interrupt-parent : should provide a link to interrupt controller either
+ explicitly or implicitly from a parent node
+
+Examples (from pxa27x-lp8x4x.dts):
+
+ serial@9050 {
+ compatible = "icpdas,uart-lp8841";
+ reg = <0x9050 0x10
+ 0x9030 0x02>;
+ interrupts = <13>;
+ status = "okay";
+ };
+
+ serial@9060 {
+ compatible = "icpdas,uart-lp8841";
+ reg = <0x9060 0x10
+ 0x9032 0x02>;
+ interrupts = <14>;
+ status = "okay";
+ };
diff --git a/drivers/tty/serial/8250/8250_lp8841.c b/drivers/tty/serial/8250/8250_lp8841.c
new file mode 100644
index 0000000..d3a72da
--- /dev/null
+++ b/drivers/tty/serial/8250/8250_lp8841.c
@@ -0,0 +1,156 @@
+/* linux/drivers/tty/serial/8250/8250_lp8841.c
+ *
+ * Support for 16550A serial ports on ICP DAS LP-8841
+ *
+ * Copyright (C) 2013 Sergei Ianovich <ynvich@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+#include <linux/serial_8250.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+
+struct lp8841_serial_data {
+ int line;
+ void __iomem *ios_mem;
+};
+
+#define LP8841_DATA_LEN_MASK 0x3
+#define LP8841_DATA_LEN_SHIFT 3
+
+static void lp8841_serial_set_termios(struct uart_port *port,
+ struct ktermios *termios, struct ktermios *old)
+{
+ struct lp8841_serial_data *data = port->private_data;
+ unsigned int old_csize = old ? old->c_cflag & CSIZE : CS8;
+ unsigned int baud;
+ u8 value;
+
+ /* We only support CS7 and CS8 */
+ while ((termios->c_cflag & CSIZE) != CS7 &&
+ (termios->c_cflag & CSIZE) != CS8) {
+ termios->c_cflag &= ~CSIZE;
+ termios->c_cflag |= old_csize;
+ old_csize = CS8;
+ }
+
+ value = (termios->c_cflag & CSIZE) == CS7 ? 0 : 1;
+ value += (termios->c_cflag & CSTOPB) ? 1 : 0;
+ value += (termios->c_cflag & PARENB) ? 1 : 0;
+ value += (termios->c_cflag & PARODD) ? 0 : 1;
+#ifdef CMSPAR
+ value += (termios->c_cflag & CMSPAR) ? 1 : 0;
+#endif
+
+ value &= LP8841_DATA_LEN_MASK;
+ value <<= LP8841_DATA_LEN_SHIFT;
+
+ baud = tty_termios_baud_rate(termios);
+
+ switch (baud) {
+ case 115200:
+ value |= 7;
+ break;
+ case 57600:
+ value |= 6;
+ break;
+ case 38400:
+ value |= 5;
+ break;
+ case 19200:
+ value |= 4;
+ break;
+ case 9600:
+ value |= 3;
+ break;
+ case 4800:
+ value |= 2;
+ break;
+ default:
+ tty_termios_encode_baud_rate(termios, 2400, 2400);
+ case 2400:
+ value |= 1;
+ break;
+ };
+ writeb(value, data->ios_mem);
+
+ serial8250_do_set_termios(port, termios, old);
+}
+
+static const struct of_device_id lp8841_serial_dt_ids[] = {
+ { .compatible = "icpdas,lp8841-uart", },
+ {}
+};
+MODULE_DEVICE_TABLE(of, lp8841_serial_dt_ids);
+
+static int lp8841_serial_probe(struct platform_device *pdev)
+{
+ struct uart_8250_port uart;
+ struct lp8841_serial_data *data;
+ struct resource *mmres, *mires;
+ int ret;
+
+ mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!mmres)
+ return -ENODEV;
+
+ data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ mires = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ data->ios_mem = devm_ioremap_resource(&pdev->dev, mires);
+ if (IS_ERR(data->ios_mem))
+ return PTR_ERR(data->ios_mem);
+
+ memset(&uart, 0, sizeof(uart));
+ uart.port.iotype = UPIO_MEM;
+ uart.port.mapbase = mmres->start;
+ uart.port.regshift = 1;
+ uart.port.irq = platform_get_irq(pdev, 0);
+ uart.port.flags = UPF_IOREMAP;
+ uart.port.dev = &pdev->dev;
+ uart.port.uartclk = 14745600;
+ uart.port.set_termios = lp8841_serial_set_termios;
+ uart.port.private_data = data;
+
+ ret = serial8250_register_8250_port(&uart);
+ if (ret < 0)
+ return ret;
+
+ data->line = ret;
+
+ platform_set_drvdata(pdev, data);
+
+ return 0;
+}
+
+static int lp8841_serial_remove(struct platform_device *pdev)
+{
+ struct lp8841_serial_data *data = platform_get_drvdata(pdev);
+
+ serial8250_unregister_port(data->line);
+
+ return 0;
+}
+
+static struct platform_driver lp8841_serial_driver = {
+ .probe = lp8841_serial_probe,
+ .remove = lp8841_serial_remove,
+ .driver = {
+ .name = "uart-lp8841",
+ .of_match_table = lp8841_serial_dt_ids,
+ },
+};
+
+module_platform_driver(lp8841_serial_driver);
+
+MODULE_AUTHOR("Sergei Ianovich");
+MODULE_DESCRIPTION("8250 serial port module for LP-8841");
+MODULE_LICENSE("GPL");
diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig
index 3b5cf9c..68640c1 100644
--- a/drivers/tty/serial/8250/Kconfig
+++ b/drivers/tty/serial/8250/Kconfig
@@ -394,3 +394,17 @@ config SERIAL_8250_PXA
help
If you have a machine based on an Intel XScale PXA2xx CPU you
can enable its onboard serial ports by enabling this option.
+
+ If you choose M here, the module name will be 8250_pxa.
+
+config SERIAL_8250_LP8841
+ tristate "Support 16550A ports on ICP DAS LP-8841"
+ depends on SERIAL_8250 && MACH_PXA27X_DT
+ select LP8841_IRQ
+ help
+ In addition to serial ports on PXA270 SoC, LP-8841 has 1 dual
+ RS232/RS485 port, 1 RS485 port and 1 RS232 port.
+
+ Say N here, unless you plan to run this kernel on a LP-8841 system.
+
+ If you choose M here, the module name will be 8250_lp8841.
diff --git a/drivers/tty/serial/8250/Makefile b/drivers/tty/serial/8250/Makefile
index d1e2f2d..10b4bf0 100644
--- a/drivers/tty/serial/8250/Makefile
+++ b/drivers/tty/serial/8250/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_SERIAL_8250_ACCENT) += 8250_accent.o
obj-$(CONFIG_SERIAL_8250_BOCA) += 8250_boca.o
obj-$(CONFIG_SERIAL_8250_EXAR_ST16C554) += 8250_exar_st16c554.o
obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o
+obj-$(CONFIG_SERIAL_8250_LP8X4X) += 8250_lp8x4x.o
obj-$(CONFIG_SERIAL_8250_FSL) += 8250_fsl.o
obj-$(CONFIG_SERIAL_8250_DW) += 8250_dw.o
obj-$(CONFIG_SERIAL_8250_EM) += 8250_em.o
@@ -30,5 +31,6 @@ obj-$(CONFIG_SERIAL_8250_INGENIC) += 8250_ingenic.o
obj-$(CONFIG_SERIAL_8250_MID) += 8250_mid.o
obj-$(CONFIG_SERIAL_OF_PLATFORM) += 8250_of.o
obj-$(CONFIG_SERIAL_8250_PXA) += 8250_pxa.o
+obj-$(CONFIG_SERIAL_8250_LP8841) += 8250_lp8841.o
CFLAGS_8250_ingenic.o += -I$(srctree)/scripts/dtc/libfdt
--
2.7.0
^ permalink raw reply related [flat|nested] 148+ messages in thread
* Re: [PATCH v6] arm: pxa: support ICP DAS LP-8x4x FPGA irq
[not found] ` <1456588562-24715-1-git-send-email-ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2016-02-27 17:41 ` Jason Cooper
@ 2016-03-03 22:12 ` Rob Herring
1 sibling, 0 replies; 148+ messages in thread
From: Rob Herring @ 2016-03-03 22:12 UTC (permalink / raw)
To: Sergei Ianovich
Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA, Arnd Bergmann, Marc Zyngier,
Thomas Gleixner, Jason Cooper, Pawel Moll, Mark Rutland,
Ian Campbell, Kumar Gala,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS
On Sat, Feb 27, 2016 at 06:56:01PM +0300, Sergei Ianovich wrote:
> ICP DAS LP-8x4x contains FPGA chip. The chip functions as an interrupt
> source providing 16 additional interrupts among other things. The
> interrupt lines are muxed to a GPIO pin of a 2nd level PXA-GPIO
> interrupt controller. GPIO pins of the 2nd level controller are in turn
> muxed to a CPU interrupt line.
>
> Until pxa is completely converted to device tree, it is impossible
> to use IRQCHIP_DECLARE() and the irqdomain needs to added manually.
> Drivers for the on-CPU IRQs and GPIO-IRQs are loaded using
> postcore_initcall(). We need to have all irq domain drivers loaded prior
> to DT parsing in order to allow normal initialization of IRQ resources
> with DT.
>
> Signed-off-by: Sergei Ianovich <ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> Reviewed-by: Linus Walleij <linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> CC: Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org>
> CC: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> CC: Marc Zyngier <marc.zyngier-5wv7dgnIgG8@public.gmane.org>
>
> v5..v6
> fixes according to Rob Herring review comments:
> * drop wildcards in binding and file names
> * rename alias 'fpga'->'fpga_irq'
>
> fixes according to Marc Zyngier review comments:
> * use writeb/readb not iowrite8/ioread8
> * redefine 2nd mask using inversion on 1st
> * add comments
>
> v4..v5
> * constify struct of_device_id
> * drop irq number from handler signature
>
> v3.2..v4
> * move DTS binding to a different patch (8/21)
>
> v3.1..v3.2
> fixes to apply Linus Walleij's "Reviewed-by":
> * add kerneldoc comment for state container struct
> * rename irq -> hwirq for clarity
> * drop overzealous error checks from the hotpaths
>
> v3..v3.1
> fixes according to Linus Walleij review comments:
> * update commit message
> * use state container instead of global variables
> * get hardware irq nums from irq_data, don't calculate them
> * use BIT() macro
> * add defines for system irq register masks
> * replace cycle control variable with break
> * use better names for resource variables
> * add a linear domain instead of a legacy one
> * use irq_create_mapping() instead of irq_alloc_desc()
>
> v2..v3
> * no changes (except number 09/16 -> 11/21)
>
> v0..v2
> * extract irqchip and move to drivers/irqchip/
> * use device tree
> * use devm helpers where possible
> ---
> .../interrupt-controller/icpdas-lp8x4x-irq.txt | 49 ++++
> drivers/irqchip/Kconfig | 5 +
> drivers/irqchip/Makefile | 1 +
> drivers/irqchip/irq-lp8841.c | 246 +++++++++++++++++++++
> 4 files changed, 301 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/interrupt-controller/icpdas-lp8x4x-irq.txt
> create mode 100644 drivers/irqchip/irq-lp8841.c
>
> diff --git a/Documentation/devicetree/bindings/interrupt-controller/icpdas-lp8x4x-irq.txt b/Documentation/devicetree/bindings/interrupt-controller/icpdas-lp8x4x-irq.txt
> new file mode 100644
> index 0000000..a72109b
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/interrupt-controller/icpdas-lp8x4x-irq.txt
> @@ -0,0 +1,49 @@
> +ICP DAS LP-8841 FPGA Interrupt Controller
> +
> +ICP DAS LP-8841 contains FPGA chip. The chip functions as a interrupt
> +source providing 16 additional interrupts among other things.
> +
> +Required properties:
> +- compatible : should be "icpdas,lp8x4x-irq"
You've still got wildcards here. Seems to be an oversight as the example
and code have "icpdas,lp8841-irq".
> +
> +- reg: physical base address of the controller and length of memory mapped
> + region.
> +
> +- interrupt-controller : identifies the node as an interrupt controller
> +
> +- #interrupt-cells : should be 1
> +
> +- interrupts : should provide interrupt
> +
> +Optional properties:
> +
> +- interrupt-parent : should provide a link to interrupt controller either
> + explicitly and implicitly from a parent node
> +
> +Example:
> +
> +fpgairq: irq@9006 {
Still not right... interrupt-controller@9006
> + compatible = "icpdas,lp8841-irq";
> + reg = <0x9006 0x16>;
> + interrupt-parent = <&gpio>;
> + interrupts = <3 IRQ_TYPE_EDGE_FALLING>;
> + #interrupt-cells = <1>;
> + interrupt-controller;
> + status = "okay";
> +};
> +
> +serial@9050 {
> + compatible = "icpdas,lp8841-uart";
> + reg = <0x9050 0x10
> + 0x9030 0x02>;
> + interrupts = <13>;
> + status = "okay";
> +};
> +
> +serial@9060 {
> + compatible = "icpdas,lp8841-uart";
> + reg = <0x9060 0x10
> + 0x9032 0x02>;
> + interrupts = <14>;
> + status = "okay";
> +};
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH v10] serial: support for 16550A serial ports on LP-8x4x
2016-03-01 21:25 ` [PATCH v10] " Sergei Ianovich
@ 2016-03-05 4:26 ` Rob Herring
0 siblings, 0 replies; 148+ messages in thread
From: Rob Herring @ 2016-03-05 4:26 UTC (permalink / raw)
To: Sergei Ianovich
Cc: linux-kernel, Alan Cox, Arnd Bergmann, Pawel Moll, Mark Rutland,
Ian Campbell, Kumar Gala, Greg Kroah-Hartman, Jiri Slaby,
Heikki Krogerus, Andy Shevchenko, Masahiro Yamada, Peter Hurley,
Paul Burton, Mans Rullgard, Scott Wood, Paul Gortmaker,
Joachim Eastwood, Peter Ujfalusi,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
SERIAL
On Wed, Mar 02, 2016 at 12:25:35AM +0300, Sergei Ianovich wrote:
> The patch adds support for 3 additional LP-8x4x built-in serial
> ports.
>
> The device can also host up to 8 extension cards with 4 serial ports
> on each card for a total of 35 ports. However, I don't have
> the hardware to test extension cards, so they are not supported, yet.
That's a lot of serial ports...
[...]
> diff --git a/Documentation/devicetree/bindings/serial/icpdas-lp8841-uart.txt b/Documentation/devicetree/bindings/serial/icpdas-lp8841-uart.txt
> new file mode 100644
> index 0000000..d6acd22
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/serial/icpdas-lp8841-uart.txt
> @@ -0,0 +1,41 @@
> +* UART ports on ICP DAS LP-8841
> +
> +LP-8441, LP-8141 and LP-8041 are fully compatible.
> +
> +ICP DAS LP-8841 contains three additional serial ports interfaced via
> +Analog Devices ADM213EA chips in addition to 3 serial ports on PXA CPU.
> +
> +The chips themselves are standard, they would work with 8250_core if
Describe in h/w terms how they are different, not what Linux driver
won't work.
> +properly connected. However, they are not connected normally. Al least
s/Al/At/
> +some of their config pins are wired to a different address region. So
> +the driver is board-specific.
> +
> +Required properties:
> +- compatible : should be "icpdas,uart-lp8841"
> +
> +- reg : should provide 16 byte man IO memory region and 1 byte region for
What is "man IO"?
> + termios
termios is a Linux term.
> +
> +- interrupts : should provide interrupt
Perhaps you should include other properties standard for 8250 such as
access size or shift. Possibly if the non-standard bits are already
configured, the UART could be used for earlycon?
> +
> +Optional property:
> +- interrupt-parent : should provide a link to interrupt controller either
> + explicitly or implicitly from a parent node
> +
> +Examples (from pxa27x-lp8x4x.dts):
> +
> + serial@9050 {
> + compatible = "icpdas,uart-lp8841";
> + reg = <0x9050 0x10
> + 0x9030 0x02>;
> + interrupts = <13>;
> + status = "okay";
> + };
> +
> + serial@9060 {
> + compatible = "icpdas,uart-lp8841";
> + reg = <0x9060 0x10
> + 0x9032 0x02>;
> + interrupts = <14>;
> + status = "okay";
> + };
[...]
> diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig
> index 3b5cf9c..68640c1 100644
> --- a/drivers/tty/serial/8250/Kconfig
> +++ b/drivers/tty/serial/8250/Kconfig
> @@ -394,3 +394,17 @@ config SERIAL_8250_PXA
> help
> If you have a machine based on an Intel XScale PXA2xx CPU you
> can enable its onboard serial ports by enabling this option.
> +
> + If you choose M here, the module name will be 8250_pxa.
> +
> +config SERIAL_8250_LP8841
> + tristate "Support 16550A ports on ICP DAS LP-8841"
> + depends on SERIAL_8250 && MACH_PXA27X_DT
> + select LP8841_IRQ
Generally, drivers don't select their interrupt controller.
> + help
> + In addition to serial ports on PXA270 SoC, LP-8841 has 1 dual
> + RS232/RS485 port, 1 RS485 port and 1 RS232 port.
> +
> + Say N here, unless you plan to run this kernel on a LP-8841 system.
> +
> + If you choose M here, the module name will be 8250_lp8841.
> diff --git a/drivers/tty/serial/8250/Makefile b/drivers/tty/serial/8250/Makefile
> index d1e2f2d..10b4bf0 100644
> --- a/drivers/tty/serial/8250/Makefile
> +++ b/drivers/tty/serial/8250/Makefile
> @@ -18,6 +18,7 @@ obj-$(CONFIG_SERIAL_8250_ACCENT) += 8250_accent.o
> obj-$(CONFIG_SERIAL_8250_BOCA) += 8250_boca.o
> obj-$(CONFIG_SERIAL_8250_EXAR_ST16C554) += 8250_exar_st16c554.o
> obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o
> +obj-$(CONFIG_SERIAL_8250_LP8X4X) += 8250_lp8x4x.o
This should be dropped.
> obj-$(CONFIG_SERIAL_8250_FSL) += 8250_fsl.o
> obj-$(CONFIG_SERIAL_8250_DW) += 8250_dw.o
> obj-$(CONFIG_SERIAL_8250_EM) += 8250_em.o
> @@ -30,5 +31,6 @@ obj-$(CONFIG_SERIAL_8250_INGENIC) += 8250_ingenic.o
> obj-$(CONFIG_SERIAL_8250_MID) += 8250_mid.o
> obj-$(CONFIG_SERIAL_OF_PLATFORM) += 8250_of.o
> obj-$(CONFIG_SERIAL_8250_PXA) += 8250_pxa.o
> +obj-$(CONFIG_SERIAL_8250_LP8841) += 8250_lp8841.o
This should be in alphabetical order. OF_PLATFORM is not for legacy
reasons I think.
>
> CFLAGS_8250_ingenic.o += -I$(srctree)/scripts/dtc/libfdt
> --
> 2.7.0
>
^ permalink raw reply [flat|nested] 148+ messages in thread
* Re: [PATCH v6] mtd: support BB SRAM on ICP DAS LP-8x4x
[not found] ` <1456253890-30825-1-git-send-email-ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2016-02-23 19:48 ` Rob Herring
@ 2016-03-08 0:19 ` Brian Norris
1 sibling, 0 replies; 148+ messages in thread
From: Brian Norris @ 2016-03-08 0:19 UTC (permalink / raw)
To: Sergei Ianovich
Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA, Rob Herring, Rob Herring,
Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
David Woodhouse, Jeremy Kerr, Neelesh Gupta, Michael Ellerman,
Cyril Bur, Joel Stanley,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list:MEMORY TECHNOLOGY DEVICES [MTD]
Hi Sergei,
A few more issues...
On Tue, Feb 23, 2016 at 09:58:01PM +0300, Sergei Ianovich wrote:
> This provides an MTD device driver for 512kB of battery backed up SRAM
> on ICPDAS LP-8X4X programmable automation controllers.
>
> SRAM chip is connected via FPGA and is not accessible without a driver,
> unlike flash memory which is wired to CPU MMU.
>
> This SRAM becomes an excellent persisent storage of volatile process
> data like counter values and sensor statuses. Storing those data in
> flash or mmc card is not a viable solution.
>
> Signed-off-by: Sergei Ianovich <ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> Reviewed-by: Brian Norris <computersforpeace-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> CC: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
>
> v5..v6
> * replace wildcards in compatible and module name
> * drop obsolete mtd_part_parser_data.of_node
>
> v4..v5
> * remove .owner from struct platform_driver
> * constify struct of_device_id
> for further Brian Norris comments:
> * drop unused property from doc file
> * move defconfig update to a different file
> * drop extra match w/ of_match_device()
>
> v3..v4 for Brian Norris 'Reviewed-by'
> * add doc file for DT binding
> * move DTS binding to a different patch (8/21)
> * drop unused include directive
> * drop safely unused callback
> * drop non-default partion probe types
> * drop duplicate error checks
> * drop duplicate error reporting
> * fixed error message on MTD registeration
> * fixed module removal routine
>
> v2..v3
> * no changes (except number 08/16 -> 10/21)
>
> v0..v2
> * use device tree
> * use devm helpers where possible
> ---
> .../devicetree/bindings/mtd/icpdas-lp8841-sram.txt | 23 +++
> drivers/mtd/devices/Kconfig | 14 ++
> drivers/mtd/devices/Makefile | 1 +
> drivers/mtd/devices/sram_lp8841.c | 198 +++++++++++++++++++++
> 4 files changed, 236 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/mtd/icpdas-lp8841-sram.txt
> create mode 100644 drivers/mtd/devices/sram_lp8841.c
>
> diff --git a/Documentation/devicetree/bindings/mtd/icpdas-lp8841-sram.txt b/Documentation/devicetree/bindings/mtd/icpdas-lp8841-sram.txt
> new file mode 100644
> index 0000000..3c1007a
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mtd/icpdas-lp8841-sram.txt
> @@ -0,0 +1,23 @@
> +512kB battery backed up SRAM on ICP DAS LP-8841 industrial computers
> +
> +LP-8441, LP-8141, and LP-8041 differ from LP-8841 only in expansion
> +slot count.
> +
> +Required properties:
> +- compatible : should be "icpdas,lp8841-sram"
> +
> +- reg: physical base addresses and region lengths of
> + * IO memory range
> + * SRAM page selector
> +
> +SRAM chip is connected via FPGA and is not accessible without a driver,
> +unlike flash memory which is wired to CPU MMU. Driver is essentially
> +an address translation routine.
> +
> +Example:
> +
> + sram@a000 {
> + compatible = "icpdas,lp8841-sram";
> + reg = <0xa000 0x1000
> + 0x901e 0x1>;
> + };
> diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig
> index f73c416..ecf5733 100644
> --- a/drivers/mtd/devices/Kconfig
> +++ b/drivers/mtd/devices/Kconfig
> @@ -233,4 +233,18 @@ config BCH_CONST_T
> default 4
> endif
>
> +config MTD_SRAM_LP8841
> + tristate "SRAM on ICP DAS LP-8841"
> + depends on OF && ARCH_PXA
> + ---help---
> + This provides an MTD device driver for 512kiB of battery backed up SRAM
> + on ICPDAS LP-8X41 programmable automation controllers.
> +
> + SRAM chip is connected via FPGA and is not accessible without a driver,
> + unlike flash memory which is wired to CPU MMU.
> +
> + Say N, unless you plan to run this kernel on LP-8X41.
> +
> + If you say M, the module will be called sram_lp8841.
> +
> endmenu
> diff --git a/drivers/mtd/devices/Makefile b/drivers/mtd/devices/Makefile
> index 7912d3a..46df5d6 100644
> --- a/drivers/mtd/devices/Makefile
> +++ b/drivers/mtd/devices/Makefile
> @@ -17,6 +17,7 @@ obj-$(CONFIG_MTD_SST25L) += sst25l.o
> obj-$(CONFIG_MTD_BCM47XXSFLASH) += bcm47xxsflash.o
> obj-$(CONFIG_MTD_ST_SPI_FSM) += st_spi_fsm.o
> obj-$(CONFIG_MTD_POWERNV_FLASH) += powernv_flash.o
> +obj-$(CONFIG_MTD_SRAM_LP8841) += sram_lp8841.o
>
>
> CFLAGS_docg3.o += -I$(src)
> diff --git a/drivers/mtd/devices/sram_lp8841.c b/drivers/mtd/devices/sram_lp8841.c
> new file mode 100644
> index 0000000..5d5d942
> --- /dev/null
> +++ b/drivers/mtd/devices/sram_lp8841.c
> @@ -0,0 +1,198 @@
> +/*
> + * linux/drivers/mtd/devices/sram_lp8841.c
> + *
> + * MTD Driver for SRAM on ICP DAS LP-8841
> + * Copyright (C) 2013 Sergei Ianovich <ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation or any later version.
> + */
> +
> +#include <linux/init.h>
> +#include <linux/io.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/mtd/map.h>
> +#include <linux/mtd/mtd.h>
> +#include <linux/mtd/partitions.h>
> +#include <linux/platform_device.h>
> +#include <linux/of_device.h>
> +#include <linux/slab.h>
> +#include <linux/string_helpers.h>
> +#include <linux/types.h>
> +
> +struct lp8841_sram_info {
> + void __iomem *bank;
> + void __iomem *virt;
> + struct mutex lock;
> + unsigned active_bank;
> + struct mtd_info mtd;
> +};
> +
> +static int
> +lp8841_sram_erase(struct mtd_info *mtd, struct erase_info *instr)
> +{
> + struct lp8841_sram_info *info = mtd->priv;
> + unsigned bank = instr->addr >> 11;
> + unsigned offset = (instr->addr & 0x7ff) << 1;
> + loff_t i;
> +
> + mutex_lock(&info->lock);
> + if (unlikely(bank != info->active_bank)) {
> + info->active_bank = bank;
> + iowrite8(bank, info->bank);
> + }
> + for (i = 0; i < instr->len; i++) {
> + iowrite8(0xff, info->virt + offset);
> + offset += 2;
> + if (unlikely(offset == 0)) {
> + info->active_bank++;
> + iowrite8(info->active_bank, info->bank);
> + }
> + }
> + mutex_unlock(&info->lock);
> + instr->state = MTD_ERASE_DONE;
> + mtd_erase_callback(instr);
> +
> + return 0;
> +}
> +
> +static int
> +lp8841_sram_write(struct mtd_info *mtd, loff_t to, size_t len,
> + size_t *retlen, const u_char *b)
> +{
> + struct lp8841_sram_info *info = mtd->priv;
> + unsigned bank = to >> 11;
> + unsigned offset = (to & 0x7ff) << 1;
> + loff_t i;
> +
> + mutex_lock(&info->lock);
> + if (unlikely(bank != info->active_bank)) {
> + info->active_bank = bank;
> + iowrite8(bank, info->bank);
> + }
> + for (i = 0; i < len; i++) {
> + iowrite8(b[i], info->virt + offset);
> + offset += 2;
> + if (unlikely(offset == 0)) {
> + info->active_bank++;
> + iowrite8(info->active_bank, info->bank);
> + }
> + }
> + mutex_unlock(&info->lock);
> + *retlen = len;
> + return 0;
> +}
> +
> +static int
> +lp8841_sram_read(struct mtd_info *mtd, loff_t from, size_t len,
> + size_t *retlen, u_char *b)
> +{
> + struct lp8841_sram_info *info = mtd->priv;
> + unsigned bank = from >> 11;
> + unsigned offset = (from & 0x7ff) << 1;
> + loff_t i;
> +
> + mutex_lock(&info->lock);
> + if (unlikely(bank != info->active_bank)) {
> + info->active_bank = bank;
> + iowrite8(bank, info->bank);
> + }
> + for (i = 0; i < len; i++) {
> + b[i] = ioread8(info->virt + offset);
> + offset += 2;
> + if (unlikely(offset == 0)) {
> + info->active_bank++;
> + iowrite8(info->active_bank, info->bank);
> + }
> + }
> + mutex_unlock(&info->lock);
> + *retlen = len;
> + return 0;
> +}
> +
> +static const struct of_device_id of_flash_match[] = {
> + {
> + .compatible = "icpdas,lp8841-sram",
> + },
> + { },
> +};
> +MODULE_DEVICE_TABLE(of, of_flash_match);
> +
> +static int
> +lp8841_sram_probe(struct platform_device *pdev)
> +{
> + struct lp8841_sram_info *info;
> + struct resource *res_virt, *res_bank;
> + char sz_str[16];
> + struct mtd_part_parser_data ppdata;
You don't need this struct any more.
> + int err = 0;
> +
> + info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
> + if (!info)
> + return -ENOMEM;
> +
> + res_virt = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> + info->virt = devm_ioremap_resource(&pdev->dev, res_virt);
> + if (IS_ERR(info->virt))
> + return PTR_ERR(info->virt);
> +
> + res_bank = platform_get_resource(pdev, IORESOURCE_MEM, 1);
> + info->bank = devm_ioremap_resource(&pdev->dev, res_bank);
> + if (IS_ERR(info->bank))
> + return PTR_ERR(info->bank);
> +
> + info->mtd.priv = info;
> + info->mtd.name = "SRAM";
> + info->mtd.type = MTD_RAM;
> + info->mtd.flags = MTD_CAP_RAM;
> + info->mtd.size = resource_size(res_virt) << 7;
> + info->mtd.erasesize = 512;
> + info->mtd.writesize = 4;
Can you please set mtd.writebufsize to an appropriate value too? Maybe
it's just the same as writesize.
> + info->mtd._erase = lp8841_sram_erase;
> + info->mtd._write = lp8841_sram_write;
> + info->mtd._read = lp8841_sram_read;
> + info->mtd.owner = THIS_MODULE;
If you set info->mtd.dev.parent (please do), you don't need the above
line.
> +
> + mutex_init(&info->lock);
> + iowrite8(info->active_bank, info->bank);
> + platform_set_drvdata(pdev, info);
> +
> + err = mtd_device_parse_register(&info->mtd, NULL, &ppdata,
> + NULL, 0);
This can just be:
err = mtd_device_register(&info->mtd, NULL, 0);
> +
> + if (err < 0) {
> + dev_err(&pdev->dev, "failed to register MTD\n");
> + return err;
> + }
> +
> + string_get_size(info->mtd.size, 1, STRING_UNITS_2, sz_str,
> + sizeof(sz_str));
> + dev_info(&pdev->dev, "using %s SRAM on LP-8X4X as %s\n", sz_str,
> + dev_name(&info->mtd.dev));
> + return 0;
> +}
> +
> +static int
> +lp8841_sram_remove(struct platform_device *dev)
> +{
> + struct lp8841_sram_info *info = platform_get_drvdata(dev);
> +
> + return mtd_device_unregister(&info->mtd);
> +}
> +
> +static struct platform_driver lp8841_sram_driver = {
> + .driver = {
> + .name = "sram-lp8841",
> + .of_match_table = of_flash_match,
> + },
> + .probe = lp8841_sram_probe,
> + .remove = lp8841_sram_remove,
> +};
> +
> +module_platform_driver(lp8841_sram_driver);
> +
> +MODULE_LICENSE("GPL");
> +MODULE_AUTHOR("Sergei Ianovich");
> +MODULE_DESCRIPTION("MTD driver for SRAM on ICPDAS LP-8841");
Brian
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 148+ messages in thread
end of thread, other threads:[~2016-03-08 0:19 UTC | newest]
Thread overview: 148+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <1386348542-9584-1-git-send-email-ynvich@gmail.com>
[not found] ` <1386543229-1542-1-git-send-email-ynvich@gmail.com>
2013-12-08 22:53 ` [PATCH 1/9] ARM: dts: pxa2xx fix compatible strings Sergei Ianovich
2013-12-08 22:53 ` [PATCH 2/9] ARM: dts: fix pxa27x-gpio interrupts Sergei Ianovich
2013-12-08 22:53 ` [PATCH 5/9] ARM: dts: provide DMA config to pxamci Sergei Ianovich
2013-12-09 1:33 ` Arnd Bergmann
2013-12-09 9:04 ` Daniel Mack
2013-12-09 9:34 ` Sergei Ianovich
2013-12-09 9:53 ` Sergei Ianovich
2013-12-09 10:21 ` Daniel Mack
[not found] ` <52A59991.1060305-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2013-12-09 12:09 ` Sergei Ianovich
2013-12-10 0:25 ` Arnd Bergmann
2013-12-10 4:25 ` Sergei Ianovich
2013-12-09 13:16 ` Sergei Ianovich
2013-12-11 8:19 ` Robert Jarzmik
2013-12-08 22:53 ` [PATCH 9/9] ARM: pxa27x: device tree support ICP DAS LP-8x4x Sergei Ianovich
2013-12-09 1:47 ` Arnd Bergmann
2013-12-09 15:16 ` Sergei Ianovich
2013-12-09 15:55 ` Sergei Ianovich
[not found] ` <1386604530.7152.184.camel-7ZSkjCHmnyFmet/iJI8ZvA@public.gmane.org>
2013-12-09 16:39 ` Arnd Bergmann
2013-12-09 16:25 ` Arnd Bergmann
[not found] ` <1386901645-28895-1-git-send-email-ynvich@gmail.com>
2013-12-13 2:27 ` [PATCH v2 01/16] ARM: dts: pxa2xx fix compatible strings Sergei Ianovich
2013-12-13 2:27 ` [PATCH v2 02/16] ARM: dts: fix pxa27x-gpio interrupts Sergei Ianovich
2013-12-13 2:27 ` [PATCH v2 03/16] ARM: dts: provide DMA config to pxamci Sergei Ianovich
2013-12-14 19:06 ` Arnd Bergmann
2013-12-14 19:34 ` Sergei Ianovich
2013-12-14 23:39 ` Arnd Bergmann
2013-12-16 9:58 ` Daniel Mack
2013-12-16 11:47 ` Sergei Ianovich
[not found] ` <1387194450.13062.134.camel-7ZSkjCHmnyFmet/iJI8ZvA@public.gmane.org>
2013-12-16 11:58 ` Lars-Peter Clausen
2013-12-16 12:03 ` Sergei Ianovich
2013-12-13 2:27 ` [PATCH v2 06/16] ARM: pxa27x: device tree support ICP DAS LP-8x4x Sergei Ianovich
2013-12-13 2:27 ` [PATCH v2 07/16] rtc: support DS1302 RTC on " Sergei Ianovich
2013-12-13 2:27 ` [PATCH v2 08/16] mtd: support BB SRAM " Sergei Ianovich
[not found] ` <1386901645-28895-1-git-send-email-ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2013-12-13 2:27 ` [PATCH v2 09/16] ARM: pxa: support ICP DAS LP-8x4x FPGA irq Sergei Ianovich
2013-12-13 2:27 ` [PATCH v2 10/16] serial: support for 16550A serial ports on LP-8x4x Sergei Ianovich
2013-12-13 2:27 ` [PATCH v2 11/16] misc: support for LP-8x4x custom parallel bus Sergei Ianovich
2013-12-13 2:27 ` [PATCH v2 12/16] misc: support for serial slots in LP-8x4x Sergei Ianovich
[not found] ` <1387309071-22382-1-git-send-email-ynvich@gmail.com>
2013-12-17 19:37 ` [PATCH v3 01/21 resend] serial: rewrite pxa2xx-uart to use 8250_core Sergei Ianovich
2013-12-18 23:55 ` Greg Kroah-Hartman
2013-12-19 8:51 ` Heikki Krogerus
2013-12-19 9:35 ` Sergei Ianovich
2013-12-19 10:01 ` Sergei Ianovich
2013-12-19 11:05 ` Heikki Krogerus
2013-12-17 19:37 ` [PATCH v3 02/21] ARM: dts: pxa2xx fix compatible strings Sergei Ianovich
[not found] ` <1387309071-22382-1-git-send-email-ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2013-12-17 19:37 ` [PATCH v3 03/21] ARM: dts: fix pxa27x-gpio interrupts Sergei Ianovich
2013-12-17 19:37 ` [PATCH v3 06/21] ARM: dts: provide DMA config to pxamci on PXA27x Sergei Ianovich
2013-12-17 19:37 ` [PATCH v3 08/21] ARM: pxa27x: device tree support ICP DAS LP-8x4x Sergei Ianovich
2013-12-17 19:37 ` [PATCH v3 09/21] rtc: support DS1302 RTC on " Sergei Ianovich
2013-12-17 19:37 ` [PATCH v3 10/21] mtd: support BB SRAM " Sergei Ianovich
2014-04-16 5:04 ` Brian Norris
2014-04-16 5:21 ` Sergei Ianovich
2013-12-17 19:37 ` [PATCH v3 11/21] ARM: pxa: support ICP DAS LP-8x4x FPGA irq Sergei Ianovich
2014-01-02 12:32 ` Linus Walleij
2014-01-08 19:01 ` Sergei Ianovich
2014-01-15 7:39 ` Linus Walleij
2014-01-15 13:17 ` Sergei Ianovich
[not found] ` <1387309071-22382-12-git-send-email-ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2014-01-09 23:07 ` [PATCH v3.1 " Sergei Ianovich
2014-01-15 7:46 ` Linus Walleij
2014-01-15 13:12 ` [PATCH v3.2 " Sergei Ianovich
2013-12-17 19:37 ` [PATCH v3 12/21] serial: support for 16550A serial ports on LP-8x4x Sergei Ianovich
2013-12-19 11:18 ` Heikki Krogerus
2013-12-17 19:37 ` [PATCH v3 13/21] misc: support for LP-8x4x custom parallel bus Sergei Ianovich
2013-12-17 19:37 ` [PATCH v3 14/21] misc: support for LP-8x4x rotary switch Sergei Ianovich
2013-12-17 19:37 ` [PATCH v3 15/21] misc: support for LP-8x4x DIP switch Sergei Ianovich
2013-12-17 19:37 ` [PATCH v3 16/21] misc: support for writing to LP-8x4x EEPROM Sergei Ianovich
2013-12-17 19:37 ` [PATCH v3 17/21] misc: support for serial slots in LP-8x4x Sergei Ianovich
2013-12-17 19:37 ` [PATCH v3 18/21] misc: support for parallel " Sergei Ianovich
[not found] ` <1397668411-27162-1-git-send-email-ynvich@gmail.com>
2014-04-16 17:13 ` [PATCH v4 01/21] serial: rewrite pxa2xx-uart to use 8250_core Sergei Ianovich
2015-01-19 18:08 ` Rob Herring
2014-04-16 17:13 ` [PATCH v4 02/21] ARM: dts: pxa2xx fix compatible strings Sergei Ianovich
2014-04-16 17:13 ` [PATCH v4 03/21] ARM: dts: fix pxa27x-gpio interrupts Sergei Ianovich
2014-04-16 17:13 ` [PATCH v4 06/21] ARM: dts: provide DMA config to pxamci on PXA27x Sergei Ianovich
[not found] ` <1397668667-27328-1-git-send-email-ynvich@gmail.com>
2014-04-16 17:17 ` [PATCH v4 08/21] ARM: pxa27x: device tree support ICP DAS LP-8x4x Sergei Ianovich
2014-04-17 10:54 ` Daniel Mack
2014-04-16 17:17 ` [PATCH v4 09/21] rtc: support DS1302 RTC on " Sergei Ianovich
2015-06-08 12:07 ` [v4,09/21] " Alexandre Belloni
2015-06-08 12:12 ` Sergei Ianovich
2014-04-16 17:17 ` [PATCH v4 10/21] mtd: support BB SRAM " Sergei Ianovich
2014-04-30 17:21 ` Brian Norris
2014-04-30 17:35 ` ООО "ЭлектроПлюс"
[not found] ` <1397668667-27328-4-git-send-email-ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2015-12-15 18:58 ` [PATCH v5] " Sergei Ianovich
2015-12-20 3:38 ` Rob Herring
2015-12-20 10:43 ` Sergei Ianovich
[not found] ` <1450608238.15911.24.camel-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2016-01-06 23:25 ` Brian Norris
[not found] ` <1450205941-15593-1-git-send-email-ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2016-02-23 18:58 ` [PATCH v6] " Sergei Ianovich
[not found] ` <1456253890-30825-1-git-send-email-ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2016-02-23 19:48 ` Rob Herring
2016-03-08 0:19 ` Brian Norris
2014-04-16 17:17 ` [PATCH v4 11/21] ARM: pxa: support ICP DAS LP-8x4x FPGA irq Sergei Ianovich
[not found] ` <1397668667-27328-5-git-send-email-ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2015-12-15 19:26 ` [PATCH v5] arm: " Sergei Ianovich
2015-12-16 11:54 ` Marc Zyngier
2015-12-19 4:20 ` Rob Herring
[not found] ` <20151219035802.GA28424@rob-hp-laptop>
2015-12-19 7:03 ` Sergei Ianovich
2016-02-27 15:56 ` [PATCH v6] " Sergei Ianovich
[not found] ` <1456588562-24715-1-git-send-email-ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2016-02-27 17:41 ` Jason Cooper
[not found] ` <20160227174100.GG7219-fahSIxCzskDQ+YiMSub0/l6hYfS7NtTn@public.gmane.org>
2016-02-29 8:29 ` Marc Zyngier
2016-03-03 22:12 ` Rob Herring
2014-04-16 17:17 ` [PATCH v4 12/21] serial: support for 16550A serial ports on LP-8x4x Sergei Ianovich
2014-04-16 18:35 ` One Thousand Gnomes
2014-04-16 19:01 ` Sergei Ianovich
2014-04-16 20:00 ` One Thousand Gnomes
[not found] ` <20140416210051.01bef49e-mUKnrFFms3BCCTY1wZZT65JpZx93mCW/@public.gmane.org>
2014-04-16 20:32 ` Sergei Ianovich
2014-04-16 17:17 ` [PATCH v4 13/21] misc: support for LP-8x4x custom parallel bus Sergei Ianovich
2014-04-16 18:41 ` One Thousand Gnomes
2014-04-16 18:42 ` Arnd Bergmann
2014-04-16 20:29 ` One Thousand Gnomes
2014-04-16 19:53 ` Sergei Ianovich
2014-04-16 17:17 ` [PATCH v4 14/21] misc: support for LP-8x4x rotary switch Sergei Ianovich
2014-04-16 17:17 ` [PATCH v4 15/21] misc: support for LP-8x4x DIP switch Sergei Ianovich
2014-04-16 17:17 ` [PATCH v4 16/21] misc: support for writing to LP-8x4x EEPROM Sergei Ianovich
2014-04-16 17:17 ` [PATCH v4 17/21] misc: support for serial slots in LP-8x4x Sergei Ianovich
2014-04-16 17:17 ` [PATCH v4 18/21] misc: support for parallel " Sergei Ianovich
[not found] ` <1397668667-27328-1-git-send-email-ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2015-12-15 21:04 ` [PATCH v5] serial: support for 16550A serial ports on LP-8x4x Sergei Ianovich
2015-12-15 21:51 ` Arnd Bergmann
2015-12-16 8:04 ` Sergei Ianovich
2015-12-16 10:26 ` Arnd Bergmann
2015-12-19 8:11 ` Sergei Ianovich
2015-12-19 21:42 ` Sergei Ianovich
2015-12-17 14:50 ` Andy Shevchenko
[not found] ` <1450213494-21884-1-git-send-email-ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2016-02-27 16:14 ` [PATCH v6] " Sergei Ianovich
[not found] ` <1456589675-25377-1-git-send-email-ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2016-02-29 10:29 ` Andy Shevchenko
2016-02-29 13:03 ` Sergei Ianovich
[not found] ` <1456750995.23036.87.camel-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2016-02-29 14:45 ` One Thousand Gnomes
2016-02-29 21:26 ` [PATCH v7] " Sergei Ianovich
[not found] ` <1456781209-11390-1-git-send-email-ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2016-03-01 11:06 ` Andy Shevchenko
[not found] ` <1456830401.13244.189.camel-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
2016-03-01 16:25 ` Sergei Ianovich
2016-03-01 16:46 ` Andy Shevchenko
[not found] ` <1456850782.13244.208.camel-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
2016-03-01 17:14 ` Sergei Ianovich
[not found] ` <1456852472.23036.124.camel-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2016-03-01 17:48 ` Andy Shevchenko
2016-03-01 18:43 ` One Thousand Gnomes
[not found] ` <1456854532.13244.215.camel-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
2016-03-01 19:28 ` Sergei Ianovich
[not found] ` <1456860493.23036.133.camel-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2016-03-01 19:53 ` One Thousand Gnomes
2016-03-01 19:54 ` [PATCH v8] " Sergei Ianovich
[not found] ` <1456862078-11795-1-git-send-email-ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2016-03-01 20:08 ` [PATCH v9] " Sergei Ianovich
[not found] ` <1456862903-12392-1-git-send-email-ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2016-03-01 20:23 ` Andy Shevchenko
2016-03-01 21:25 ` [PATCH v10] " Sergei Ianovich
2016-03-05 4:26 ` Rob Herring
[not found] ` <1449700088-28076-1-git-send-email-ynvich@gmail.com>
[not found] ` <1449700088-28076-1-git-send-email-ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2015-12-09 22:28 ` [PATCH v4 2/2] arm: pxa27x: support for ICP DAS LP-8x4x w/ DT Sergei Ianovich
2015-12-11 2:53 ` Rob Herring
[not found] ` <1449700088-28076-3-git-send-email-ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2015-12-15 16:27 ` [PATCH v5 " Sergei Ianovich
2015-12-15 16:32 ` Arnd Bergmann
2015-12-15 16:42 ` Sergei Ianovich
2015-12-15 17:02 ` Arnd Bergmann
2015-12-15 17:24 ` Sergei Ianovich
2015-12-15 18:06 ` Robert Jarzmik
2015-12-15 18:50 ` Sergei Ianovich
[not found] ` <1450205413.21989.44.camel-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2015-12-15 19:21 ` Arnd Bergmann
2015-12-15 20:01 ` Robert Jarzmik
2015-12-15 20:40 ` Arnd Bergmann
2015-12-19 12:27 ` Robert Jarzmik
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).