summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--README15
-rw-r--r--arch/arm/Kconfig1
-rw-r--r--arch/arm/Makefile3
-rw-r--r--arch/arm/boards/embedsky-e9/board.c5
-rw-r--r--arch/arm/boards/freescale-mx6-sabresd/board.c5
-rw-r--r--arch/arm/boards/ls1046ardb/board.c122
-rw-r--r--arch/arm/boards/nvidia-beaver/Makefile4
-rw-r--r--arch/arm/boards/nvidia-jetson-tk1/Makefile4
-rw-r--r--arch/arm/boards/phytec-som-imx6/defaultenv-physom-imx6-phycore/init/bootsource2
-rw-r--r--arch/arm/boards/phytec-som-imx6/defaultenv-physom-imx6/init/bootsource2
-rw-r--r--arch/arm/boards/phytec-som-imx6/flash-header-phytec-pcaaxl3-1gib-1bank.imxcfg1
-rw-r--r--arch/arm/boards/phytec-som-imx6/flash-header-phytec-pcaaxl3-1gib.imxcfg1
-rw-r--r--arch/arm/boards/phytec-som-imx6/flash-header-phytec-pcaaxl3-2gib.imxcfg1
-rw-r--r--arch/arm/boards/phytec-som-imx6/flash-header-phytec-pcl063-256mb.imxcfg1
-rw-r--r--arch/arm/boards/phytec-som-imx6/flash-header-phytec-pcl063-512mb.imxcfg1
-rw-r--r--arch/arm/boards/phytec-som-imx6/flash-header-phytec-pcm058-1gib.imxcfg1
-rw-r--r--arch/arm/boards/phytec-som-imx6/flash-header-phytec-pcm058-2gib.imxcfg1
-rw-r--r--arch/arm/boards/phytec-som-imx6/flash-header-phytec-pcm058dl-1gib-32bit.imxcfg1
-rw-r--r--arch/arm/boards/phytec-som-imx6/flash-header-phytec-pcm058dl-1gib.imxcfg1
-rw-r--r--arch/arm/boards/phytec-som-imx6/flash-header-phytec-pcm058dl-256mb.imxcfg2
-rw-r--r--arch/arm/boards/phytec-som-imx6/flash-header-phytec-pcm058qp-1gib.imxcfg1
-rw-r--r--arch/arm/boards/phytec-som-imx6/flash-header-phytec-pfla02-1gib-1bank.imxcfg1
-rw-r--r--arch/arm/boards/phytec-som-imx6/flash-header-phytec-pfla02-1gib.imxcfg1
-rw-r--r--arch/arm/boards/phytec-som-imx6/flash-header-phytec-pfla02-2gib.imxcfg1
-rw-r--r--arch/arm/boards/phytec-som-imx6/flash-header-phytec-pfla02-4gib.imxcfg1
-rw-r--r--arch/arm/boards/phytec-som-imx6/flash-header-phytec-pfla02-512mb-1bank.imxcfg1
-rw-r--r--arch/arm/boards/phytec-som-imx6/flash-header-phytec-pfla02dl-1gib-1bank.imxcfg1
-rw-r--r--arch/arm/boards/phytec-som-imx6/flash-header-phytec-pfla02dl-1gib.imxcfg1
-rw-r--r--arch/arm/boards/phytec-som-imx6/flash-header-phytec-pfla02s-128mb-1bank.imxcfg1
-rw-r--r--arch/arm/boards/phytec-som-imx6/flash-header-phytec-pfla02s-256mb-1bank.imxcfg1
-rw-r--r--arch/arm/boards/phytec-som-imx6/flash-header-phytec-pfla02s-512mb-1bank.imxcfg1
-rw-r--r--arch/arm/boards/toradex-colibri-t20/Makefile6
-rw-r--r--arch/arm/boards/toshiba-ac100/Makefile4
-rw-r--r--arch/arm/boards/zii-imx51-rdu1/Makefile1
-rw-r--r--arch/arm/boards/zii-imx7d-dev/Makefile1
-rw-r--r--arch/arm/boards/zii-vf610-dev/Makefile1
-rw-r--r--arch/arm/cpu/Makefile2
-rw-r--r--arch/arm/cpu/dtb.c2
-rw-r--r--arch/arm/cpu/mmu-early_64.c6
-rw-r--r--arch/arm/cpu/mmu_64.c7
-rw-r--r--arch/arm/cpu/mmu_64.h9
-rw-r--r--arch/arm/cpu/psci.c104
-rw-r--r--arch/arm/cpu/start.c22
-rw-r--r--arch/arm/dts/fsl-ls1046a-rdb.dts46
-rw-r--r--arch/arm/dts/fsl-tqmls1046a-mbls10xxa.dts50
-rw-r--r--arch/arm/dts/imx6dl-phytec-pbab01.dts4
-rw-r--r--arch/arm/dts/imx6dl-phytec-phyboard-subra.dts3
-rw-r--r--arch/arm/dts/imx6dl-phytec-phycore-som-emmc.dts37
-rw-r--r--arch/arm/dts/imx6dl-phytec-phycore-som-lc-emmc.dts24
-rw-r--r--arch/arm/dts/imx6dl-phytec-phycore-som-lc-nand.dts18
-rw-r--r--arch/arm/dts/imx6dl-phytec-phycore-som-nand.dts34
-rw-r--r--arch/arm/dts/imx6q-phytec-pbaa03.dts3
-rw-r--r--arch/arm/dts/imx6q-phytec-pbab01.dts3
-rw-r--r--arch/arm/dts/imx6q-phytec-phyboard-alcor.dts3
-rw-r--r--arch/arm/dts/imx6q-phytec-phyboard-subra.dts3
-rw-r--r--arch/arm/dts/imx6q-phytec-phycore-som-emmc.dts40
-rw-r--r--arch/arm/dts/imx6q-phytec-phycore-som-nand.dts40
-rw-r--r--arch/arm/dts/imx6qdl-phytec-mira.dtsi44
-rw-r--r--arch/arm/dts/imx6qdl-phytec-phycore-som.dtsi297
-rw-r--r--arch/arm/dts/imx6qp-phytec-phycore-som-nand.dts38
-rw-r--r--arch/arm/dts/imx6s-phytec-pbab01.dts4
-rw-r--r--arch/arm/dts/imx6ul-phytec-phycore-som-nand.dts4
-rw-r--r--arch/arm/dts/imx6ull-phytec-phycore-som-emmc.dts4
-rw-r--r--arch/arm/dts/imx6ull-phytec-phycore-som-lc-nand.dts4
-rw-r--r--arch/arm/dts/imx6ull-phytec-phycore-som-nand.dts4
-rw-r--r--arch/arm/include/asm/pgtable64.h5
-rw-r--r--arch/arm/mach-imx/Kconfig22
-rw-r--r--arch/arm/mach-imx/include/mach/vf610.h2
-rw-r--r--arch/arm/mach-imx/vf610.c8
-rw-r--r--arch/arm/mach-layerscape/ppa.c19
-rw-r--r--arch/arm/mach-omap/Makefile2
-rw-r--r--arch/arm/mach-tegra/Makefile12
-rw-r--r--arch/mips/Makefile4
-rw-r--r--arch/mips/mach-ath79/art.c2
-rw-r--r--arch/x86/mach-efi/elf_x86_64_efi.lds.S7
-rw-r--r--commands/Kconfig15
-rw-r--r--commands/Makefile1
-rw-r--r--commands/gpio.c4
-rw-r--r--commands/smc.c162
-rw-r--r--common/efi/efi.c2
-rw-r--r--drivers/block/efi-block-io.c11
-rw-r--r--drivers/bus/Kconfig8
-rw-r--r--drivers/bus/Makefile1
-rw-r--r--drivers/bus/acpi.c255
-rw-r--r--drivers/clk/imx/clk-imx6ul.c3
-rw-r--r--drivers/efi/efi-device.c11
-rw-r--r--drivers/gpio/gpiolib.c47
-rw-r--r--drivers/i2c/busses/i2c-gpio.c4
-rw-r--r--drivers/mci/mci-core.c4
-rw-r--r--drivers/misc/Kconfig6
-rw-r--r--drivers/misc/Makefile1
-rw-r--r--drivers/misc/acpi-test.c61
-rw-r--r--drivers/mtd/spi-nor/spi-nor.c2
-rw-r--r--drivers/net/designware_stm32.c1
-rw-r--r--drivers/net/fsl-fman.c128
-rw-r--r--drivers/of/base.c122
-rw-r--r--drivers/pci/Kconfig7
-rw-r--r--drivers/pci/Makefile1
-rw-r--r--drivers/pci/bus.c26
-rw-r--r--drivers/pci/pci-imx6.c11
-rw-r--r--drivers/pci/pci-layerscape.c484
-rw-r--r--drivers/pci/pcie-designware-host.c16
-rw-r--r--drivers/pci/pcie-designware.c108
-rw-r--r--drivers/pci/pcie-designware.h152
-rw-r--r--drivers/serial/Kconfig8
-rw-r--r--drivers/serial/Makefile1
-rw-r--r--drivers/serial/serial_ns16550_pci.c5311
-rw-r--r--drivers/usb/gadget/f_fastboot.c2
-rw-r--r--dts/src/arm/imx6-logicpd-baseboard.dtsi4
-rw-r--r--dts/src/arm/imx6qdl-sabreauto.dtsi8
-rw-r--r--dts/src/arm/stm32mp157c-ev1.dts13
-rw-r--r--dts/src/arm/stm32mp157c.dtsi4
-rw-r--r--dts/src/arm/sun8i-a83t-tbs-a711.dts1
-rw-r--r--dts/src/arm64/freescale/fsl-ls1028a-qds.dts2
-rw-r--r--dts/src/arm64/freescale/imx8mm.dtsi6
-rw-r--r--dts/src/arm64/freescale/imx8mn.dtsi6
-rw-r--r--dts/src/arm64/freescale/imx8mq-zii-ultra.dtsi2
-rw-r--r--images/Makefile.imx587
-rw-r--r--include/acpi.h73
-rw-r--r--include/driver.h4
-rw-r--r--include/efi.h42
-rw-r--r--include/efi/efi-device.h12
-rw-r--r--include/gpio.h6
-rw-r--r--include/linux/mod_devicetable.h1
-rw-r--r--include/linux/mtd/spi-nor.h2
-rw-r--r--include/linux/pci.h34
-rw-r--r--include/of.h83
-rw-r--r--include/soc/fsl/fsl_fman.h3
-rw-r--r--scripts/imx/imx.c23
130 files changed, 7693 insertions, 1341 deletions
diff --git a/Makefile b/Makefile
index b21ad5f58d..600ca36a31 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,5 @@
VERSION = 2019
-PATCHLEVEL = 11
+PATCHLEVEL = 12
SUBLEVEL = 0
EXTRAVERSION =
NAME = None
diff --git a/README b/README
index dada97cab3..d8077d21b6 100644
--- a/README
+++ b/README
@@ -225,6 +225,21 @@ are the release rules:
people.
+Contributing
+------------
+
+For any questions regarding Barebox, send a mail to the mailing list at
+<barebox@lists.infradead.org>. The archives for this list are available
+publicly at <http://lists.infradead.org/pipermail/barebox/> and
+<https://www.mail-archive.com/barebox@lists.infradead.org/>.
+
+The same list should also be used to send patches. Barebox uses a similar
+process as the Linux kernel, so most of the Linux guide for submitting patches
+<https://www.kernel.org/doc/html/latest/process/submitting-patches.html> also
+applies to Barebox (except the step for selecting your recipient - we don't
+have a MAINTAINERS file, instead all patches go to the list).
+
+
License
-------
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 780a4707a2..372257413d 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -106,6 +106,7 @@ config ARCH_LAYERSCAPE
select COMMON_CLK
select CLKDEV_LOOKUP
select COMMON_CLK_OF_PROVIDER
+ select HW_HAS_PCI
select OFTREE
select OFDEVICE
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 13e8cee286..740b0790e7 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -141,6 +141,9 @@ CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE)
CPPFLAGS += -fdata-sections -ffunction-sections
LDFLAGS_barebox += --gc-sections
+# early code often runs at addresses we are not linked at
+CPPFLAGS += -fPIE
+
ifdef CONFIG_RELOCATABLE
LDFLAGS_barebox += -pie
else
diff --git a/arch/arm/boards/embedsky-e9/board.c b/arch/arm/boards/embedsky-e9/board.c
index 0f47677bb0..e5f92636fb 100644
--- a/arch/arm/boards/embedsky-e9/board.c
+++ b/arch/arm/boards/embedsky-e9/board.c
@@ -22,7 +22,6 @@
#include <init.h>
#include <environment.h>
#include <mach/imx6-regs.h>
-#include <gpio.h>
#include <asm/armlinux.h>
#include <generated/mach-types.h>
#include <partition.h>
@@ -102,8 +101,4 @@ static int e9_coredevices_init(void)
return 0;
}
-/*
- * Do this before the fec initializes but after our
- * gpios are available.
- */
coredevice_initcall(e9_coredevices_init);
diff --git a/arch/arm/boards/freescale-mx6-sabresd/board.c b/arch/arm/boards/freescale-mx6-sabresd/board.c
index 595b1eae0b..a5059835df 100644
--- a/arch/arm/boards/freescale-mx6-sabresd/board.c
+++ b/arch/arm/boards/freescale-mx6-sabresd/board.c
@@ -19,7 +19,6 @@
#include <init.h>
#include <environment.h>
#include <mach/imx6-regs.h>
-#include <gpio.h>
#include <asm/armlinux.h>
#include <generated/mach-types.h>
#include <partition.h>
@@ -84,8 +83,4 @@ static int sabresd_coredevices_init(void)
return 0;
}
-/*
- * Do this before the fec initializes but after our
- * gpios are available.
- */
coredevice_initcall(sabresd_coredevices_init);
diff --git a/arch/arm/boards/ls1046ardb/board.c b/arch/arm/boards/ls1046ardb/board.c
index 0846df9fad..ef68e9c7f9 100644
--- a/arch/arm/boards/ls1046ardb/board.c
+++ b/arch/arm/boards/ls1046ardb/board.c
@@ -2,13 +2,132 @@
#include <common.h>
#include <init.h>
+#include <bbu.h>
+#include <net.h>
+#include <crc.h>
+#include <fs.h>
#include <envfs.h>
+#include <libfile.h>
#include <asm/memory.h>
#include <linux/sizes.h>
#include <linux/clk.h>
#include <linux/clkdev.h>
#include <asm/system.h>
#include <mach/layerscape.h>
+#include <mach/bbu.h>
+
+#define MAX_NUM_PORTS 16
+struct nxid {
+ u8 id[4]; /* 0x00 - 0x03 EEPROM Tag 'NXID' */
+ u8 sn[12]; /* 0x04 - 0x0F Serial Number */
+ u8 errata[5]; /* 0x10 - 0x14 Errata Level */
+ u8 date[6]; /* 0x15 - 0x1a Build Date */
+ u8 res_0; /* 0x1b Reserved */
+ u32 version; /* 0x1c - 0x1f NXID Version */
+ u8 tempcal[8]; /* 0x20 - 0x27 Temperature Calibration Factors */
+ u8 tempcalsys[2]; /* 0x28 - 0x29 System Temperature Calibration Factors */
+ u8 tempcalflags; /* 0x2a Temperature Calibration Flags */
+ u8 res_1[21]; /* 0x2b - 0x3f Reserved */
+ u8 mac_count; /* 0x40 Number of MAC addresses */
+ u8 mac_flag; /* 0x41 MAC table flags */
+ u8 mac[MAX_NUM_PORTS][6]; /* 0x42 - 0xa1 MAC addresses */
+ u8 res_2[90]; /* 0xa2 - 0xfb Reserved */
+ u32 crc; /* 0xfc - 0xff CRC32 checksum */
+} __packed;
+
+static int nxid_is_valid(struct nxid *nxid)
+{
+ unsigned char id[] = { 'N', 'X', 'I', 'D' };
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(id); i++)
+ if (nxid->id[i] != id[i])
+ return false;
+ return true;
+}
+
+static struct nxid *nxp_nxid_read(const char *filename, unsigned int offset)
+{
+ struct nxid *nxid;
+ int fd, ret, i, n;
+ struct device_node *root;
+ u32 crc, crc_expected;
+
+ nxid = xzalloc(sizeof(*nxid));
+
+ fd = open(filename, O_RDONLY);
+ if (fd < 0) {
+ ret = -errno;
+ goto out;
+ }
+
+ ret = pread(fd, nxid, sizeof(*nxid), offset);
+ if (ret < 0) {
+ close(fd);
+ goto out;
+ }
+
+ if (!nxid_is_valid(nxid)) {
+ ret = -ENODEV;
+ goto out;
+ }
+
+ crc = crc32(0, nxid, 256 - 4);
+ crc_expected = be32_to_cpu(nxid->crc);
+ if (crc != crc_expected) {
+ pr_err("CRC mismatch (%08x != %08x)\n", crc, crc_expected);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ root = of_get_root_node();
+
+ i = n = 0;
+
+ /*
+ * The MAC addresses in the nxid structure are in the order of enabled
+ * network interfaces. We have to find the network interfaces by their
+ * aliases and skip assigning MAC addresses to disabled devices.
+ */
+ while (1) {
+ struct device_node *np;
+ char alias[sizeof("ethernetxxx")];
+
+ sprintf(alias, "ethernet%d", n);
+
+ np = of_find_node_by_alias(root, alias);
+ if (!np)
+ goto out;
+
+ n++;
+ if (!of_device_is_available(np))
+ continue;
+
+ of_eth_register_ethaddr(np, (char *)nxid->mac[i]);
+
+ i++;
+
+ if (i == nxid->mac_count)
+ break;
+ }
+
+ ret = 0;
+out:
+ if (ret) {
+ free(nxid);
+ nxid = ERR_PTR(ret);
+ }
+
+ return nxid;
+}
+
+static int rdb_late_init(void)
+{
+ nxp_nxid_read("/dev/eeprom", 256);
+
+ return 0;
+}
+late_initcall(rdb_late_init);
static int rdb_mem_init(void)
{
@@ -35,6 +154,9 @@ static int rdb_postcore_init(void)
defaultenv_append_directory(defaultenv_ls1046ardb);
+ ls1046a_bbu_mmc_register_handler("sd", "/dev/mmc0.barebox",
+ BBU_HANDLER_FLAG_DEFAULT);
+
return 0;
}
diff --git a/arch/arm/boards/nvidia-beaver/Makefile b/arch/arm/boards/nvidia-beaver/Makefile
index 7ade54e854..f0eb7b2de0 100644
--- a/arch/arm/boards/nvidia-beaver/Makefile
+++ b/arch/arm/boards/nvidia-beaver/Makefile
@@ -1,6 +1,4 @@
-CFLAGS_pbl-entry.o := \
- -mcpu=arm7tdmi -march=armv4t \
- -fno-tree-switch-conversion -fno-jump-tables
+CFLAGS_pbl-entry.o := -mcpu=arm7tdmi -march=armv4t
soc := tegra30
lwl-y += entry.o
obj-y += board.o
diff --git a/arch/arm/boards/nvidia-jetson-tk1/Makefile b/arch/arm/boards/nvidia-jetson-tk1/Makefile
index 16b203f9f3..5487f0289a 100644
--- a/arch/arm/boards/nvidia-jetson-tk1/Makefile
+++ b/arch/arm/boards/nvidia-jetson-tk1/Makefile
@@ -1,6 +1,4 @@
-CFLAGS_pbl-entry.o := \
- -mcpu=arm7tdmi -march=armv4t \
- -fno-tree-switch-conversion -fno-jump-tables
+CFLAGS_pbl-entry.o := -mcpu=arm7tdmi -march=armv4t
soc := tegra124
lwl-y += entry.o
obj-y += board.o
diff --git a/arch/arm/boards/phytec-som-imx6/defaultenv-physom-imx6-phycore/init/bootsource b/arch/arm/boards/phytec-som-imx6/defaultenv-physom-imx6-phycore/init/bootsource
index 515613b041..fa5f7f26c5 100644
--- a/arch/arm/boards/phytec-som-imx6/defaultenv-physom-imx6-phycore/init/bootsource
+++ b/arch/arm/boards/phytec-som-imx6/defaultenv-physom-imx6-phycore/init/bootsource
@@ -12,7 +12,7 @@ if [ $bootsource = mmc ]; then
fi
elif [ $bootsource = nand ]; then
global.boot.default="nand spi emmc mmc net"
-elif [ $bootsource = spi ]; then
+elif [ $bootsource = spi-nor ]; then
global.boot.default="spi nand emmc mmc net"
elif [ $bootsource = net ]; then
global.boot.default="net nand spi emmc mmc"
diff --git a/arch/arm/boards/phytec-som-imx6/defaultenv-physom-imx6/init/bootsource b/arch/arm/boards/phytec-som-imx6/defaultenv-physom-imx6/init/bootsource
index 3f2ff4bcc8..9c9f0ec381 100644
--- a/arch/arm/boards/phytec-som-imx6/defaultenv-physom-imx6/init/bootsource
+++ b/arch/arm/boards/phytec-som-imx6/defaultenv-physom-imx6/init/bootsource
@@ -8,7 +8,7 @@ if [ $bootsource = mmc ]; then
global.boot.default="mmc nand spi net"
elif [ $bootsource = nand ]; then
global.boot.default="nand spi mmc net"
-elif [ $bootsource = spi ]; then
+elif [ $bootsource = spi-nor ]; then
global.boot.default="spi nand mmc net"
elif [ $bootsource = net ]; then
global.boot.default="net nand spi mmc"
diff --git a/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pcaaxl3-1gib-1bank.imxcfg b/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pcaaxl3-1gib-1bank.imxcfg
index 62a24ed0df..bb4fbeb205 100644
--- a/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pcaaxl3-1gib-1bank.imxcfg
+++ b/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pcaaxl3-1gib-1bank.imxcfg
@@ -7,3 +7,4 @@
wm 32 0x021b0000 0x831a0000
#include "flash-header-phytec-pcaaxl3.h"
+#include <mach/habv4-imx6-gencsf.h>
diff --git a/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pcaaxl3-1gib.imxcfg b/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pcaaxl3-1gib.imxcfg
index bab726d147..990c34b3af 100644
--- a/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pcaaxl3-1gib.imxcfg
+++ b/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pcaaxl3-1gib.imxcfg
@@ -7,3 +7,4 @@
wm 32 0x021b0000 0xc21a0000
#include "flash-header-phytec-pcaaxl3.h"
+#include <mach/habv4-imx6-gencsf.h>
diff --git a/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pcaaxl3-2gib.imxcfg b/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pcaaxl3-2gib.imxcfg
index 512f6cbd47..7c56c24ed7 100644
--- a/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pcaaxl3-2gib.imxcfg
+++ b/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pcaaxl3-2gib.imxcfg
@@ -7,3 +7,4 @@
wm 32 0x021b0000 0xc31a0000
#include "flash-header-phytec-pcaaxl3.h"
+#include <mach/habv4-imx6-gencsf.h>
diff --git a/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pcl063-256mb.imxcfg b/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pcl063-256mb.imxcfg
index 4a827e4dfa..b93e81fb4e 100644
--- a/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pcl063-256mb.imxcfg
+++ b/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pcl063-256mb.imxcfg
@@ -7,3 +7,4 @@
wm 32 0x021B0000 0x83180000
#include "flash-header-phytec-pcl063.h"
+#include <mach/habv4-imx6-gencsf.h>
diff --git a/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pcl063-512mb.imxcfg b/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pcl063-512mb.imxcfg
index c4122d245d..26998c3fd8 100644
--- a/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pcl063-512mb.imxcfg
+++ b/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pcl063-512mb.imxcfg
@@ -7,3 +7,4 @@
wm 32 0x021B0000 0x84180000
#include "flash-header-phytec-pcl063.h"
+#include <mach/habv4-imx6-gencsf.h>
diff --git a/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pcm058-1gib.imxcfg b/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pcm058-1gib.imxcfg
index 5df46b9ff4..0042909c95 100644
--- a/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pcm058-1gib.imxcfg
+++ b/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pcm058-1gib.imxcfg
@@ -6,3 +6,4 @@
wm 32 0x021b0000 0x831A0000
#include "flash-header-phytec-pcm058.h"
+#include <mach/habv4-imx6-gencsf.h>
diff --git a/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pcm058-2gib.imxcfg b/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pcm058-2gib.imxcfg
index 54c9e41d28..8a09036992 100644
--- a/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pcm058-2gib.imxcfg
+++ b/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pcm058-2gib.imxcfg
@@ -6,3 +6,4 @@
wm 32 0x021b0000 0x841A0000
#include "flash-header-phytec-pcm058.h"
+#include <mach/habv4-imx6-gencsf.h>
diff --git a/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pcm058dl-1gib-32bit.imxcfg b/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pcm058dl-1gib-32bit.imxcfg
index bf95d0f6ae..c949f98503 100644
--- a/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pcm058dl-1gib-32bit.imxcfg
+++ b/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pcm058dl-1gib-32bit.imxcfg
@@ -6,3 +6,4 @@
wm 32 0x021b0000 0x84190000
#include "flash-header-phytec-pcm058dl.h"
+#include <mach/habv4-imx6-gencsf.h>
diff --git a/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pcm058dl-1gib.imxcfg b/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pcm058dl-1gib.imxcfg
index f047253084..3ac7e4e7ff 100644
--- a/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pcm058dl-1gib.imxcfg
+++ b/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pcm058dl-1gib.imxcfg
@@ -6,3 +6,4 @@
wm 32 0x021b0000 0x831A0000
#include "flash-header-phytec-pcm058dl.h"
+#include <mach/habv4-imx6-gencsf.h>
diff --git a/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pcm058dl-256mb.imxcfg b/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pcm058dl-256mb.imxcfg
index bf50190c78..bb8cdc9e4d 100644
--- a/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pcm058dl-256mb.imxcfg
+++ b/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pcm058dl-256mb.imxcfg
@@ -6,3 +6,5 @@
wm 32 0x021b0000 0x82190000
#include "flash-header-phytec-pcm058dl.h"
+#include <mach/habv4-imx6-gencsf.h>
+
diff --git a/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pcm058qp-1gib.imxcfg b/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pcm058qp-1gib.imxcfg
index bf85f0a19c..3ed5b346ae 100644
--- a/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pcm058qp-1gib.imxcfg
+++ b/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pcm058qp-1gib.imxcfg
@@ -6,3 +6,4 @@
wm 32 0x021b0000 0x831A0000
#include "flash-header-phytec-pcm058qp.h"
+#include <mach/habv4-imx6-gencsf.h>
diff --git a/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pfla02-1gib-1bank.imxcfg b/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pfla02-1gib-1bank.imxcfg
index 75dc982432..02f3fa7b33 100644
--- a/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pfla02-1gib-1bank.imxcfg
+++ b/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pfla02-1gib-1bank.imxcfg
@@ -6,3 +6,4 @@
wm 32 0x021b0000 0x831a0000
#include "flash-header-phytec-pfla02.h"
+#include <mach/habv4-imx6-gencsf.h>
diff --git a/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pfla02-1gib.imxcfg b/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pfla02-1gib.imxcfg
index 1f1fbe542c..dd142a20a9 100644
--- a/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pfla02-1gib.imxcfg
+++ b/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pfla02-1gib.imxcfg
@@ -6,3 +6,4 @@
wm 32 0x021b0000 0xc21a0000
#include "flash-header-phytec-pfla02.h"
+#include <mach/habv4-imx6-gencsf.h>
diff --git a/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pfla02-2gib.imxcfg b/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pfla02-2gib.imxcfg
index aa01c056be..3f9d11dc49 100644
--- a/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pfla02-2gib.imxcfg
+++ b/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pfla02-2gib.imxcfg
@@ -6,3 +6,4 @@
wm 32 0x021b0000 0xC31A0000
#include "flash-header-phytec-pfla02.h"
+#include <mach/habv4-imx6-gencsf.h>
diff --git a/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pfla02-4gib.imxcfg b/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pfla02-4gib.imxcfg
index c8d33cfacc..fdb1d15538 100644
--- a/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pfla02-4gib.imxcfg
+++ b/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pfla02-4gib.imxcfg
@@ -6,3 +6,4 @@
wm 32 0x021b0000 0xC41A0000
#include "flash-header-phytec-pfla02.h"
+#include <mach/habv4-imx6-gencsf.h>
diff --git a/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pfla02-512mb-1bank.imxcfg b/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pfla02-512mb-1bank.imxcfg
index d6bbe1f1c3..f4f150ee68 100644
--- a/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pfla02-512mb-1bank.imxcfg
+++ b/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pfla02-512mb-1bank.imxcfg
@@ -6,3 +6,4 @@
wm 32 0x021b0000 0x821a0000
#include "flash-header-phytec-pfla02.h"
+#include <mach/habv4-imx6-gencsf.h>
diff --git a/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pfla02dl-1gib-1bank.imxcfg b/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pfla02dl-1gib-1bank.imxcfg
index 7b64e5d2fd..b2a0521bbc 100644
--- a/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pfla02dl-1gib-1bank.imxcfg
+++ b/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pfla02dl-1gib-1bank.imxcfg
@@ -6,3 +6,4 @@
wm 32 0x021b0000 0x831a0000
#include "flash-header-phytec-pfla02dl.h"
+#include <mach/habv4-imx6-gencsf.h>
diff --git a/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pfla02dl-1gib.imxcfg b/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pfla02dl-1gib.imxcfg
index 04c489d7e8..e03e25eae2 100644
--- a/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pfla02dl-1gib.imxcfg
+++ b/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pfla02dl-1gib.imxcfg
@@ -6,3 +6,4 @@
wm 32 0x021b0000 0xc21a0000
#include "flash-header-phytec-pfla02dl.h"
+#include <mach/habv4-imx6-gencsf.h>
diff --git a/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pfla02s-128mb-1bank.imxcfg b/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pfla02s-128mb-1bank.imxcfg
index ebe5a968b1..58c1576219 100644
--- a/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pfla02s-128mb-1bank.imxcfg
+++ b/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pfla02s-128mb-1bank.imxcfg
@@ -6,3 +6,4 @@
wm 32 0x021b0000 0x82180000
#include "flash-header-phytec-pfla02dl.h"
+#include <mach/habv4-imx6-gencsf.h>
diff --git a/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pfla02s-256mb-1bank.imxcfg b/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pfla02s-256mb-1bank.imxcfg
index 5f1585a40b..9975e2197b 100644
--- a/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pfla02s-256mb-1bank.imxcfg
+++ b/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pfla02s-256mb-1bank.imxcfg
@@ -6,3 +6,4 @@
wm 32 0x021b0000 0x82190000
#include "flash-header-phytec-pfla02dl.h"
+#include <mach/habv4-imx6-gencsf.h>
diff --git a/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pfla02s-512mb-1bank.imxcfg b/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pfla02s-512mb-1bank.imxcfg
index 5ff3ec69d7..edc396bc5d 100644
--- a/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pfla02s-512mb-1bank.imxcfg
+++ b/arch/arm/boards/phytec-som-imx6/flash-header-phytec-pfla02s-512mb-1bank.imxcfg
@@ -6,3 +6,4 @@
wm 32 0x021b0000 0x83190000
#include "flash-header-phytec-pfla02dl.h"
+#include <mach/habv4-imx6-gencsf.h>
diff --git a/arch/arm/boards/toradex-colibri-t20/Makefile b/arch/arm/boards/toradex-colibri-t20/Makefile
index d0347f2382..644a8e5269 100644
--- a/arch/arm/boards/toradex-colibri-t20/Makefile
+++ b/arch/arm/boards/toradex-colibri-t20/Makefile
@@ -1,9 +1,7 @@
-CFLAGS_pbl-entry.o := \
- -mcpu=arm7tdmi -march=armv4t \
- -fno-tree-switch-conversion -fno-jump-tables
+CFLAGS_pbl-entry.o := -mcpu=arm7tdmi -march=armv4t
soc := tegra20
lwl-y += entry.o
obj-y += board.o
extra-y += colibri-t20_256_hsmmc.bct colibri-t20_256_v11_nand.bct \
colibri-t20_256_v12_nand.bct colibri-t20_512_hsmmc.bct \
- colibri-t20_512_v11_nand.bct colibri-t20_512_v12_nand.bct \ No newline at end of file
+ colibri-t20_512_v11_nand.bct colibri-t20_512_v12_nand.bct
diff --git a/arch/arm/boards/toshiba-ac100/Makefile b/arch/arm/boards/toshiba-ac100/Makefile
index 2b6c09e279..4ef18c0ce9 100644
--- a/arch/arm/boards/toshiba-ac100/Makefile
+++ b/arch/arm/boards/toshiba-ac100/Makefile
@@ -1,5 +1,3 @@
-CFLAGS_pbl-entry.o := \
- -mcpu=arm7tdmi -march=armv4t \
- -fno-tree-switch-conversion -fno-jump-tables
+CFLAGS_pbl-entry.o := -mcpu=arm7tdmi -march=armv4t
lwl-y += entry.o
obj-y += board.o
diff --git a/arch/arm/boards/zii-imx51-rdu1/Makefile b/arch/arm/boards/zii-imx51-rdu1/Makefile
index 604b3621be..01c7a259e9 100644
--- a/arch/arm/boards/zii-imx51-rdu1/Makefile
+++ b/arch/arm/boards/zii-imx51-rdu1/Makefile
@@ -1,3 +1,2 @@
obj-y += board.o
-CFLAGS_pbl-lowlevel.o := -fno-tree-switch-conversion -fno-jump-tables
lwl-y += lowlevel.o
diff --git a/arch/arm/boards/zii-imx7d-dev/Makefile b/arch/arm/boards/zii-imx7d-dev/Makefile
index e1baed17ba..01c7a259e9 100644
--- a/arch/arm/boards/zii-imx7d-dev/Makefile
+++ b/arch/arm/boards/zii-imx7d-dev/Makefile
@@ -1,3 +1,2 @@
-CFLAGS_pbl-lowlevel.o := -fno-tree-switch-conversion -fno-jump-tables
obj-y += board.o
lwl-y += lowlevel.o
diff --git a/arch/arm/boards/zii-vf610-dev/Makefile b/arch/arm/boards/zii-vf610-dev/Makefile
index 3c3a3f2387..1297d815e3 100644
--- a/arch/arm/boards/zii-vf610-dev/Makefile
+++ b/arch/arm/boards/zii-vf610-dev/Makefile
@@ -1,4 +1,3 @@
obj-y += board.o
-CFLAGS_pbl-lowlevel.o := -fno-tree-switch-conversion -fno-jump-tables
lwl-y += lowlevel.o
bbenv-y += defaultenv-zii-vf610-dev
diff --git a/arch/arm/cpu/Makefile b/arch/arm/cpu/Makefile
index 4b6e238497..63cf35c299 100644
--- a/arch/arm/cpu/Makefile
+++ b/arch/arm/cpu/Makefile
@@ -2,7 +2,7 @@ obj-y += cpu.o
obj-$(CONFIG_ARM_EXCEPTIONS) += exceptions$(S64).o interrupts$(S64).o
obj-$(CONFIG_MMU) += mmu$(S64).o mmu-common.o
-lwl-y += lowlevel$(S64).o
+obj-pbl-y += lowlevel$(S64).o
obj-pbl-$(CONFIG_MMU) += mmu-early$(S64).o
obj-pbl-$(CONFIG_CPU_32v7) += hyp.o
AFLAGS_hyp.o :=-Wa,-march=armv7-a -Wa,-mcpu=all
diff --git a/arch/arm/cpu/dtb.c b/arch/arm/cpu/dtb.c
index 1ba5aa415e..c43474e63b 100644
--- a/arch/arm/cpu/dtb.c
+++ b/arch/arm/cpu/dtb.c
@@ -19,8 +19,6 @@
#include <of.h>
#include <asm/barebox-arm.h>
-extern char __dtb_start[];
-
static int of_arm_init(void)
{
struct device_node *root;
diff --git a/arch/arm/cpu/mmu-early_64.c b/arch/arm/cpu/mmu-early_64.c
index f07d107e0d..94e372637a 100644
--- a/arch/arm/cpu/mmu-early_64.c
+++ b/arch/arm/cpu/mmu-early_64.c
@@ -48,6 +48,8 @@ static void create_sections(void *ttb, uint64_t virt, uint64_t phys,
}
}
+#define EARLY_BITS_PER_VA 39
+
void mmu_early_enable(unsigned long membase, unsigned long memsize,
unsigned long ttb)
{
@@ -64,8 +66,8 @@ void mmu_early_enable(unsigned long membase, unsigned long memsize,
memset((void *)ttb, 0, GRANULE_SIZE);
el = current_el();
- set_ttbr_tcr_mair(el, ttb, calc_tcr(el), MEMORY_ATTRIBUTES);
- create_sections((void *)ttb, 0, 0, 1UL << (BITS_PER_VA - 1), UNCACHED_MEM);
+ set_ttbr_tcr_mair(el, ttb, calc_tcr(el, EARLY_BITS_PER_VA), MEMORY_ATTRIBUTES);
+ create_sections((void *)ttb, 0, 0, 1UL << (EARLY_BITS_PER_VA - 1), UNCACHED_MEM);
create_sections((void *)ttb, membase, membase, memsize, CACHED_MEM);
tlb_invalidate();
isb();
diff --git a/arch/arm/cpu/mmu_64.c b/arch/arm/cpu/mmu_64.c
index b45a69661e..f7a13014af 100644
--- a/arch/arm/cpu/mmu_64.c
+++ b/arch/arm/cpu/mmu_64.c
@@ -64,7 +64,7 @@ static __maybe_unused uint64_t *find_pte(uint64_t addr)
pte = ttb;
- for (i = 1; i < 4; i++) {
+ for (i = 0; i < 4; i++) {
block_shift = level2shift(i);
idx = (addr & level2mask(i)) >> block_shift;
pte += idx;
@@ -129,7 +129,7 @@ static void create_sections(uint64_t virt, uint64_t phys, uint64_t size,
while (size) {
table = ttb;
- for (level = 1; level < 4; level++) {
+ for (level = 0; level < 4; level++) {
block_shift = level2shift(level);
idx = (addr & level2mask(level)) >> block_shift;
block_size = (1ULL << block_shift);
@@ -193,7 +193,8 @@ void __mmu_init(bool mmu_on)
ttb = create_table();
el = current_el();
- set_ttbr_tcr_mair(el, (uint64_t)ttb, calc_tcr(el), MEMORY_ATTRIBUTES);
+ set_ttbr_tcr_mair(el, (uint64_t)ttb, calc_tcr(el, BITS_PER_VA),
+ MEMORY_ATTRIBUTES);
pr_debug("ttb: 0x%p\n", ttb);
diff --git a/arch/arm/cpu/mmu_64.h b/arch/arm/cpu/mmu_64.h
index e2e125686d..a2a5477569 100644
--- a/arch/arm/cpu/mmu_64.h
+++ b/arch/arm/cpu/mmu_64.h
@@ -75,7 +75,9 @@ static inline uint64_t level2mask(int level)
{
uint64_t mask = -EINVAL;
- if (level == 1)
+ if (level == 0)
+ mask = L0_ADDR_MASK;
+ else if (level == 1)
mask = L1_ADDR_MASK;
else if (level == 2)
mask = L2_ADDR_MASK;
@@ -85,13 +87,12 @@ static inline uint64_t level2mask(int level)
return mask;
}
-static inline uint64_t calc_tcr(int el)
+static inline uint64_t calc_tcr(int el, int va_bits)
{
- u64 ips, va_bits;
+ u64 ips;
u64 tcr;
ips = 2;
- va_bits = BITS_PER_VA;
if (el == 1)
tcr = (ips << 32) | TCR_EPD1_DISABLE;
diff --git a/arch/arm/cpu/psci.c b/arch/arm/cpu/psci.c
index c19994ae9c..5a69aaa810 100644
--- a/arch/arm/cpu/psci.c
+++ b/arch/arm/cpu/psci.c
@@ -228,107 +228,3 @@ static int armv7_psci_init(void)
}
device_initcall(armv7_psci_init);
-#ifdef CONFIG_ARM_PSCI_DEBUG
-
-#include <command.h>
-#include <getopt.h>
-#include "mmu.h"
-
-static void second_entry(void)
-{
- struct arm_smccc_res res;
-
- psci_printf("2nd CPU online, now turn off again\n");
-
- arm_smccc_smc(ARM_PSCI_0_2_FN_CPU_OFF,
- 0, 0, 0, 0, 0, 0, 0, &res);
-
- psci_printf("2nd CPU still alive?\n");
-
- while (1);
-}
-
-static const char *psci_xlate_str(long err)
-{
- static char errno_string[sizeof "error 0x123456789ABCDEF0"];
-
- switch(err)
- {
- case ARM_PSCI_RET_SUCCESS:
- return "Success";
- case ARM_PSCI_RET_NOT_SUPPORTED:
- return "Operation not supported";
- case ARM_PSCI_RET_INVAL:
- return "Invalid argument";
- case ARM_PSCI_RET_DENIED:
- return "Operation not permitted";
- case ARM_PSCI_RET_ALREADY_ON:
- return "CPU already on";
- case ARM_PSCI_RET_ON_PENDING:
- return "CPU_ON in progress";
- case ARM_PSCI_RET_INTERNAL_FAILURE:
- return "Internal failure";
- case ARM_PSCI_RET_NOT_PRESENT:
- return "Trusted OS not present on core";
- case ARM_PSCI_RET_DISABLED:
- return "CPU is disabled";
- case ARM_PSCI_RET_INVALID_ADDRESS:
- return "Bad address";
- }
-
- sprintf(errno_string, "error 0x%lx", err);
- return errno_string;
-}
-
-static int do_smc(int argc, char *argv[])
-{
- long ret;
- int opt;
- struct arm_smccc_res res = {
- .a0 = 0xdeadbee0,
- .a1 = 0xdeadbee1,
- .a2 = 0xdeadbee2,
- .a3 = 0xdeadbee3,
- };
-
- if (argc < 2)
- return COMMAND_ERROR_USAGE;
-
- while ((opt = getopt(argc, argv, "nic")) > 0) {
- switch (opt) {
- case 'n':
- armv7_secure_monitor_install();
- break;
- case 'i':
- arm_smccc_smc(ARM_PSCI_0_2_FN_PSCI_VERSION,
- 0, 0, 0, 0, 0, 0, 0, &res);
- printf("found psci version %ld.%ld\n", res.a0 >> 16, res.a0 & 0xffff);
- break;
- case 'c':
- arm_smccc_smc(ARM_PSCI_0_2_FN_CPU_ON,
- 1, (unsigned long)second_entry, 0, 0, 0, 0, 0, &res);
- ret = (long)res.a0;
- printf("CPU_ON returns with: %s\n", psci_xlate_str(ret));
- if (ret)
- return COMMAND_ERROR;
- }
- }
-
-
- return 0;
-}
-BAREBOX_CMD_HELP_START(smc)
-BAREBOX_CMD_HELP_TEXT("Secure monitor code test command")
-BAREBOX_CMD_HELP_TEXT("")
-BAREBOX_CMD_HELP_TEXT("Options:")
-BAREBOX_CMD_HELP_OPT ("-n", "Install secure monitor and switch to nonsecure mode")
-BAREBOX_CMD_HELP_OPT ("-i", "Show information about installed PSCI version")
-BAREBOX_CMD_HELP_OPT ("-c", "Start secondary CPU core")
-BAREBOX_CMD_HELP_END
-
-BAREBOX_CMD_START(smc)
- .cmd = do_smc,
- BAREBOX_CMD_DESC("secure monitor test command")
- BAREBOX_CMD_GROUP(CMD_GRP_MISC)
-BAREBOX_CMD_END
-#endif
diff --git a/arch/arm/cpu/start.c b/arch/arm/cpu/start.c
index 44d974e40e..d99dd147b0 100644
--- a/arch/arm/cpu/start.c
+++ b/arch/arm/cpu/start.c
@@ -193,7 +193,17 @@ __noreturn void barebox_non_pbl_start(unsigned long membase,
uint32_t totalsize = 0;
const char *name;
- if ((unsigned long)boarddata < 8192) {
+ if (blob_is_fdt(boarddata)) {
+ totalsize = get_unaligned_be32(boarddata + 4);
+ name = "DTB";
+ } else if (blob_is_compressed_fdt(boarddata)) {
+ struct barebox_arm_boarddata_compressed_dtb *bd = boarddata;
+ totalsize = bd->datalen + sizeof(*bd);
+ name = "Compressed DTB";
+ } else if (blob_is_arm_boarddata(boarddata)) {
+ totalsize = sizeof(struct barebox_arm_boarddata);
+ name = "machine type";
+ } else if ((unsigned long)boarddata < 8192) {
struct barebox_arm_boarddata *bd;
uint32_t machine_type = (unsigned long)boarddata;
unsigned long mem = arm_mem_boarddata(membase, endmem,
@@ -205,16 +215,6 @@ __noreturn void barebox_non_pbl_start(unsigned long membase,
bd->magic = BAREBOX_ARM_BOARDDATA_MAGIC;
bd->machine = machine_type;
malloc_end = mem;
- } else if (blob_is_fdt(boarddata)) {
- totalsize = get_unaligned_be32(boarddata + 4);
- name = "DTB";
- } else if (blob_is_compressed_fdt(boarddata)) {
- struct barebox_arm_boarddata_compressed_dtb *bd = boarddata;
- totalsize = bd->datalen + sizeof(*bd);
- name = "Compressed DTB";
- } else if (blob_is_arm_boarddata(boarddata)) {
- totalsize = sizeof(struct barebox_arm_boarddata);
- name = "machine type";
}
if (totalsize) {
diff --git a/arch/arm/dts/fsl-ls1046a-rdb.dts b/arch/arm/dts/fsl-ls1046a-rdb.dts
index 842d684588..32b3f40769 100644
--- a/arch/arm/dts/fsl-ls1046a-rdb.dts
+++ b/arch/arm/dts/fsl-ls1046a-rdb.dts
@@ -5,6 +5,10 @@
#include <arm64/freescale/fsl-ls1046a-rdb.dts>
/ {
+ aliases {
+ eeprom = &eeprom;
+ };
+
chosen {
stdout-path = &duart0;
@@ -23,9 +27,14 @@
#address-cells = <1>;
#size-cells = <1>;
- environment_sd: partition@200000 {
+ partition@1000 {
+ label = "barebox";
+ reg = <0x1000 0xdf000>;
+ };
+
+ environment_sd: partition@e0000 {
label = "barebox-environment";
- reg = <0x200000 0x20000>;
+ reg = <0xe0000 0x20000>;
};
};
@@ -41,6 +50,17 @@
status = "okay";
};
+&i2c0 {
+ eeprom: eeprom@52 {
+ compatible = "atmel,24c04";
+ };
+
+ non_existent_eeprom: eeprom@53 {
+ };
+};
+
+/delete-node/ &non_existent_eeprom;
+
&fman0 {
ethernet@e0000 {
status = "disabled";
@@ -109,6 +129,14 @@
};
};
+&qflash0 {
+ compatible = "jedec,spi-nor";
+};
+
+&qflash1 {
+ compatible = "jedec,spi-nor";
+};
+
&usb0 {
dr_mode = "host";
};
@@ -122,3 +150,17 @@
&usb2 {
dr_mode = "host";
};
+
+&soc {
+ pcie1: pcie@3400000 {
+ status = "okay";
+ };
+
+ pcie2: pcie@3500000 {
+ status = "okay";
+ };
+
+ pcie3: pcie@3600000 {
+ status = "okay";
+ };
+};
diff --git a/arch/arm/dts/fsl-tqmls1046a-mbls10xxa.dts b/arch/arm/dts/fsl-tqmls1046a-mbls10xxa.dts
index f0332e3999..7b17fe2210 100644
--- a/arch/arm/dts/fsl-tqmls1046a-mbls10xxa.dts
+++ b/arch/arm/dts/fsl-tqmls1046a-mbls10xxa.dts
@@ -84,7 +84,7 @@
compatible = "fixed-partitions";
- partition@0 {
+ partition@1000 {
label = "barebox";
reg = <0x1000 0xdf000>;
};
@@ -131,6 +131,22 @@
reg = <0x20>;
gpio-controller;
#gpio-cells = <2>;
+ gpio-line-names = "sd1_3_lane_a_mux",
+ "sd1_2_lane_b_mux",
+ "sd1_0_lane_d_mux",
+ "sd2_1_lane_b_mux",
+ "sd2_3_lane_d_mux1",
+ "sd2_3_lane_d_mux2",
+ "sd_mux_shdn",
+ "sd1_ref_clk2_sel",
+ "mpcie1_disable_n",
+ "mpcie1_wake_n",
+ "mpcie2_disable_n",
+ "mpcie2_wake_n",
+ "prsnt_n",
+ "pcie_pwr_en",
+ "dcdc_pwr_en",
+ "dcdc_pgood_1v8";
};
gpioexp2: pca9555@21 {
@@ -138,6 +154,22 @@
reg = <0x21>;
gpio-controller;
#gpio-cells = <2>;
+ gpio-line-names = "xfi1_tx_dis",
+ "xfi1_tx_fault",
+ "xfi1_moddef_det",
+ "xfi1_rx_loss",
+ "retimer1_loss",
+ "xfi1_ensmb",
+ "qsgmii1_clk_sel0",
+ "qsgmii_phy1_config3",
+ "xfi2_tx_fault",
+ "xfi2_tx_dis",
+ "xfi2_moddef_det",
+ "xfi2_rx_loss",
+ "retimer2_loss",
+ "xfi2_ensmb",
+ "qsgmii2_clk_sel0",
+ "qsgmii_phy2_config3";
};
gpioexp3: pca9555@22 {
@@ -145,6 +177,22 @@
reg = <0x22>;
gpio-controller;
#gpio-cells = <2>;
+ gpio-line-names = "ec1_phy_pwdn",
+ "ec2_phy_pwdn",
+ "usb_c_pwron",
+ "usb_en_oc_3v3_n",
+ "usb_h_grst_n",
+ "gpio_button0",
+ "gpio_button1",
+ "sda_pwr_en",
+ "qsgmii_phy1_int_n",
+ "qsgmii_phy2_int_n",
+ "spi_clko_sof",
+ "spi_int",
+ "can_sel",
+ "led_n",
+ "pcie_rst_3v3_n",
+ "pcie_wake_3v3_n";
};
};
diff --git a/arch/arm/dts/imx6dl-phytec-pbab01.dts b/arch/arm/dts/imx6dl-phytec-pbab01.dts
index d10fbf668f..4fe3c308e7 100644
--- a/arch/arm/dts/imx6dl-phytec-pbab01.dts
+++ b/arch/arm/dts/imx6dl-phytec-pbab01.dts
@@ -10,7 +10,9 @@
*/
/dts-v1/;
-
+#ifdef CONFIG_BOOTM_FITIMAGE_PUBKEY
+#include CONFIG_BOOTM_FITIMAGE_PUBKEY
+#endif
#include "imx6dl-phytec-pfla02.dtsi"
#include "imx6qdl-phytec-pbab01.dtsi"
diff --git a/arch/arm/dts/imx6dl-phytec-phyboard-subra.dts b/arch/arm/dts/imx6dl-phytec-phyboard-subra.dts
index 3d1069a965..430745f100 100644
--- a/arch/arm/dts/imx6dl-phytec-phyboard-subra.dts
+++ b/arch/arm/dts/imx6dl-phytec-phyboard-subra.dts
@@ -10,6 +10,9 @@
*/
/dts-v1/;
+#ifdef CONFIG_BOOTM_FITIMAGE_PUBKEY
+#include CONFIG_BOOTM_FITIMAGE_PUBKEY
+#endif
#include "imx6s-phytec-pfla02.dtsi"
#include "imx6qdl-phytec-phyboard-subra.dtsi"
diff --git a/arch/arm/dts/imx6dl-phytec-phycore-som-emmc.dts b/arch/arm/dts/imx6dl-phytec-phycore-som-emmc.dts
index 21cbb5f944..03df77f41d 100644
--- a/arch/arm/dts/imx6dl-phytec-phycore-som-emmc.dts
+++ b/arch/arm/dts/imx6dl-phytec-phycore-som-emmc.dts
@@ -1,31 +1,24 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later)
/*
* Copyright (C) 2015 PHYTEC Messtechnik GmbH,
* Author: Stefan Christ <s.christ@phytec.de>
- *
- * The code contained herein is licensed under the GNU General Public
- * License. You may obtain a copy of the GNU General Public License
- * Version 2 or later at the following locations:
- *
- * http://www.opensource.org/licenses/gpl-license.html
- * http://www.gnu.org/copyleft/gpl.html
*/
/dts-v1/;
-
+#ifdef CONFIG_BOOTM_FITIMAGE_PUBKEY
+#include CONFIG_BOOTM_FITIMAGE_PUBKEY
+#endif
#include <arm/imx6dl.dtsi>
#include "imx6dl.dtsi"
#include "imx6qdl-phytec-phycore-som.dtsi"
+#include "imx6qdl-phytec-mira.dtsi"
#include "imx6qdl-phytec-state.dtsi"
/ {
- model = "Phytec phyCORE-i.MX6 DualLite/SOLO with eMMC";
+ model = "PHYTEC phyCORE-i.MX6 DualLite/SOLO with eMMC";
compatible = "phytec,imx6dl-pcm058-emmc", "fsl,imx6dl";
};
-&ecspi1 {
- status = "okay";
-};
-
&eeprom {
status = "okay";
};
@@ -38,7 +31,7 @@
status = "okay";
};
-&flash {
+&m25p80 {
status = "okay";
};
@@ -52,22 +45,6 @@
&usdhc1 {
status = "okay";
-
- partitions {
- compatible = "fixed-partitions";
- #address-cells = <1>;
- #size-cells = <1>;
-
- partition@0 {
- label = "barebox";
- reg = <0x0 0xe0000>;
- };
-
- partition@e0000 {
- label = "barebox-environment";
- reg = <0xe0000 0x20000>;
- };
- };
};
&usdhc4 {
diff --git a/arch/arm/dts/imx6dl-phytec-phycore-som-lc-emmc.dts b/arch/arm/dts/imx6dl-phytec-phycore-som-lc-emmc.dts
index b8efb95ee0..0ef6f96bbe 100644
--- a/arch/arm/dts/imx6dl-phytec-phycore-som-lc-emmc.dts
+++ b/arch/arm/dts/imx6dl-phytec-phycore-som-lc-emmc.dts
@@ -5,10 +5,13 @@
*/
/dts-v1/;
-
+#ifdef CONFIG_BOOTM_FITIMAGE_PUBKEY
+#include CONFIG_BOOTM_FITIMAGE_PUBKEY
+#endif
#include <arm/imx6dl.dtsi>
#include "imx6dl.dtsi"
#include "imx6qdl-phytec-phycore-som.dtsi"
+#include "imx6qdl-phytec-mira.dtsi"
#include "imx6qdl-phytec-state.dtsi"
/ {
@@ -16,10 +19,6 @@
compatible = "phytec,imx6dl-pcm058-emmc", "fsl,imx6dl";
};
-&ecspi1 {
- status = "okay";
-};
-
&eeprom {
status = "okay";
};
@@ -32,7 +31,7 @@
status = "okay";
};
-&flash {
+&m25p80 {
status = "okay";
};
@@ -46,19 +45,6 @@
&usdhc1 {
status = "okay";
-
- #address-cells = <1>;
- #size-cells = <1>;
-
- partition@0 {
- label = "barebox";
- reg = <0x0 0xe0000>;
- };
-
- partition@e0000 {
- label = "barebox-environment";
- reg = <0xe0000 0x20000>;
- };
};
&usdhc4 {
diff --git a/arch/arm/dts/imx6dl-phytec-phycore-som-lc-nand.dts b/arch/arm/dts/imx6dl-phytec-phycore-som-lc-nand.dts
index 4d38d1698a..0a4c2e6fb6 100644
--- a/arch/arm/dts/imx6dl-phytec-phycore-som-lc-nand.dts
+++ b/arch/arm/dts/imx6dl-phytec-phycore-som-lc-nand.dts
@@ -5,10 +5,13 @@
*/
/dts-v1/;
-
+#ifdef CONFIG_BOOTM_FITIMAGE_PUBKEY
+#include CONFIG_BOOTM_FITIMAGE_PUBKEY
+#endif
#include <arm/imx6dl.dtsi>
#include "imx6dl.dtsi"
#include "imx6qdl-phytec-phycore-som.dtsi"
+#include "imx6qdl-phytec-mira.dtsi"
#include "imx6qdl-phytec-state.dtsi"
/ {
@@ -42,17 +45,4 @@
&usdhc1 {
status = "okay";
-
- #address-cells = <1>;
- #size-cells = <1>;
-
- partition@0 {
- label = "barebox";
- reg = <0x0 0xe0000>;
- };
-
- partition@e0000 {
- label = "barebox-environment";
- reg = <0xe0000 0x20000>;
- };
};
diff --git a/arch/arm/dts/imx6dl-phytec-phycore-som-nand.dts b/arch/arm/dts/imx6dl-phytec-phycore-som-nand.dts
index 3ad3723d28..fa518286c3 100644
--- a/arch/arm/dts/imx6dl-phytec-phycore-som-nand.dts
+++ b/arch/arm/dts/imx6dl-phytec-phycore-som-nand.dts
@@ -1,23 +1,21 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later)
/*
- * Copyright 2015 Christian Hemp, Phytec Messtechnik GmbH
- *
- * The code contained herein is licensed under the GNU General Public
- * License. You may obtain a copy of the GNU General Public License
- * Version 2 or later at the following locations:
- *
- * http://www.opensource.org/licenses/gpl-license.html
- * http://www.gnu.org/copyleft/gpl.html
+ * Copyright (C) 2015 PHYTEC Messtechnik GmbH
+ * Author: Christian Hemp <c.hemp@phytec.de>
*/
/dts-v1/;
-
+#ifdef CONFIG_BOOTM_FITIMAGE_PUBKEY
+#include CONFIG_BOOTM_FITIMAGE_PUBKEY
+#endif
#include <arm/imx6dl.dtsi>
#include "imx6dl.dtsi"
#include "imx6qdl-phytec-phycore-som.dtsi"
+#include "imx6qdl-phytec-mira.dtsi"
#include "imx6qdl-phytec-state.dtsi"
/ {
- model = "Phytec phyCORE-i.MX6 Duallite/SOLO with NAND";
+ model = "PHYTEC phyCORE-i.MX6 Duallite/SOLO with NAND";
compatible = "phytec,imx6dl-pcm058-nand", "fsl,imx6dl";
};
@@ -47,20 +45,4 @@
&usdhc1 {
status = "okay";
-
- partitions {
- compatible = "fixed-partitions";
- #address-cells = <1>;
- #size-cells = <1>;
-
- partition@0 {
- label = "barebox";
- reg = <0x0 0xe0000>;
- };
-
- partition@e0000 {
- label = "barebox-environment";
- reg = <0xe0000 0x20000>;
- };
- };
};
diff --git a/arch/arm/dts/imx6q-phytec-pbaa03.dts b/arch/arm/dts/imx6q-phytec-pbaa03.dts
index 4724a02ad7..5216a2dfe3 100644
--- a/arch/arm/dts/imx6q-phytec-pbaa03.dts
+++ b/arch/arm/dts/imx6q-phytec-pbaa03.dts
@@ -10,6 +10,9 @@
*/
/dts-v1/;
+#ifdef CONFIG_BOOTM_FITIMAGE_PUBKEY
+#include CONFIG_BOOTM_FITIMAGE_PUBKEY
+#endif
#include "imx6q-phytec-pcaaxl3.dtsi"
/ {
diff --git a/arch/arm/dts/imx6q-phytec-pbab01.dts b/arch/arm/dts/imx6q-phytec-pbab01.dts
index 2f816dd1ac..91562a2ffe 100644
--- a/arch/arm/dts/imx6q-phytec-pbab01.dts
+++ b/arch/arm/dts/imx6q-phytec-pbab01.dts
@@ -10,6 +10,9 @@
*/
/dts-v1/;
+#ifdef CONFIG_BOOTM_FITIMAGE_PUBKEY
+#include CONFIG_BOOTM_FITIMAGE_PUBKEY
+#endif
#include "imx6q-phytec-pfla02.dtsi"
#include "imx6qdl-phytec-pbab01.dtsi"
diff --git a/arch/arm/dts/imx6q-phytec-phyboard-alcor.dts b/arch/arm/dts/imx6q-phytec-phyboard-alcor.dts
index 1c4a78552d..d97c7f15c9 100644
--- a/arch/arm/dts/imx6q-phytec-phyboard-alcor.dts
+++ b/arch/arm/dts/imx6q-phytec-phyboard-alcor.dts
@@ -10,6 +10,9 @@
*/
/dts-v1/;
+#ifdef CONFIG_BOOTM_FITIMAGE_PUBKEY
+#include CONFIG_BOOTM_FITIMAGE_PUBKEY
+#endif
#include "imx6q-phytec-pfla02.dtsi"
/ {
diff --git a/arch/arm/dts/imx6q-phytec-phyboard-subra.dts b/arch/arm/dts/imx6q-phytec-phyboard-subra.dts
index 561e985604..4986111036 100644
--- a/arch/arm/dts/imx6q-phytec-phyboard-subra.dts
+++ b/arch/arm/dts/imx6q-phytec-phyboard-subra.dts
@@ -11,6 +11,9 @@
*/
/dts-v1/;
+#ifdef CONFIG_BOOTM_FITIMAGE_PUBKEY
+#include CONFIG_BOOTM_FITIMAGE_PUBKEY
+#endif
#include "imx6q-phytec-pfla02.dtsi"
#include "imx6qdl-phytec-phyboard-subra.dtsi"
diff --git a/arch/arm/dts/imx6q-phytec-phycore-som-emmc.dts b/arch/arm/dts/imx6q-phytec-phycore-som-emmc.dts
index 7a86d5b94d..2414befd35 100644
--- a/arch/arm/dts/imx6q-phytec-phycore-som-emmc.dts
+++ b/arch/arm/dts/imx6q-phytec-phycore-som-emmc.dts
@@ -1,30 +1,24 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later)
/*
- * Copyright 2015 Christian Hemp, Phytec Messtechnik GmbH
- *
- * The code contained herein is licensed under the GNU General Public
- * License. You may obtain a copy of the GNU General Public License
- * Version 2 or later at the following locations:
- *
- * http://www.opensource.org/licenses/gpl-license.html
- * http://www.gnu.org/copyleft/gpl.html
+ * Copyright (C) 2015 PHYTEC Messtechnik GmbH
+ * Author: Christian Hemp <c.hemp@phytec.de>
*/
/dts-v1/;
-
+#ifdef CONFIG_BOOTM_FITIMAGE_PUBKEY
+#include CONFIG_BOOTM_FITIMAGE_PUBKEY
+#endif
#include <arm/imx6q.dtsi>
#include "imx6q.dtsi"
#include "imx6qdl-phytec-phycore-som.dtsi"
+#include "imx6qdl-phytec-mira.dtsi"
#include "imx6qdl-phytec-state.dtsi"
/ {
- model = "Phytec phyCORE-i.MX6 Quad with eMMC";
+ model = "PHYTEC phyCORE-i.MX6 Quad with eMMC";
compatible = "phytec,imx6q-pcm058-emmc", "fsl,imx6q";
};
-&ecspi1 {
- status = "okay";
-};
-
&eeprom {
status = "okay";
};
@@ -37,7 +31,7 @@
status = "okay";
};
-&flash {
+&m25p80 {
status = "okay";
};
@@ -51,22 +45,6 @@
&usdhc1 {
status = "okay";
-
- partitions {
- compatible = "fixed-partitions";
- #address-cells = <1>;
- #size-cells = <1>;
-
- partition@0 {
- label = "barebox";
- reg = <0x0 0xe0000>;
- };
-
- partition@e0000 {
- label = "barebox-environment";
- reg = <0xe0000 0x20000>;
- };
- };
};
&usdhc4 {
diff --git a/arch/arm/dts/imx6q-phytec-phycore-som-nand.dts b/arch/arm/dts/imx6q-phytec-phycore-som-nand.dts
index 96d1de224c..864dc190bc 100644
--- a/arch/arm/dts/imx6q-phytec-phycore-som-nand.dts
+++ b/arch/arm/dts/imx6q-phytec-phycore-som-nand.dts
@@ -1,31 +1,25 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later)
/*
- * Copyright 2015 Christian Hemp, Phytec Messtechnik GmbH
- *
- * The code contained herein is licensed under the GNU General Public
- * License. You may obtain a copy of the GNU General Public License
- * Version 2 or later at the following locations:
- *
- * http://www.opensource.org/licenses/gpl-license.html
- * http://www.gnu.org/copyleft/gpl.html
+ * Copyright (C) 2015 PHYTEC Messtechnik GmbH
+ * Author: Christian Hemp <c.hemp@phytec.de>
*/
/dts-v1/;
-
+#ifdef CONFIG_BOOTM_FITIMAGE_PUBKEY
+#include CONFIG_BOOTM_FITIMAGE_PUBKEY
+#endif
#include <arm/imx6q.dtsi>
#include "imx6q.dtsi"
#include "imx6qdl-phytec-phycore-som.dtsi"
+#include "imx6qdl-phytec-mira.dtsi"
#include "imx6qdl-phytec-state.dtsi"
/ {
- model = "Phytec phyCORE-i.MX6 Quad with NAND";
+ model = "PHYTEC phyCORE-i.MX6 Quad with NAND";
compatible = "phytec,imx6q-pcm058-nand", "fsl,imx6q";
};
-&ecspi1 {
- status = "okay";
-};
-
&eeprom {
status = "okay";
};
@@ -38,7 +32,7 @@
status = "okay";
};
-&flash {
+&m25p80 {
status = "okay";
};
@@ -56,20 +50,4 @@
&usdhc1 {
status = "okay";
-
- partitions {
- compatible = "fixed-partitions";
- #address-cells = <1>;
- #size-cells = <1>;
-
- partition@0 {
- label = "barebox";
- reg = <0x0 0xe0000>;
- };
-
- partition@e0000 {
- label = "barebox-environment";
- reg = <0xe0000 0x20000>;
- };
- };
};
diff --git a/arch/arm/dts/imx6qdl-phytec-mira.dtsi b/arch/arm/dts/imx6qdl-phytec-mira.dtsi
new file mode 100644
index 0000000000..49cbd25fc3
--- /dev/null
+++ b/arch/arm/dts/imx6qdl-phytec-mira.dtsi
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT)
+/*
+ * Copyright (C) 2019 PHYTEC Messtechnik GmbH
+ * Author: Stefan Riedmueller <s.riedmueller@phytec.de>
+ */
+
+#include <arm/imx6qdl-phytec-mira.dtsi>
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ chosen {
+ stdout-path = &uart2;
+ };
+};
+
+&backlight {
+ status = "disabled";
+};
+
+&ldb {
+ status = "disabled";
+};
+
+&pwm1 {
+ status = "disabled";
+};
+
+&usdhc1 {
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "barebox";
+ reg = <0x0 0xe0000>;
+ };
+
+ partition@e0000 {
+ label = "barebox-environment";
+ reg = <0xe0000 0x20000>;
+ };
+ };
+};
diff --git a/arch/arm/dts/imx6qdl-phytec-phycore-som.dtsi b/arch/arm/dts/imx6qdl-phytec-phycore-som.dtsi
index 1d39368165..69f252b423 100644
--- a/arch/arm/dts/imx6qdl-phytec-phycore-som.dtsi
+++ b/arch/arm/dts/imx6qdl-phytec-phycore-som.dtsi
@@ -1,20 +1,14 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later)
/*
- * Copyright 2015 Christian Hemp, Phytec Messtechnik GmbH
- *
- * The code contained herein is licensed under the GNU General Public
- * License. You may obtain a copy of the GNU General Public License
- * Version 2 or later at the following locations:
- *
- * http://www.opensource.org/licenses/gpl-license.html
- * http://www.gnu.org/copyleft/gpl.html
+ * Copyright (C) 2015 PHYTEC Messtechnik GmbH
+ * Author: Christian Hemp <c.hemp@phytec.de>
*/
+#include <arm/imx6qdl-phytec-phycore-som.dtsi>
#include <dt-bindings/gpio/gpio.h>
/ {
chosen {
- stdout-path = &uart2;
-
environment-sd1 {
compatible = "barebox,environment";
device-path = &usdhc1, "partname:barebox-environment";
@@ -35,102 +29,20 @@
environment-spinor {
compatible = "barebox,environment";
- device-path = &flash, "partname:barebox-environment";
+ device-path = &m25p80, "partname:barebox-environment";
status = "disabled";
};
};
- reg_usbh1_vbus: regulator-usbh1 {
- compatible = "regulator-fixed";
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_usbh1_vbus>;
- regulator-name = "usbh1_vbus";
- regulator-min-microvolt = <5000000>;
- regulator-max-microvolt = <5000000>;
- gpio = <&gpio2 18 GPIO_ACTIVE_HIGH>;
- enable-active-high;
- };
-
- reg_usbotg_vbus: regulator-usbotg {
- compatible = "regulator-fixed";
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_usbotg_vbus>;
- regulator-name = "usbotg_vbus";
- regulator-min-microvolt = <5000000>;
- regulator-max-microvolt = <5000000>;
- gpio = <&gpio2 19 GPIO_ACTIVE_HIGH>;
- enable-active-high;
- };
-};
-
-&ecspi1 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_ecspi1>;
- fsl,spi-num-chipselects = <1>;
- cs-gpios = <&gpio3 19 0>;
- status = "disabled";
-
- flash: flash@0 {
- compatible = "jedec,spi-nor";
- spi-max-frequency = <20000000>;
- reg = <0>;
- status = "disabled";
-
- partitions {
- compatible = "fixed-partitions";
- #address-cells = <1>;
- #size-cells = <1>;
-
- partition@0 {
- label = "barebox";
- reg = <0x0 0x100000>;
- };
-
- partition@100000 {
- label = "barebox-environment";
- reg = <0x100000 0x20000>;
- };
-
- partition@120000 {
- label = "oftree";
- reg = <0x120000 0x20000>;
- };
-
- partition@140000 {
- label = "kernel";
- reg = <0x140000 0x0>;
- };
- };
- };
+ /delete-node/ memory@10000000;
};
&fec {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_enet>;
- phy-handle = <&ethphy>;
- phy-mode = "rgmii";
- phy-reset-gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
+ /delete-property/ phy-supply;
phy-reset-duration = <10>; /* in msecs */
- status = "disabled";
-
- mdio {
- #address-cells = <1>;
- #size-cells = <0>;
-
- ethphy: ethernet-phy@3 {
- reg = <3>;
- txc-skew-ps = <1680>;
- rxc-skew-ps = <1860>;
- };
- };
};
&gpmi {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_gpmi_nand>;
- nand-on-flash-bbt;
- status = "disabled";
-
partitions {
compatible = "fixed-partitions";
#address-cells = <1>;
@@ -154,141 +66,44 @@
};
&i2c3 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_i2c3>;
- clock-frequency = <400000>;
- status = "okay";
-
eeprom: eeprom@50 {
status = "disabled";
- compatible = "24c32";
- reg = <0x50>;
};
pmic@58 {
- compatible = "dlg,da9062";
- reg = <0x58>;
- status = "okay";
-
watchdog-priority = <500>;
restart-priority = <500>;
reset-source-priority = <500>;
};
};
-&iomuxc {
- pinctrl_ecspi1: ecspi1grp {
- fsl,pins = <
- MX6QDL_PAD_EIM_D16__ECSPI1_SCLK 0x100b1
- MX6QDL_PAD_EIM_D17__ECSPI1_MISO 0x100b1
- MX6QDL_PAD_EIM_D18__ECSPI1_MOSI 0x100b1
- MX6QDL_PAD_EIM_D19__GPIO3_IO19 0x80000000
- >;
- };
-
- pinctrl_enet: enetgrp {
- fsl,pins = <
- MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
- MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
- MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
- MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
- MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
- MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
- MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
- MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
- MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
- MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
- MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
- MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
- MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
- MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
- MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
- MX6QDL_PAD_ENET_TX_EN__ENET_TX_EN 0x1b0b0
- MX6QDL_PAD_SD2_DAT1__GPIO1_IO14 0x80000000
- >;
- };
-
- pinctrl_gpmi_nand: gpmigrp {
- fsl,pins = <
- MX6QDL_PAD_NANDF_CLE__NAND_CLE 0xb0b1
- MX6QDL_PAD_NANDF_ALE__NAND_ALE 0xb0b1
- MX6QDL_PAD_NANDF_WP_B__NAND_WP_B 0xb0b1
- MX6QDL_PAD_NANDF_RB0__NAND_READY_B 0xb000
- MX6QDL_PAD_NANDF_CS0__NAND_CE0_B 0xb0b1
- MX6QDL_PAD_NANDF_CS1__NAND_CE1_B 0xb0b1
- MX6QDL_PAD_NANDF_CS2__NAND_CE2_B 0xb0b1
- MX6QDL_PAD_NANDF_CS3__NAND_CE3_B 0xb0b1
- MX6QDL_PAD_SD4_CMD__NAND_RE_B 0xb0b1
- MX6QDL_PAD_SD4_CLK__NAND_WE_B 0xb0b1
- MX6QDL_PAD_NANDF_D0__NAND_DATA00 0xb0b1
- MX6QDL_PAD_NANDF_D1__NAND_DATA01 0xb0b1
- MX6QDL_PAD_NANDF_D2__NAND_DATA02 0xb0b1
- MX6QDL_PAD_NANDF_D3__NAND_DATA03 0xb0b1
- MX6QDL_PAD_NANDF_D4__NAND_DATA04 0xb0b1
- MX6QDL_PAD_NANDF_D5__NAND_DATA05 0xb0b1
- MX6QDL_PAD_NANDF_D6__NAND_DATA06 0xb0b1
- MX6QDL_PAD_NANDF_D7__NAND_DATA07 0xb0b1
- MX6QDL_PAD_SD4_DAT0__NAND_DQS 0x00b1
- >;
- };
-
- pinctrl_i2c3: i2c3grp {
- fsl,pins = <
- MX6QDL_PAD_GPIO_6__I2C3_SDA 0x4001b8b1
- MX6QDL_PAD_GPIO_5__I2C3_SCL 0x4001b8b1
- >;
- };
-
- pinctrl_uart2: uart2grp {
- fsl,pins = <
- MX6QDL_PAD_EIM_D26__UART2_TX_DATA 0x1b0b1
- MX6QDL_PAD_EIM_D27__UART2_RX_DATA 0x1b0b1
- >;
- };
+&m25p80 {
+ status = "disabled";
- pinctrl_usbh1_vbus: usbh1vbusgrp {
- fsl,pins = <
- MX6QDL_PAD_EIM_A20__GPIO2_IO18 0xb0b1
- >;
- };
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
- pinctrl_usbotg: usbotggrp {
- fsl,pins = <
- MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059
- >;
- };
+ partition@0 {
+ label = "barebox";
+ reg = <0x0 0x100000>;
+ };
- pinctrl_usbotg_vbus: usbotgvbusgrp {
- fsl,pins = <
- MX6QDL_PAD_EIM_A19__GPIO2_IO19 0xb0b1
- >;
- };
+ partition@100000 {
+ label = "barebox-environment";
+ reg = <0x100000 0x20000>;
+ };
- pinctrl_usdhc1: usdhc1grp {
- fsl,pins = <
- MX6QDL_PAD_SD1_CMD__SD1_CMD 0x170f9
- MX6QDL_PAD_SD1_CLK__SD1_CLK 0x100f9
- MX6QDL_PAD_SD1_DAT0__SD1_DATA0 0x170f9
- MX6QDL_PAD_SD1_DAT1__SD1_DATA1 0x170f9
- MX6QDL_PAD_SD1_DAT2__SD1_DATA2 0x170f9
- MX6QDL_PAD_SD1_DAT3__SD1_DATA3 0x170f9
- MX6QDL_PAD_EIM_BCLK__GPIO6_IO31 0x80000000 /* CD */
- >;
- };
+ partition@120000 {
+ label = "oftree";
+ reg = <0x120000 0x20000>;
+ };
- pinctrl_usdhc4: usdhc4grp {
- fsl,pins = <
- MX6QDL_PAD_SD4_CMD__SD4_CMD 0x17059
- MX6QDL_PAD_SD4_CLK__SD4_CLK 0x10059
- MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x17059
- MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x17059
- MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x17059
- MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x17059
- MX6QDL_PAD_SD4_DAT4__SD4_DATA4 0x17059
- MX6QDL_PAD_SD4_DAT5__SD4_DATA5 0x17059
- MX6QDL_PAD_SD4_DAT6__SD4_DATA6 0x17059
- MX6QDL_PAD_SD4_DAT7__SD4_DATA7 0x17059
- >;
+ partition@140000 {
+ label = "kernel";
+ reg = <0x140000 0x0>;
+ };
};
};
@@ -296,50 +111,20 @@
barebox,provide-mac-address = <&fec 0x620>;
};
-&uart2 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_uart2>;
- status = "okay";
-};
-
-&usbh1 {
- vbus-supply = <&reg_usbh1_vbus>;
- disable-over-current;
- status = "disabled";
-};
-
-&usbotg {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_usbotg>;
- vbus-supply = <&reg_usbotg_vbus>;
- disable-over-current;
- status = "disabled";
-};
-
-&usdhc1 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_usdhc1>;
- cd-gpios = <&gpio6 31 0>;
- status = "disabled";
-};
-
&usdhc4 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_usdhc4>;
- bus-width = <8>;
- non-removable;
- status = "disabled";
-
- #address-cells = <1>;
- #size-cells = <1>;
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
- partition@0 {
- label = "barebox";
- reg = <0x0 0xe0000>;
- };
+ partition@0 {
+ label = "barebox";
+ reg = <0x0 0xe0000>;
+ };
- partition@e0000 {
- label = "barebox-environment";
- reg = <0xe0000 0x20000>;
+ partition@e0000 {
+ label = "barebox-environment";
+ reg = <0xe0000 0x20000>;
+ };
};
};
diff --git a/arch/arm/dts/imx6qp-phytec-phycore-som-nand.dts b/arch/arm/dts/imx6qp-phytec-phycore-som-nand.dts
index 437457ce75..378806df53 100644
--- a/arch/arm/dts/imx6qp-phytec-phycore-som-nand.dts
+++ b/arch/arm/dts/imx6qp-phytec-phycore-som-nand.dts
@@ -1,28 +1,22 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later)
/*
- * Copyright (C) 2016 Phytec Messtechnik GmbH
+ * Copyright (C) 2016 PHYTEC Messtechnik GmbH
* Author: Christian Hemp <c.hemp@phytec.de>
- *
- * The code contained herein is licensed under the GNU General Public
- * License. You may obtain a copy of the GNU General Public License
- * Version 2 or later at the following locations:
- *
- * http://www.opensource.org/licenses/gpl-license.html
- * http://www.gnu.org/copyleft/gpl.html
*/
/dts-v1/;
+#ifdef CONFIG_BOOTM_FITIMAGE_PUBKEY
+#include CONFIG_BOOTM_FITIMAGE_PUBKEY
+#endif
#include <arm/imx6qp.dtsi>
#include "imx6qdl-phytec-phycore-som.dtsi"
+#include "imx6qdl-phytec-mira.dtsi"
/ {
- model = "Phytec phyCORE-i.MX6 Quad with NAND";
+ model = "PHYTEC phyCORE-i.MX6 QuadPlus with NAND";
compatible = "phytec,imx6qp-pcm058-nand", "fsl,imx6qp";
};
-&ecspi1 {
- status = "okay";
-};
-
&eeprom {
status = "okay";
};
@@ -35,7 +29,7 @@
status = "okay";
};
-&flash {
+&m25p80 {
status = "okay";
};
@@ -53,20 +47,4 @@
&usdhc1 {
status = "okay";
-
- partitions {
- compatible = "fixed-partitions";
- #address-cells = <1>;
- #size-cells = <1>;
-
- partition@0 {
- label = "barebox";
- reg = <0x0 0xe0000>;
- };
-
- partition@e0000 {
- label = "barebox-environment";
- reg = <0xe0000 0x20000>;
- };
- };
};
diff --git a/arch/arm/dts/imx6s-phytec-pbab01.dts b/arch/arm/dts/imx6s-phytec-pbab01.dts
index 1cb5a237a3..516d20f776 100644
--- a/arch/arm/dts/imx6s-phytec-pbab01.dts
+++ b/arch/arm/dts/imx6s-phytec-pbab01.dts
@@ -10,7 +10,9 @@
*/
/dts-v1/;
-
+#ifdef CONFIG_BOOTM_FITIMAGE_PUBKEY
+#include CONFIG_BOOTM_FITIMAGE_PUBKEY
+#endif
#include "imx6s-phytec-pfla02.dtsi"
#include "imx6qdl-phytec-pbab01.dtsi"
diff --git a/arch/arm/dts/imx6ul-phytec-phycore-som-nand.dts b/arch/arm/dts/imx6ul-phytec-phycore-som-nand.dts
index 67478e26dc..c8d43c5e25 100644
--- a/arch/arm/dts/imx6ul-phytec-phycore-som-nand.dts
+++ b/arch/arm/dts/imx6ul-phytec-phycore-som-nand.dts
@@ -5,7 +5,9 @@
*/
/dts-v1/;
-
+#ifdef CONFIG_BOOTM_FITIMAGE_PUBKEY
+#include CONFIG_BOOTM_FITIMAGE_PUBKEY
+#endif
#include <arm/imx6ul.dtsi>
#include "imx6ul-phytec-phycore-som.dtsi"
#include "imx6ul-phytec-state.dtsi"
diff --git a/arch/arm/dts/imx6ull-phytec-phycore-som-emmc.dts b/arch/arm/dts/imx6ull-phytec-phycore-som-emmc.dts
index aa162cc42d..2201b4c1b2 100644
--- a/arch/arm/dts/imx6ull-phytec-phycore-som-emmc.dts
+++ b/arch/arm/dts/imx6ull-phytec-phycore-som-emmc.dts
@@ -5,7 +5,9 @@
*/
/dts-v1/;
-
+#ifdef CONFIG_BOOTM_FITIMAGE_PUBKEY
+#include CONFIG_BOOTM_FITIMAGE_PUBKEY
+#endif
#include <arm/imx6ull.dtsi>
#include "imx6ul-phytec-phycore-som.dtsi"
diff --git a/arch/arm/dts/imx6ull-phytec-phycore-som-lc-nand.dts b/arch/arm/dts/imx6ull-phytec-phycore-som-lc-nand.dts
index e6c588b449..9c912df4de 100644
--- a/arch/arm/dts/imx6ull-phytec-phycore-som-lc-nand.dts
+++ b/arch/arm/dts/imx6ull-phytec-phycore-som-lc-nand.dts
@@ -5,7 +5,9 @@
*/
/dts-v1/;
-
+#ifdef CONFIG_BOOTM_FITIMAGE_PUBKEY
+#include CONFIG_BOOTM_FITIMAGE_PUBKEY
+#endif
#include <arm/imx6ull.dtsi>
#include "imx6ul-phytec-phycore-som.dtsi"
diff --git a/arch/arm/dts/imx6ull-phytec-phycore-som-nand.dts b/arch/arm/dts/imx6ull-phytec-phycore-som-nand.dts
index a5fa3e051c..224e853e1a 100644
--- a/arch/arm/dts/imx6ull-phytec-phycore-som-nand.dts
+++ b/arch/arm/dts/imx6ull-phytec-phycore-som-nand.dts
@@ -5,7 +5,9 @@
*/
/dts-v1/;
-
+#ifdef CONFIG_BOOTM_FITIMAGE_PUBKEY
+#include CONFIG_BOOTM_FITIMAGE_PUBKEY
+#endif
#include <arm/imx6ull.dtsi>
#include "imx6ul-phytec-phycore-som.dtsi"
#include "imx6ul-phytec-state.dtsi"
diff --git a/arch/arm/include/asm/pgtable64.h b/arch/arm/include/asm/pgtable64.h
index d8382505d0..d142612d0d 100644
--- a/arch/arm/include/asm/pgtable64.h
+++ b/arch/arm/include/asm/pgtable64.h
@@ -21,7 +21,7 @@
#define UNUSED_DESC 0x6EbAAD0BBADbA6E0
#define VA_START 0x0
-#define BITS_PER_VA 39
+#define BITS_PER_VA 48
/* Granule size of 4KB is being used */
#define GRANULE_SIZE_SHIFT 12
@@ -30,11 +30,13 @@
#define GRANULE_SIZE_MASK ((1 << GRANULE_SIZE_SHIFT) - 1)
#define BITS_RESOLVED_PER_LVL (GRANULE_SIZE_SHIFT - 3)
+#define L0_ADDR_SHIFT (GRANULE_SIZE_SHIFT + BITS_RESOLVED_PER_LVL * 3)
#define L1_ADDR_SHIFT (GRANULE_SIZE_SHIFT + BITS_RESOLVED_PER_LVL * 2)
#define L2_ADDR_SHIFT (GRANULE_SIZE_SHIFT + BITS_RESOLVED_PER_LVL * 1)
#define L3_ADDR_SHIFT (GRANULE_SIZE_SHIFT + BITS_RESOLVED_PER_LVL * 0)
+#define L0_ADDR_MASK (((1UL << BITS_RESOLVED_PER_LVL) - 1) << L0_ADDR_SHIFT)
#define L1_ADDR_MASK (((1UL << BITS_RESOLVED_PER_LVL) - 1) << L1_ADDR_SHIFT)
#define L2_ADDR_MASK (((1UL << BITS_RESOLVED_PER_LVL) - 1) << L2_ADDR_SHIFT)
#define L3_ADDR_MASK (((1UL << BITS_RESOLVED_PER_LVL) - 1) << L3_ADDR_SHIFT)
@@ -44,6 +46,7 @@
#define L3_XLAT_SIZE (1UL << L3_ADDR_SHIFT)
#define L2_XLAT_SIZE (1UL << L2_ADDR_SHIFT)
#define L1_XLAT_SIZE (1UL << L1_ADDR_SHIFT)
+#define L0_XLAT_SIZE (1UL << L0_ADDR_SHIFT)
#define GRANULE_MASK GRANULE_SIZE
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 6e98e95dbb..f5c8a4242b 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -859,6 +859,28 @@ config HABV4_IMG_CRT_PEM
endif
+if HABV4
+
+config HABV4_IMAGE_SIGNED
+ bool "build signed images"
+ help
+ enable the creation of a signed image, if the habv4-imx6-gencsf.h
+ included in the flash-header and the NXP cst Tool is available
+
+config HABV4_IMAGE_SIGNED_USB
+ bool "build signed USB images"
+ help
+ enable the creation of a usb signed image, if the habv4-imx6-gencsf.h
+ included in the flash-header and the NXP cst Tool is available
+
+config HABV4_IMAGE_SIGNED_ENCRYPTED
+ bool "build signed encrypted images"
+ help
+ enable the creation of the encrypted image, if the habv4-imx6-gencsf.h
+ included in the flash-header and the NXP cst Tool is available
+
+endif
+
config HABV3
tristate "HABv3 support"
select HAB
diff --git a/arch/arm/mach-imx/include/mach/vf610.h b/arch/arm/mach-imx/include/mach/vf610.h
index 6d00d2e457..7ac10a7b1e 100644
--- a/arch/arm/mach-imx/include/mach/vf610.h
+++ b/arch/arm/mach-imx/include/mach/vf610.h
@@ -48,4 +48,6 @@ static inline int vf610_cpu_revision(void)
return readl(VF610_ROM_VERSION_OFFSET) & 0xff;
}
+u64 vf610_uid(void);
+
#endif
diff --git a/arch/arm/mach-imx/vf610.c b/arch/arm/mach-imx/vf610.c
index b548cbcb5f..2fbd6393ea 100644
--- a/arch/arm/mach-imx/vf610.c
+++ b/arch/arm/mach-imx/vf610.c
@@ -19,6 +19,7 @@
#include <mach/revision.h>
#include <mach/vf610.h>
#include <mach/reset-reason.h>
+#include <mach/ocotp.h>
static const struct imx_reset_reason vf610_reset_reasons[] = {
{ VF610_SRC_SRSR_POR_RST, RESET_POR, 0 },
@@ -30,6 +31,11 @@ static const struct imx_reset_reason vf610_reset_reasons[] = {
{ /* sentinel */ }
};
+u64 vf610_uid(void)
+{
+ return imx_ocotp_read_uid(IOMEM(VF610_OCOTP_BASE_ADDR));
+}
+
int vf610_init(void)
{
const char *cputypestr;
@@ -57,5 +63,7 @@ int vf610_init(void)
imx_set_silicon_revision(cputypestr, vf610_cpu_revision());
imx_set_reset_reason(src + IMX_SRC_SRSR, vf610_reset_reasons);
+ pr_info("%s unique ID: %llx\n", cputypestr, vf610_uid());
+
return 0;
}
diff --git a/arch/arm/mach-layerscape/ppa.c b/arch/arm/mach-layerscape/ppa.c
index 987cb65876..477e894781 100644
--- a/arch/arm/mach-layerscape/ppa.c
+++ b/arch/arm/mach-layerscape/ppa.c
@@ -18,14 +18,33 @@
int ppa_entry(const void *, u32 *, u32 *);
+#define SEC_JR3_OFFSET 0x40000
+
static int of_psci_do_fixup(struct device_node *root, void *unused)
{
unsigned long psci_version;
+ struct device_node *np;
struct arm_smccc_res res = {};
arm_smccc_smc(ARM_PSCI_0_2_FN_PSCI_VERSION, 0, 0, 0, 0, 0, 0, 0, &res);
psci_version = res.a0;
+ for_each_compatible_node_from(np, root, NULL, "fsl,sec-v4.0-job-ring") {
+ const void *reg;
+ int na = of_n_addr_cells(np);
+ u64 offset;
+
+ reg = of_get_property(np, "reg", NULL);
+ if (!reg)
+ continue;
+
+ offset = of_read_number(reg, na);
+ if (offset != SEC_JR3_OFFSET)
+ continue;
+
+ of_delete_node(np);
+ }
+
return of_psci_fixup(root, psci_version);
}
diff --git a/arch/arm/mach-omap/Makefile b/arch/arm/mach-omap/Makefile
index 06cd191f95..36b2aa090e 100644
--- a/arch/arm/mach-omap/Makefile
+++ b/arch/arm/mach-omap/Makefile
@@ -22,8 +22,6 @@ pbl-$(CONFIG_ARCH_OMAP3) += omap3_generic.o auxcr.o
obj-$(CONFIG_ARCH_OMAP4) += omap4_generic.o omap4_clock.o
pbl-$(CONFIG_ARCH_OMAP4) += omap4_generic.o omap4_clock.o
obj-pbl-$(CONFIG_ARCH_AM33XX) += am33xx_generic.o am33xx_clock.o am33xx_mux.o am3xxx.o
-CFLAGS_pbl-am33xx_generic.o := -fno-tree-switch-conversion -fno-jump-tables
-CFLAGS_am33xx_generic.o := -fno-tree-switch-conversion -fno-jump-tables
obj-pbl-$(CONFIG_ARCH_AM35XX) += am3xxx.o am35xx_emif4.o
obj-$(CONFIG_ARCH_AM33XX) += am33xx_scrm.o
obj-$(CONFIG_ARCH_OMAP3) += omap3_clock.o
diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile
index 7c4c1fd137..7547951752 100644
--- a/arch/arm/mach-tegra/Makefile
+++ b/arch/arm/mach-tegra/Makefile
@@ -1,13 +1,5 @@
-CFLAGS_tegra_avp_init.o := \
- -mcpu=arm7tdmi -march=armv4t \
- -fno-tree-switch-conversion -fno-jump-tables
-CFLAGS_pbl-tegra_avp_init.o := \
- -mcpu=arm7tdmi -march=armv4t \
- -fno-tree-switch-conversion -fno-jump-tables
-CFLAGS_tegra_maincomplex_init.o := \
- -fno-tree-switch-conversion -fno-jump-tables
-CFLAGS_pbl-tegra_maincomplex_init.o := \
- -fno-tree-switch-conversion -fno-jump-tables
+CFLAGS_tegra_avp_init.o := -mcpu=arm7tdmi -march=armv4t
+CFLAGS_pbl-tegra_avp_init.o := -mcpu=arm7tdmi -march=armv4t
lwl-y += tegra_avp_init.o
lwl-y += tegra_maincomplex_init.o
obj-y += tegra20.o
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index ee465dc8e9..1c10db599c 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -52,9 +52,7 @@ cflags-$(CONFIG_CPU_MIPS32_R1) += $(call cc-option,-march=mips32,-mips32 -U_MIPS
cflags-$(CONFIG_CPU_MIPS32_R2) += $(call cc-option,-march=mips32r2,-mips32r2 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS32) -Wa,-mips32r2 -Wa,--trap
cflags-$(CONFIG_CPU_MIPS64_R1) += $(call cc-option,-march=mips64,-mips64 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS64) -Wa,-mips64 -Wa,--trap
cflags-$(CONFIG_CPU_MIPS64_R2) += $(call cc-option,-march=mips64r2,-mips64r2 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS64) -Wa,-mips64r2 -Wa,--trap
-cflags-$(CONFIG_CPU_LOONGSON1) += \
- $(call cc-option,-march=mips32r2,-mips32r2 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS32) \
- -Wa,-mips32r2 -Wa,--trap
+cflags-$(CONFIG_CPU_LOONGSON1) += $(call cc-option,-march=mips32r2,-mips32r2 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS32) -Wa,-mips32r2 -Wa,--trap
CPPFLAGS += -DTEXT_BASE=$(CONFIG_TEXT_BASE)
diff --git a/arch/mips/mach-ath79/art.c b/arch/mips/mach-ath79/art.c
index 2a2099e9f5..44118c19e9 100644
--- a/arch/mips/mach-ath79/art.c
+++ b/arch/mips/mach-ath79/art.c
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL-2.
+// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2018 Oleksij Rempel <linux@rempel-privat.de>
*/
diff --git a/arch/x86/mach-efi/elf_x86_64_efi.lds.S b/arch/x86/mach-efi/elf_x86_64_efi.lds.S
index 40a9425034..ed79118a36 100644
--- a/arch/x86/mach-efi/elf_x86_64_efi.lds.S
+++ b/arch/x86/mach-efi/elf_x86_64_efi.lds.S
@@ -58,12 +58,7 @@ SECTIONS
. = ALIGN(4096);
.rela : {
- *(.rela.data*)
- *(.rela.barebox*)
- *(.rela.initcall*)
- *(.rela.exitcall*)
- *(.rela.got)
- *(.rela.stab)
+ *(.rela*)
}
. = ALIGN(4096);
diff --git a/commands/Kconfig b/commands/Kconfig
index a6db52ae54..7784966282 100644
--- a/commands/Kconfig
+++ b/commands/Kconfig
@@ -1867,6 +1867,21 @@ config CMD_POWEROFF
help
Turn the power off.
+config CMD_SMC
+ bool
+ depends on ARM_SMCCC
+ prompt "PSCI test command"
+ default CONFIG_ARM_PSCI_DEBUG
+ help
+ Secure monitor code test command
+
+ Usage: smc [-nic]
+
+ Options:
+ -n Install secure monitor and switch to nonsecure mode
+ -i Show information about installed PSCI version
+ -c Start secondary CPU core
+
config CMD_SPI
bool
depends on SPI
diff --git a/commands/Makefile b/commands/Makefile
index 2f0980185c..01082de44c 100644
--- a/commands/Makefile
+++ b/commands/Makefile
@@ -17,6 +17,7 @@ obj-$(CONFIG_CMD_MEMSET) += memset.o
obj-$(CONFIG_CMD_EDIT) += edit.o
obj-$(CONFIG_CMD_EXEC) += exec.o
obj-$(CONFIG_CMD_SLEEP) += sleep.o
+obj-$(CONFIG_CMD_SMC) += smc.o
obj-$(CONFIG_CMD_MSLEEP) += msleep.o
obj-$(CONFIG_CMD_RESET) += reset.o
obj-$(CONFIG_CMD_POWEROFF) += poweroff.o
diff --git a/commands/gpio.c b/commands/gpio.c
index 951ad2c285..6d88ab6bbe 100644
--- a/commands/gpio.c
+++ b/commands/gpio.c
@@ -25,7 +25,9 @@ static int get_gpio_and_value(int argc, char *argv[],
if (argc < count)
return COMMAND_ERROR_USAGE;
- *gpio = gpio_find_by_label(argv[1]);
+ *gpio = gpio_find_by_name(argv[1]);
+ if (*gpio < 0)
+ *gpio = gpio_find_by_label(argv[1]);
if (*gpio < 0) {
ret = kstrtoint(argv[1], 0, gpio);
if (ret < 0)
diff --git a/commands/smc.c b/commands/smc.c
new file mode 100644
index 0000000000..84102f3249
--- /dev/null
+++ b/commands/smc.c
@@ -0,0 +1,162 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <common.h>
+#include <command.h>
+#include <getopt.h>
+#include <dma.h>
+#include <linux/iopoll.h>
+#include <asm/barebox-arm-head.h>
+
+#include <asm/psci.h>
+#include <asm/secure.h>
+#include <linux/arm-smccc.h>
+
+#define STACK_SIZE 100
+#define HANDSHAKE_MAGIC 0xBA12EB0C
+#define ERROR_MAGIC 0xDEADBEEF
+
+struct cpu_context {
+ unsigned long stack[STACK_SIZE];
+ long handshake;
+};
+
+static void noinline cpu_handshake(long *handshake)
+{
+ struct arm_smccc_res res;
+
+ writel(HANDSHAKE_MAGIC, handshake);
+
+ arm_smccc_smc(ARM_PSCI_0_2_FN_CPU_OFF,
+ 0, 0, 0, 0, 0, 0, 0, &res);
+
+ writel(ERROR_MAGIC, handshake);
+
+ while (1)
+ ;
+}
+
+static void __naked second_entry(unsigned long arg0)
+{
+ struct cpu_context *context = (void*)arg0;
+
+ arm_cpu_lowlevel_init();
+ arm_setup_stack((unsigned long)&context->stack[STACK_SIZE]);
+ barrier();
+
+ cpu_handshake(&context->handshake);
+}
+
+static const char *psci_xlate_str(long err)
+{
+ static char errno_string[sizeof "error 0x123456789ABCDEF0"];
+
+ switch(err)
+ {
+ case ARM_PSCI_RET_SUCCESS:
+ return "Success";
+ case ARM_PSCI_RET_NOT_SUPPORTED:
+ return "Operation not supported";
+ case ARM_PSCI_RET_INVAL:
+ return "Invalid argument";
+ case ARM_PSCI_RET_DENIED:
+ return "Operation not permitted";
+ case ARM_PSCI_RET_ALREADY_ON:
+ return "CPU already on";
+ case ARM_PSCI_RET_ON_PENDING:
+ return "CPU_ON in progress";
+ case ARM_PSCI_RET_INTERNAL_FAILURE:
+ return "Internal failure";
+ case ARM_PSCI_RET_NOT_PRESENT:
+ return "Trusted OS not present on core";
+ case ARM_PSCI_RET_DISABLED:
+ return "CPU is disabled";
+ case ARM_PSCI_RET_INVALID_ADDRESS:
+ return "Bad address";
+ }
+
+ sprintf(errno_string, "error 0x%lx", err);
+ return errno_string;
+}
+
+static struct cpu_context *context;
+
+static int do_smc(int argc, char *argv[])
+{
+ long ret;
+ int opt;
+ struct arm_smccc_res res = {
+ .a0 = 0xdeadbee0,
+ .a1 = 0xdeadbee1,
+ .a2 = 0xdeadbee2,
+ .a3 = 0xdeadbee3,
+ };
+
+ if (argc < 2)
+ return COMMAND_ERROR_USAGE;
+
+ while ((opt = getopt(argc, argv, "nic")) > 0) {
+ switch (opt) {
+ case 'n':
+ if (!IS_ENABLED(CONFIG_ARM_SECURE_MONITOR)) {
+ printf("secure monitor support not compiled in\n");
+ return COMMAND_ERROR;
+ }
+
+ armv7_secure_monitor_install();
+ break;
+ case 'i':
+ arm_smccc_smc(ARM_PSCI_0_2_FN_PSCI_VERSION,
+ 0, 0, 0, 0, 0, 0, 0, &res);
+ printf("found psci version %ld.%ld\n", res.a0 >> 16, res.a0 & 0xffff);
+ break;
+ case 'c':
+ if (!context)
+ context = dma_alloc_coherent(sizeof(*context),
+ DMA_ADDRESS_BROKEN);
+
+ if (!context) {
+ printf("Out of memory\n");
+ return COMMAND_ERROR;
+ }
+
+ arm_smccc_smc(ARM_PSCI_0_2_FN_CPU_ON,
+ 1, (unsigned long)second_entry, (unsigned long)context,
+ 0, 0, 0, 0, &res);
+ ret = (long)res.a0;
+ printf("CPU_ON returns with: %s\n", psci_xlate_str(ret));
+ if (ret) {
+ unsigned long magic = readl(&context->handshake);
+ if (magic == ERROR_MAGIC)
+ printf("Turning off CPU had failed\n");
+ return COMMAND_ERROR;
+ }
+
+ readl_poll_timeout(&context->handshake, ret,
+ ret != HANDSHAKE_MAGIC, USEC_PER_SEC);
+ if (ret == 0) {
+ printf("Second CPU handshake timed out.\n");
+ return COMMAND_ERROR;
+ }
+
+ printf("Second CPU handshake successful.\n");
+ }
+ }
+
+
+ return 0;
+}
+BAREBOX_CMD_HELP_START(smc)
+BAREBOX_CMD_HELP_TEXT("Secure monitor code test command")
+BAREBOX_CMD_HELP_TEXT("")
+BAREBOX_CMD_HELP_TEXT("Options:")
+BAREBOX_CMD_HELP_OPT ("-n", "Install secure monitor and switch to nonsecure mode")
+BAREBOX_CMD_HELP_OPT ("-i", "Show information about installed PSCI version")
+BAREBOX_CMD_HELP_OPT ("-c", "Start secondary CPU core")
+BAREBOX_CMD_HELP_END
+
+BAREBOX_CMD_START(smc)
+ .cmd = do_smc,
+ BAREBOX_CMD_DESC("secure monitor test command")
+ BAREBOX_CMD_HELP(cmd_smc_help)
+ BAREBOX_CMD_GROUP(CMD_GRP_MISC)
+BAREBOX_CMD_END
diff --git a/common/efi/efi.c b/common/efi/efi.c
index 73cea37036..ed81583550 100644
--- a/common/efi/efi.c
+++ b/common/efi/efi.c
@@ -361,7 +361,7 @@ efi_status_t efi_main(efi_handle_t image, efi_system_table_t *sys_table)
if (EFI_ERROR(efiret))
panic("failed to allocate malloc pool: %s\n",
efi_strerror(efiret));
- mem_malloc_init((void *)mem, (void *)mem + memsize);
+ mem_malloc_init((void *)mem, (void *)mem + memsize - 1);
start_barebox();
diff --git a/drivers/block/efi-block-io.c b/drivers/block/efi-block-io.c
index 39dbfb0f7a..30db486876 100644
--- a/drivers/block/efi-block-io.c
+++ b/drivers/block/efi-block-io.c
@@ -131,16 +131,9 @@ static void efi_bio_print_info(struct efi_bio_priv *priv)
media->optimal_transfer_length_granularity);
}
-static int is_bio_usbdev(struct efi_device *efidev)
+static bool is_bio_usbdev(struct efi_device *efidev)
{
- int i;
-
- for (i = 0; i < efidev->num_guids; i++) {
- if (!efi_guidcmp(efidev->guids[i], EFI_USB_IO_PROTOCOL_GUID))
- return 1;
- }
-
- return 0;
+ return efi_device_has_guid(efidev, EFI_USB_IO_PROTOCOL_GUID);
}
static int efi_bio_probe(struct efi_device *efidev)
diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig
index 219982d878..1a2ff9129e 100644
--- a/drivers/bus/Kconfig
+++ b/drivers/bus/Kconfig
@@ -25,4 +25,12 @@ config MVEBU_MBUS
Driver needed for the MBus configuration on Marvell EBU SoCs
(Kirkwood, Dove, Orion5x, MV78XX0 and Armada 370/XP).
+config ACPI
+ bool "Advanced Configuration and Power Interface (ACPI)"
+ default y
+ depends on EFI_BOOTUP
+ help
+ Driver needed for supporting drivers probed from ACPI tables.
+ The root SDT is found via UEFI.
+
endmenu
diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile
index ba5cee4063..518689a1ea 100644
--- a/drivers/bus/Makefile
+++ b/drivers/bus/Makefile
@@ -2,3 +2,4 @@ obj-$(CONFIG_BUS_OMAP_GPMC) += omap-gpmc.o
obj-$(CONFIG_IMX_WEIM) += imx-weim.o
obj-$(CONFIG_MVEBU_MBUS) += mvebu-mbus.o
obj-$(CONFIG_TI_SYSC) += ti-sysc.o
+obj-$(CONFIG_ACPI) += acpi.o
diff --git a/drivers/bus/acpi.c b/drivers/bus/acpi.c
new file mode 100644
index 0000000000..2515b6633b
--- /dev/null
+++ b/drivers/bus/acpi.c
@@ -0,0 +1,255 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 Ahmad Fatoum
+ */
+
+#include <common.h>
+#include <driver.h>
+#include <init.h>
+#include <efi/efi.h>
+#include <efi/efi-device.h>
+#include <acpi.h>
+
+static struct sig_desc {
+ const char sig[4];
+ const char *desc;
+} signatures[] = {
+ /* ACPI 6.3 Table 5-29, Defined DESCRIPTION_HEADER Signatures */
+ { "APIC", "Multiple APIC Description" },
+ { "BERT", "Boot Error Record" },
+ { "BGRT", "Boot Graphics Resource" },
+ { "CPEP", "Corrected Platform Error Polling" },
+ { "DSDT", "Differentiated System Description" },
+ { "ECDT", "Embedded Controller Boot Resource" },
+ { "EINJ", "Error Injection" },
+ { "ERST", "Error Record Serialization" },
+ { "FACP", "Fixed ACPI Description" },
+ { "FACS", "Firmware ACPI Control Structure" },
+ { "FPDT", "Firmware Performance Data" },
+ { "GTDT", "Generic Timer Description" },
+ { "HEST", "Hardware Error Source" },
+ { "MSCT", "Maximum System Characteristics" },
+ { "MPST", "Memory Power State" },
+ { "NFIT", "NVDIMM Firmware Interface" },
+ { "OEM\0", "OEM Specific Information" },
+ { "PCCT", "Platform Communications Channel" },
+ { "PMTT", "Platform Memory Topology" },
+ { "PSDT", "Persistent System Description" },
+ { "RASF", "ACPI RAS Feature" },
+ { "RSDT", "Root System Description" },
+ { "SBST", "Smart Battery Specification" },
+ { "SDEV", "Secure Devices" },
+ { "SLIT", "System Locality Distance Information" },
+ { "SRAT", "System Resource Affinity" },
+ { "SSDT", "Secondary System Description" },
+ { "XSDT", "Extended System Description" },
+
+ /* ACPI 6.3 Table 5-30, Reserved DESCRIPTION_HEADER Signatures */
+ { "BOOT", "Simple BOOT Flag" },
+ { "CSRT", "Core System Resource" },
+ { "DBG2", "Microsoft Debug Port 2" },
+ { "DBGP", "Debug Port" },
+ { "DMAR", "DMA Remapping" },
+ { "DPPT", "DMA Protection Policy" },
+ { "DRTM", "Dynamic Root of Trust for Measurement" },
+ { "ETDT", "(Obsolete) Event Timer Description" },
+ { "HPET", "IA-PC High Precision Event Timer" },
+ { "IBFT", "iSCSI Boot Firmware" },
+ { "IORT", "I/O Remapping" },
+ { "IVRS", "I/O Virtualization Reporting Structure" },
+ { "LPIT", "Low Power Idle" },
+ { "MCFG", "PCI Express memory mapped configuration" },
+ { "MCHI", "Management Controller Host Interface" },
+ { "MSDM", "Microsoft Data Management" },
+ { "SDEI", "Software Delegated Exceptions Interface" },
+ { "SLIC", "Microsoft Software Licensing Specification" },
+ { "SPCR", "Serial Port Console Redirection" },
+ { "SPMI", "Server Platform Management Interface" },
+ { "STAO", "_STA Override" },
+ { "TCPA", "Trusted Computing Platform Alliance Capabilities" },
+ { "TPM2", "Trusted Platform Module 2" },
+ { "UEFI", "UEFI ACPI Data" },
+ { "WAET", "Windows ACPI Emulated Devices" },
+ { "WDAT", "Watch Dog Action" },
+ { "WDRT", "Watchdog Resource" },
+ { "WPBT", "Platform Binary" },
+ { "WSMT", "Windows SMM Security Mitigation" },
+ { "XENV", "Xen Project" },
+
+ /* Others */
+ { "NHLT", "Non-HD Audio" },
+ { "ASF!", "Alert Standard Format" },
+
+ { /* sentinel */ }
+};
+
+static struct acpi_sdt *acpi_get_dev_sdt(struct device_d *dev)
+{
+ int i;
+
+ for (i = 0; i < dev->num_resources; i++) {
+ if (!strcmp(dev->resource[i].name, "SDT"))
+ return (struct acpi_sdt *)dev->resource[i].start;
+ }
+
+ return NULL;
+}
+
+static void acpi_devinfo(struct device_d *dev)
+{
+ struct acpi_sdt *sdt = acpi_get_dev_sdt(dev);
+ struct sig_desc *sig_desc;
+
+ printf("Signature: %.4s", sdt->signature);
+
+ for (sig_desc = signatures; sig_desc->desc; sig_desc++) {
+ size_t len = strnlen(sig_desc->sig, 4);
+
+ if (!memcmp(sdt->signature, sig_desc->sig, len)) {
+ printf(" (%s Table)", sig_desc->desc);
+ break;
+ }
+ }
+
+ printf("\nRevision: %u\n", sdt->revision);
+ printf("OemId: %.6s\n", sdt->oem_id);
+ printf("OemTableId: %.8s\n", sdt->oem_table_id);
+ printf("OemRevision: %u\n", sdt->oem_revision);
+ printf("CreatorId: 0x%08x\n", sdt->creator_id);
+ printf("CreatorRevision: %u\n", sdt->creator_revision);
+}
+
+static int acpi_register_device(struct device_d *dev, struct acpi_sdt *sdt)
+{
+ int ret;
+
+ ret = register_device(dev);
+ if (ret)
+ return ret;
+
+ device_add_resource(dev, "SDT", (resource_size_t)sdt, sdt->len,
+ IORESOURCE_MEM | IORESOURCE_ROM_COPY | IORESOURCE_ROM_BIOS_COPY);
+
+ dev_dbg(dev, "registered as ACPI device\n");
+
+ return 0;
+}
+
+static struct device_d *acpi_add_device(struct bus_type *bus,
+ acpi_sig_t signature)
+{
+ struct device_d *dev;
+
+ dev = xzalloc(sizeof(*dev));
+
+ dev->bus = bus;
+ dev->parent = bus->dev;
+ dev->id = DEVICE_ID_DYNAMIC;
+ dev->info = acpi_devinfo;
+
+ dev_set_name(dev, "acpi-%.4s", signature);
+
+ return dev;
+}
+
+static int acpi_register_devices(struct bus_type *bus)
+{
+ efi_config_table_t *table = bus->dev->priv;
+ struct acpi_rsdp *rsdp;
+ struct acpi_rsdt *root;
+ size_t entry_count;
+ const char *sig;
+ int i;
+
+ rsdp = (struct acpi_rsdp *)table->table;
+
+ if (!rsdp)
+ return -EFAULT;
+
+ /* ACPI specification v6.3
+ * 5.2.5.2 Finding the RSDP on UEFI Enabled Systems
+ */
+ if (memcmp("RSD PTR ", rsdp->signature, sizeof(rsdp->signature))) {
+ dev_dbg(bus->dev, "unexpected signature at start of config table: '%.8s'\n",
+ rsdp->signature);
+ return -ENODEV;
+ }
+
+ if (rsdp->revision < 0x02) {
+ sig = "RSDT";
+ root = (struct acpi_rsdt *)(unsigned long)rsdp->rsdt_addr;
+ entry_count = (root->sdt.len - sizeof(struct acpi_rsdt)) / sizeof(u32);
+ } else {
+ sig = "XSDT";
+ root = (struct acpi_rsdt *)((struct acpi2_rsdp *)rsdp)->xsdt_addr;
+ entry_count = (root->sdt.len - sizeof(struct acpi_rsdt)) / sizeof(u64);
+ }
+
+ if (acpi_sigcmp(sig, root->sdt.signature)) {
+ dev_err(bus->dev, "Expected %s, but found '%.4s'.\n",
+ sig, root->sdt.signature);
+ return -EIO;
+ }
+
+ dev_info(bus->dev, "Found %s (OEM: %.8s) with %lu entries\n",
+ sig, root->sdt.oem_id, entry_count);
+
+ for (i = 0; i < entry_count; i++) {
+ struct acpi_sdt *sdt = root->entries[i];
+ acpi_register_device(acpi_add_device(bus, sdt->signature), sdt);
+ }
+
+ return 0;
+}
+
+static int acpi_bus_match(struct device_d *dev, struct driver_d *drv)
+{
+ struct acpi_driver *acpidrv = to_acpi_driver(drv);
+ struct acpi_sdt *sdt = acpi_get_dev_sdt(dev);
+
+ return acpi_sigcmp(acpidrv->signature, sdt->signature);
+}
+
+static int acpi_bus_probe(struct device_d *dev)
+{
+ return dev->driver->probe(dev);
+}
+
+static void acpi_bus_remove(struct device_d *dev)
+{
+ if (dev->driver->remove)
+ dev->driver->remove(dev);
+}
+
+struct bus_type acpi_bus = {
+ .match = acpi_bus_match,
+ .probe = acpi_bus_probe,
+ .remove = acpi_bus_remove,
+};
+
+static int efi_acpi_probe(void)
+{
+ efi_config_table_t *table = NULL;
+ int i;
+
+ for (i = 0; i < efi_sys_table->nr_tables; i++) {
+ efi_config_table_t *ect = &efi_sys_table->tables[i];
+ /* take ACPI < 2 table only if no ACPI 2.0 is available */
+ if (!efi_guidcmp(ect->guid, EFI_ACPI_20_TABLE_GUID)) {
+ acpi_bus.name = "acpi2";
+ table = ect;
+ } else if (!table && !efi_guidcmp(ect->guid, EFI_ACPI_TABLE_GUID)) {
+ acpi_bus.name = "acpi";
+ table = ect;
+ }
+ }
+
+ if (!table)
+ return 0;
+
+ bus_register(&acpi_bus);
+ acpi_bus.dev->priv = table;
+
+ return acpi_register_devices(&acpi_bus);
+}
+postcore_initcall(efi_acpi_probe);
diff --git a/drivers/clk/imx/clk-imx6ul.c b/drivers/clk/imx/clk-imx6ul.c
index b0a6bb0e8d..35483efde6 100644
--- a/drivers/clk/imx/clk-imx6ul.c
+++ b/drivers/clk/imx/clk-imx6ul.c
@@ -450,6 +450,9 @@ static int imx6_ccm_probe(struct device_d *dev)
clk_set_parent(clks[IMX6ULL_CLK_EPDC_PRE_SEL],
clks[IMX6UL_CLK_PLL3_PFD2]);
+ /* Disable GPMI_IO clk before reparenting to avoid glitches */
+ clks[IMX6UL_CLK_GPMI_IO]->ops->disable(clks[IMX6UL_CLK_GPMI_IO]);
+
clk_set_parent(clks[IMX6UL_CLK_ENFC_SEL], clks[IMX6UL_CLK_PLL2_PFD2]);
return 0;
diff --git a/drivers/efi/efi-device.c b/drivers/efi/efi-device.c
index a1aac2dd31..ac035dcfac 100644
--- a/drivers/efi/efi-device.c
+++ b/drivers/efi/efi-device.c
@@ -386,16 +386,9 @@ static int efi_is_setup_mode(void)
return ret != 1;
}
-static int is_bio_usbdev(struct efi_device *efidev)
+static bool is_bio_usbdev(struct efi_device *efidev)
{
- int i;
-
- for (i = 0; i < efidev->num_guids; i++) {
- if (!efi_guidcmp(efidev->guids[i], EFI_USB_IO_PROTOCOL_GUID))
- return 1;
- }
-
- return 0;
+ return efi_device_has_guid(efidev, EFI_USB_IO_PROTOCOL_GUID);
}
static struct efi_device *bootdev;
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index f96009896a..9764ddf0f0 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -16,6 +16,7 @@ struct gpio_info {
bool requested;
bool active_low;
char *label;
+ char *name;
};
static struct gpio_info *gpio_desc;
@@ -108,6 +109,23 @@ int gpio_find_by_label(const char *label)
return -ENOENT;
}
+int gpio_find_by_name(const char *name)
+{
+ int i;
+
+ for (i = 0; i < ARCH_NR_GPIOS; i++) {
+ struct gpio_info *info = &gpio_desc[i];
+
+ if (!info->chip || !info->name)
+ continue;
+
+ if (!strcmp(info->name, name))
+ return i;
+ }
+
+ return -ENOENT;
+}
+
void gpio_free(unsigned gpio)
{
struct gpio_info *gi = gpio_to_desc(gpio);
@@ -410,11 +428,25 @@ static int of_hog_gpio(struct device_node *np, struct gpio_chip *chip,
static int of_gpiochip_scan_hogs(struct gpio_chip *chip)
{
struct device_node *np;
- int ret, i;
+ int ret, i, count;
if (!IS_ENABLED(CONFIG_OFDEVICE) || !chip->dev->device_node)
return 0;
+ count = of_property_count_strings(chip->dev->device_node, "gpio-line-names");
+
+ if (count > 0) {
+ const char **arr = xzalloc(count * sizeof(char *));
+
+ of_property_read_string_array(chip->dev->device_node,
+ "gpio-line-names", arr, count);
+
+ for (i = 0; i < chip->ngpio && i < count; i++)
+ gpio_desc[chip->base + i].name = xstrdup(arr[i]);
+
+ free(arr);
+ }
+
for_each_available_child_of_node(chip->dev->device_node, np) {
if (!of_property_read_bool(np, "gpio-hog"))
continue;
@@ -500,7 +532,7 @@ static int do_gpiolib(int argc, char *argv[])
gi->chip->base,
gi->chip->base + gi->chip->ngpio - 1,
gi->chip->dev->name);
- printf("%*cdir val requested label\n", 13, ' ');
+ printf(" %-3s %-3s %-9s %-20s %-20s\n", "dir", "val", "requested", "name", "label");
}
if (gi->chip->ops->get_direction)
@@ -510,11 +542,12 @@ static int do_gpiolib(int argc, char *argv[])
val = gi->chip->ops->get(gi->chip,
i - gi->chip->base);
- printf(" GPIO %*d: %*s %*s %*s %s\n", 4, i,
- 3, (dir < 0) ? "unk" : ((dir == GPIOF_DIR_IN) ? "in" : "out"),
- 3, (val < 0) ? "unk" : ((val == 0) ? "lo" : "hi"),
- 12, gi->requested ? (gi->active_low ? "active low" : "true") : "false",
- (gi->requested && gi->label) ? gi->label : "");
+ printf(" GPIO %4d: %-3s %-3s %-9s %-20s %-20s\n", i,
+ (dir < 0) ? "unk" : ((dir == GPIOF_DIR_IN) ? "in" : "out"),
+ (val < 0) ? "unk" : ((val == 0) ? "lo" : "hi"),
+ gi->requested ? (gi->active_low ? "active low" : "true") : "false",
+ gi->name ? gi->name : "",
+ gi->label ? gi->label : "");
}
return 0;
diff --git a/drivers/i2c/busses/i2c-gpio.c b/drivers/i2c/busses/i2c-gpio.c
index 5ab43fe935..7ccdb0b222 100644
--- a/drivers/i2c/busses/i2c-gpio.c
+++ b/drivers/i2c/busses/i2c-gpio.c
@@ -94,8 +94,8 @@ static int of_i2c_gpio_probe(struct device_node *np,
if (!IS_ENABLED(CONFIG_OFDEVICE))
return -ENODEV;
- pdata->sda_pin = of_get_named_gpio_flags(np, "sda-gpios", 0, NULL);
- pdata->scl_pin = of_get_named_gpio_flags(np, "scl-gpios", 0, NULL);
+ pdata->sda_pin = of_get_named_gpio(np, "sda-gpios", 0);
+ pdata->scl_pin = of_get_named_gpio(np, "scl-gpios", 0);
if ((!gpio_is_valid(pdata->sda_pin) || !gpio_is_valid(pdata->scl_pin))
&& (of_gpio_count(np) >= 2)) {
diff --git a/drivers/mci/mci-core.c b/drivers/mci/mci-core.c
index 9e39cbbb55..67257bcd18 100644
--- a/drivers/mci/mci-core.c
+++ b/drivers/mci/mci-core.c
@@ -1819,10 +1819,6 @@ int mci_register(struct mci_host *host)
host->supply = regulator_get(host->hw_dev, "vmmc");
if (IS_ERR(host->supply)) {
- if (host->supply == ERR_PTR(-EPROBE_DEFER)) {
- ret = -EPROBE_DEFER;
- goto err_free;
- }
dev_err(&mci->dev, "Failed to get 'vmmc' regulator.\n");
host->supply = NULL;
}
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 8abbf69b3a..87674a2a29 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -36,4 +36,10 @@ config UBOOTVAR
While it can be used standalone, it is best when coupled
with corresponding filesystem driver.
+config ACPI_TEST
+ bool "ACPI Test driver"
+ depends on ACPI
+ help
+ This is a simple Test driver to test the ACPI bus.
+
endmenu
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index bc1c01ea4d..4d92465a1e 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -7,3 +7,4 @@ obj-$(CONFIG_SRAM) += sram.o
obj-$(CONFIG_STATE_DRV) += state.o
obj-$(CONFIG_DEV_MEM) += mem.o
obj-$(CONFIG_UBOOTVAR) += ubootvar.o
+obj-$(CONFIG_ACPI_TEST) += acpi-test.o
diff --git a/drivers/misc/acpi-test.c b/drivers/misc/acpi-test.c
new file mode 100644
index 0000000000..970b435a0e
--- /dev/null
+++ b/drivers/misc/acpi-test.c
@@ -0,0 +1,61 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 Ahmad Fatoum
+ */
+
+#include <common.h>
+#include <init.h>
+#include <acpi.h>
+
+static const char *profiles[] = {
+ "Unspecified",
+ "Desktop",
+ "Mobile",
+ "Workstation",
+ "Enterprise Server",
+ "SOHO Server",
+ "Applicance PC",
+ "Performance Server",
+ "Tablet",
+};
+
+static int acpi_test_probe(struct device_d *dev)
+{
+ const char *profile = "reserved";
+ u8 *sdt;
+ u8 profileno;
+
+ dev_dbg(dev, "driver initializing...\n");
+
+ sdt = (u8 __force *)dev_request_mem_region_by_name(dev, "SDT");
+ if (IS_ERR(sdt)) {
+ dev_err(dev, "no SDT resource available: %s\n", strerrorp(sdt));
+ return PTR_ERR(sdt);
+ }
+
+ dev_dbg(dev, "SDT is at 0x%p\n", sdt);
+
+ profileno = sdt[45];
+
+ if (profileno < ARRAY_SIZE(profiles))
+ profile = profiles[profileno];
+
+ dev_info(dev, "PM profile is for '%s'\n", profile);
+
+ return 0;
+}
+
+static void acpi_test_remove(struct device_d *dev)
+{
+ dev_info(dev, "FADT driver removed\n");
+}
+
+static struct acpi_driver acpi_test_driver = {
+ .signature = "FACP",
+ .driver = {
+ .name = "acpi-test",
+ .probe = acpi_test_probe,
+ .remove = acpi_test_remove,
+ }
+};
+device_acpi_driver(acpi_test_driver);
diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index b251035982..1e1b69626a 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -677,6 +677,8 @@ static const struct spi_device_id spi_nor_ids[] = {
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ "is25lp016d", INFO(0x9d6015, 0, 64 * 1024, 32,
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
+ { "is25lp01g", INFO(0x9d601b, 0, 64 * 1024, 2048,
+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ "is25lp080d", INFO(0x9d6014, 0, 64 * 1024, 16,
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ "is25lp032", INFO(0x9d6016, 0, 64 * 1024, 64,
diff --git a/drivers/net/designware_stm32.c b/drivers/net/designware_stm32.c
index 9acdf11903..4c682a5dac 100644
--- a/drivers/net/designware_stm32.c
+++ b/drivers/net/designware_stm32.c
@@ -174,7 +174,6 @@ static int eqos_init_stm32(struct device_d *dev, struct eqos *eqos)
return 0;
}
-// todo split!
static struct eqos_ops stm32_ops = {
.init = eqos_init_stm32,
.get_ethaddr = eqos_get_ethaddr,
diff --git a/drivers/net/fsl-fman.c b/drivers/net/fsl-fman.c
index 4e6bb2ecfd..1aae58e494 100644
--- a/drivers/net/fsl-fman.c
+++ b/drivers/net/fsl-fman.c
@@ -104,11 +104,11 @@ struct fm_eth {
struct device_d *dev;
struct fm_port_global_pram *rx_pram; /* Rx parameter table */
struct fm_port_global_pram *tx_pram; /* Tx parameter table */
- void *rx_bd_ring; /* Rx BD ring base */
- void *cur_rxbd; /* current Rx BD */
+ struct fm_port_bd *rx_bd_ring; /* Rx BD ring base */
+ int cur_rxbd_idx; /* current Rx BD index */
void *rx_buf; /* Rx buffer base */
- void *tx_bd_ring; /* Tx BD ring base */
- void *cur_txbd; /* current Tx BD */
+ struct fm_port_bd *tx_bd_ring; /* Tx BD ring base */
+ int cur_txbd_idx; /* current Tx BD index */
struct memac *regs;
};
@@ -628,12 +628,13 @@ static int fm_eth_rx_port_parameter_init(struct fm_eth *fm_eth)
/* save them to fm_eth */
fm_eth->rx_bd_ring = rx_bd_ring_base;
- fm_eth->cur_rxbd = rx_bd_ring_base;
+ fm_eth->cur_rxbd_idx = 0;
fm_eth->rx_buf = rx_buf_pool;
/* init Rx BDs ring */
- rxbd = rx_bd_ring_base;
for (i = 0; i < RX_BD_RING_SIZE; i++) {
+ rxbd = &fm_eth->rx_bd_ring[i];
+
muram_writew(&rxbd->status, RxBD_EMPTY);
muram_writew(&rxbd->len, 0);
buf_hi = upper_32_bits(virt_to_phys(rx_buf_pool +
@@ -644,7 +645,6 @@ static int fm_eth_rx_port_parameter_init(struct fm_eth *fm_eth)
MAX_RXBUF_LEN, DMA_FROM_DEVICE);
muram_writew(&rxbd->buf_ptr_hi, (u16)buf_hi);
out_be32(&rxbd->buf_ptr_lo, buf_lo);
- rxbd++;
}
/* set the Rx queue descriptor */
@@ -702,16 +702,16 @@ static int fm_eth_tx_port_parameter_init(struct fm_eth *fm_eth)
* TX_BD_RING_SIZE);
/* save it to fm_eth */
fm_eth->tx_bd_ring = tx_bd_ring_base;
- fm_eth->cur_txbd = tx_bd_ring_base;
+ fm_eth->cur_txbd_idx = 0;
/* init Tx BDs ring */
- txbd = tx_bd_ring_base;
for (i = 0; i < TX_BD_RING_SIZE; i++) {
+ txbd = &fm_eth->tx_bd_ring[i];
+
muram_writew(&txbd->status, TxBD_LAST);
muram_writew(&txbd->len, 0);
muram_writew(&txbd->buf_ptr_hi, 0);
out_be32(&txbd->buf_ptr_lo, 0);
- txbd++;
}
/* set the Tx queue decriptor */
@@ -834,13 +834,12 @@ static int fm_eth_send(struct eth_device *edev, void *buf, int len)
{
struct fm_eth *fm_eth = to_fm_eth(edev);
struct fm_port_global_pram *pram;
- struct fm_port_bd *txbd, *txbd_base;
- u16 offset_in;
- int i;
+ struct fm_port_bd *txbd;
+ int i, ret;
dma_addr_t dma;
pram = fm_eth->tx_pram;
- txbd = fm_eth->cur_txbd;
+ txbd = &fm_eth->tx_bd_ring[fm_eth->cur_txbd_idx];
/* find one empty TxBD */
for (i = 0; muram_readw(&txbd->status) & TxBD_READY; i++) {
@@ -862,41 +861,35 @@ static int fm_eth_send(struct eth_device *edev, void *buf, int len)
muram_writew(&txbd->len, len);
muram_writew(&txbd->status, TxBD_READY | TxBD_LAST);
+ /* advance the TxBD */
+ fm_eth->cur_txbd_idx = (fm_eth->cur_txbd_idx + 1) % TX_BD_RING_SIZE;
+
/* update TxQD, let RISC to send the packet */
- offset_in = muram_readw(&pram->txqd.offset_in);
- offset_in += sizeof(struct fm_port_bd);
- if (offset_in >= muram_readw(&pram->txqd.bd_ring_size))
- offset_in = 0;
- muram_writew(&pram->txqd.offset_in, offset_in);
+ muram_writew(&pram->txqd.offset_in,
+ fm_eth->cur_txbd_idx * sizeof(struct fm_port_bd));
/* wait for buffer to be transmitted */
+ ret = 0;
for (i = 0; muram_readw(&txbd->status) & TxBD_READY; i++) {
udelay(10);
if (i > 0x10000) {
dev_err(&edev->dev, "Tx error, txbd->status = 0x%x\n",
muram_readw(&txbd->status));
- return -EIO;
+ ret = -EIO;
+ break;
}
}
dma_unmap_single(fm_eth->dev, dma, len, DMA_TO_DEVICE);
- /* advance the TxBD */
- txbd++;
- txbd_base = fm_eth->tx_bd_ring;
- if (txbd >= (txbd_base + TX_BD_RING_SIZE))
- txbd = txbd_base;
- /* update current txbd */
- fm_eth->cur_txbd = (void *)txbd;
-
- return 0;
+ return ret;
}
static int fm_eth_recv(struct eth_device *edev)
{
struct fm_eth *fm_eth = to_fm_eth(edev);
struct fm_port_global_pram *pram;
- struct fm_port_bd *rxbd, *rxbd_base;
+ struct fm_port_bd *rxbd;
u16 status, len;
u32 buf_lo, buf_hi;
u8 *data;
@@ -904,10 +897,14 @@ static int fm_eth_recv(struct eth_device *edev)
int ret = 1;
pram = fm_eth->rx_pram;
- rxbd = fm_eth->cur_rxbd;
- status = muram_readw(&rxbd->status);
- while (!(status & RxBD_EMPTY)) {
+ while (1) {
+ rxbd = &fm_eth->rx_bd_ring[fm_eth->cur_rxbd_idx];
+
+ status = muram_readw(&rxbd->status);
+ if (status & RxBD_EMPTY)
+ break;
+
if (!(status & RxBD_ERROR)) {
buf_hi = muram_readw(&rxbd->buf_ptr_hi);
buf_lo = in_be32(&rxbd->buf_ptr_lo);
@@ -933,12 +930,7 @@ static int fm_eth_recv(struct eth_device *edev)
muram_writew(&rxbd->len, 0);
/* advance RxBD */
- rxbd++;
- rxbd_base = fm_eth->rx_bd_ring;
- if (rxbd >= (rxbd_base + RX_BD_RING_SIZE))
- rxbd = rxbd_base;
- /* read next status */
- status = muram_readw(&rxbd->status);
+ fm_eth->cur_rxbd_idx = (fm_eth->cur_rxbd_idx + 1) % RX_BD_RING_SIZE;
/* update RxQD */
offset_out = muram_readw(&pram->rxqd.offset_out);
@@ -947,7 +939,6 @@ static int fm_eth_recv(struct eth_device *edev)
offset_out = 0;
muram_writew(&pram->rxqd.offset_out, offset_out);
}
- fm_eth->cur_rxbd = rxbd;
return ret;
}
@@ -1175,6 +1166,8 @@ static int fsl_fman_memac_probe(struct device_d *dev)
/* alloc the FMan ethernet private struct */
fm_eth = xzalloc(sizeof(*fm_eth));
+ dev->priv = fm_eth;
+
fm_eth->dev = dev;
ret = fsl_fman_memac_port_bind(fm_eth, FMAN_PORT_TYPE_TX);
@@ -1216,6 +1209,13 @@ static int fsl_fman_memac_probe(struct device_d *dev)
return 0;
}
+static void fsl_fman_memac_remove(struct device_d *dev)
+{
+ struct fm_eth *fm_eth = dev->priv;
+
+ fm_eth_halt(&fm_eth->edev);
+}
+
static int fsl_fman_muram_probe(struct device_d *dev)
{
struct resource *iores;
@@ -1274,6 +1274,7 @@ static struct of_device_id fsl_fman_memac_dt_ids[] = {
static struct driver_d fman_memac_driver = {
.name = "fsl-fman-memac",
.probe = fsl_fman_memac_probe,
+ .remove = fsl_fman_memac_remove,
.of_compatible = DRV_OF_COMPAT(fsl_fman_memac_dt_ids),
};
@@ -1303,6 +1304,7 @@ static int fsl_fman_probe(struct device_d *dev)
return PTR_ERR(iores);
reg = IOMEM(iores->start);
+ dev->priv = reg;
ret = of_platform_populate(dev->device_node, NULL, dev);
if (ret)
@@ -1320,6 +1322,13 @@ static int fsl_fman_probe(struct device_d *dev)
return 0;
}
+static void fsl_fman_remove(struct device_d *dev)
+{
+ struct ccsr_fman *reg = dev->priv;
+
+ setbits_be32(&reg->fm_fpm.fmrstc, FMFP_RSTC_RFM);
+}
+
static struct of_device_id fsl_fman_dt_ids[] = {
{
.compatible = "fsl,fman",
@@ -1330,6 +1339,45 @@ static struct of_device_id fsl_fman_dt_ids[] = {
static struct driver_d fman_driver = {
.name = "fsl-fman",
.probe = fsl_fman_probe,
+ .remove = fsl_fman_remove,
.of_compatible = DRV_OF_COMPAT(fsl_fman_dt_ids),
};
device_platform_driver(fman_driver);
+
+static int fman_of_fixup(struct device_node *root, void *context)
+{
+ struct device_node *fman, *fman_bb;
+ struct device_node *child, *child_bb;
+
+ fman_bb = of_find_compatible_node(NULL, NULL, "fsl,fman");
+ fman = of_find_compatible_node(root, NULL, "fsl,fman");
+
+ /*
+ * The dts files in the Linux tree have all network interfaces
+ * enabled. Disable the ones that are disabled under barebox
+ * as well.
+ */
+ for_each_child_of_node(fman, child) {
+ if (!of_device_is_compatible(child, "fsl,fman-memac"))
+ continue;
+
+ child_bb = of_get_child_by_name(fman_bb, child->name);
+ if (!child_bb)
+ continue;
+
+ if (of_device_is_available(child_bb))
+ of_device_enable(child);
+ else
+ of_device_disable(child);
+ }
+
+ return 0;
+}
+
+static int fman_register_of_fixup(void)
+{
+ of_register_fixup(fman_of_fixup, NULL);
+
+ return 0;
+}
+late_initcall(fman_register_of_fixup);
diff --git a/drivers/of/base.c b/drivers/of/base.c
index 98ef5fc0d4..80ceeab13b 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -887,54 +887,6 @@ int of_property_read_string(struct device_node *np, const char *propname,
EXPORT_SYMBOL_GPL(of_property_read_string);
/**
- * of_property_read_string_index - Find and read a string from a multiple
- * strings property.
- * @np: device node from which the property value is to be read.
- * @propname: name of the property to be searched.
- * @index: index of the string in the list of strings
- * @out_string: pointer to null terminated return string, modified only if
- * return value is 0.
- *
- * Search for a property in a device tree node and retrieve a null
- * terminated string value (pointer to data, not a copy) in the list of strings
- * contained in that property.
- * Returns 0 on success, -EINVAL if the property does not exist, -ENODATA if
- * property does not have a value, and -EILSEQ if the string is not
- * null-terminated within the length of the property data.
- *
- * The out_string pointer is modified only if a valid string can be decoded.
- */
-int of_property_read_string_index(struct device_node *np, const char *propname,
- int index, const char **output)
-{
- struct property *prop = of_find_property(np, propname, NULL);
- int i = 0;
- size_t l = 0, total = 0;
- const char *p;
- const void *value;
-
- if (!prop)
- return -EINVAL;
- value = of_property_get_value(prop);
- if (!value)
- return -ENODATA;
- if (strnlen(value, prop->length) >= prop->length)
- return -EILSEQ;
-
- p = value;
-
- for (i = 0; total < prop->length; total += l, p += l) {
- l = strlen(p) + 1;
- if (i++ == index) {
- *output = p;
- return 0;
- }
- }
- return -ENODATA;
-}
-EXPORT_SYMBOL_GPL(of_property_read_string_index);
-
-/**
* of_property_match_string() - Find string in a list and return index
* @np: pointer to node containing string list property
* @propname: string list property name
@@ -972,43 +924,6 @@ int of_property_match_string(struct device_node *np, const char *propname,
}
EXPORT_SYMBOL_GPL(of_property_match_string);
-/**
- * of_property_count_strings - Find and return the number of strings from a
- * multiple strings property.
- * @np: device node from which the property value is to be read.
- * @propname: name of the property to be searched.
- *
- * Search for a property in a device tree node and retrieve the number of null
- * terminated string contain in it. Returns the number of strings on
- * success, -EINVAL if the property does not exist, -ENODATA if property
- * does not have a value, and -EILSEQ if the string is not null-terminated
- * within the length of the property data.
- */
-int of_property_count_strings(struct device_node *np, const char *propname)
-{
- struct property *prop = of_find_property(np, propname, NULL);
- int i = 0;
- size_t l = 0, total = 0;
- const char *p;
- const void *value;
-
- if (!prop)
- return -EINVAL;
- value = of_property_get_value(prop);
- if (!value)
- return -ENODATA;
- if (strnlen(value, prop->length) >= prop->length)
- return -EILSEQ;
-
- p = value;
-
- for (i = 0; total < prop->length; total += l, p += l, i++)
- l = strlen(p) + 1;
-
- return i;
-}
-EXPORT_SYMBOL_GPL(of_property_count_strings);
-
const __be32 *of_prop_next_u32(struct property *prop, const __be32 *cur,
u32 *pu)
{
@@ -1777,6 +1692,43 @@ struct device_node *of_get_child_by_name(const struct device_node *node,
}
EXPORT_SYMBOL(of_get_child_by_name);
+/**
+ * of_property_read_string_helper() - Utility helper for parsing string properties
+ * @np: device node from which the property value is to be read.
+ * @propname: name of the property to be searched.
+ * @out_strs: output array of string pointers.
+ * @sz: number of array elements to read.
+ * @skip: Number of strings to skip over at beginning of list.
+ *
+ * Don't call this function directly. It is a utility helper for the
+ * of_property_read_string*() family of functions.
+ */
+int of_property_read_string_helper(const struct device_node *np,
+ const char *propname, const char **out_strs,
+ size_t sz, int skip)
+{
+ const struct property *prop = of_find_property(np, propname, NULL);
+ int l = 0, i = 0;
+ const char *p, *end;
+
+ if (!prop)
+ return -EINVAL;
+ if (!prop->value)
+ return -ENODATA;
+ p = prop->value;
+ end = p + prop->length;
+
+ for (i = 0; p < end && (!out_strs || i < skip + sz); i++, p += l) {
+ l = strnlen(p, end - p) + 1;
+ if (p + l > end)
+ return -EILSEQ;
+ if (out_strs && i >= skip)
+ *out_strs++ = p;
+ }
+ i -= skip;
+ return i <= 0 ? -ENODATA : i;
+}
+
static void __of_print_nodes(struct device_node *node, int indent, const char *prefix)
{
struct device_node *n;
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index 44a89d005f..025c418f2b 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -47,6 +47,13 @@ config PCI_IMX6
select OF_PCI
select PCI
+config PCI_LAYERSCAPE
+ bool "Freescale Layerscape PCIe controller"
+ depends on ARCH_LAYERSCAPE
+ select PCIE_DW
+ select OF_PCI
+ select PCI
+
endmenu
endif
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index 562304c65d..3ca6708657 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -11,3 +11,4 @@ obj-$(CONFIG_PCI_MVEBU) += pci-mvebu.o pci-mvebu-phy.o
obj-$(CONFIG_PCI_TEGRA) += pci-tegra.o
obj-$(CONFIG_PCIE_DW) += pcie-designware.o pcie-designware-host.o
obj-$(CONFIG_PCI_IMX6) += pci-imx6.o
+obj-$(CONFIG_PCI_LAYERSCAPE) += pci-layerscape.o
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
index ac15623307..251be4fffa 100644
--- a/drivers/pci/bus.c
+++ b/drivers/pci/bus.c
@@ -23,6 +23,32 @@ pci_match_one_device(const struct pci_device_id *id, const struct pci_dev *dev)
return NULL;
}
+/**
+ * pci_match_id - See if a pci device matches a given pci_id table
+ * @ids: array of PCI device id structures to search in
+ * @dev: the PCI device structure to match against.
+ *
+ * Used by a driver to check whether a PCI device present in the
+ * system is in its list of supported devices. Returns the matching
+ * pci_device_id structure or %NULL if there is no match.
+ *
+ * Deprecated, don't use this as it will not catch any dynamic ids
+ * that a driver might want to check for.
+ */
+const struct pci_device_id *pci_match_id(const struct pci_device_id *ids,
+ struct pci_dev *dev)
+{
+ if (ids) {
+ while (ids->vendor || ids->subvendor || ids->class_mask) {
+ if (pci_match_one_device(ids, dev))
+ return ids;
+ ids++;
+ }
+ }
+ return NULL;
+}
+EXPORT_SYMBOL(pci_match_id);
+
static int pci_match(struct device_d *dev, struct driver_d *drv)
{
struct pci_dev *pdev = to_pci_dev(dev);
diff --git a/drivers/pci/pci-imx6.c b/drivers/pci/pci-imx6.c
index 85307bad3e..05df9c0f79 100644
--- a/drivers/pci/pci-imx6.c
+++ b/drivers/pci/pci-imx6.c
@@ -97,8 +97,6 @@ struct imx6_pcie {
#define PCIE_PL_PFLR (PL_OFFSET + 0x08)
#define PCIE_PL_PFLR_LINK_STATE_MASK (0x3f << 16)
#define PCIE_PL_PFLR_FORCE_LINK (1 << 15)
-#define PCIE_PHY_DEBUG_R0 (PL_OFFSET + 0x28)
-#define PCIE_PHY_DEBUG_R1_XMLH_LINK_IN_TRAINING (1 << 29)
#define PCIE_PHY_DEBUG_R1_XMLH_LINK_UP (1 << 4)
#define PCIE_PHY_CTRL (PL_OFFSET + 0x114)
@@ -112,7 +110,6 @@ struct imx6_pcie {
#define PCIE_PHY_STAT_ACK_LOC 16
#define PCIE_LINK_WIDTH_SPEED_CONTROL 0x80C
-#define PORT_LOGIC_SPEED_CHANGE (0x1 << 17)
/* PHY registers (not memory-mapped) */
#define PCIE_PHY_RX_ASIC_OUT 0x100D
@@ -636,8 +633,8 @@ static int imx6_pcie_establish_link(struct imx6_pcie *imx6_pcie)
err_reset_phy:
dev_dbg(dev, "PHY DEBUG_R0=0x%08x DEBUG_R1=0x%08x\n",
- dw_pcie_readl_dbi(pci, PCIE_PHY_DEBUG_R0),
- dw_pcie_readl_dbi(pci, PCIE_PHY_DEBUG_R1));
+ dw_pcie_readl_dbi(pci, PCIE_PORT_DEBUG0),
+ dw_pcie_readl_dbi(pci, PCIE_PORT_DEBUG1));
imx6_pcie_reset_phy(imx6_pcie);
return ret;
@@ -659,8 +656,8 @@ static int imx6_pcie_host_init(struct pcie_port *pp)
static int imx6_pcie_link_up(struct dw_pcie *pci)
{
- return dw_pcie_readl_dbi(pci, PCIE_PHY_DEBUG_R1) &
- PCIE_PHY_DEBUG_R1_XMLH_LINK_UP;
+ return dw_pcie_readl_dbi(pci, PCIE_PORT_DEBUG1) &
+ PCIE_PORT_DEBUG1_LINK_UP;
}
static const struct dw_pcie_ops dw_pcie_ops = {
diff --git a/drivers/pci/pci-layerscape.c b/drivers/pci/pci-layerscape.c
new file mode 100644
index 0000000000..ccdc025c2e
--- /dev/null
+++ b/drivers/pci/pci-layerscape.c
@@ -0,0 +1,484 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PCIe host controller driver for Freescale Layerscape SoCs
+ *
+ * Copyright (C) 2014 Freescale Semiconductor.
+ *
+ * Author: Minghuan Lian <Minghuan.Lian@freescale.com>
+ */
+
+#include <common.h>
+#include <clock.h>
+#include <abort.h>
+#include <malloc.h>
+#include <io.h>
+#include <init.h>
+#include <gpio.h>
+#include <asm/mmu.h>
+#include <of_gpio.h>
+#include <of_device.h>
+#include <linux/clk.h>
+#include <linux/kernel.h>
+#include <of_address.h>
+#include <of_pci.h>
+#include <regmap.h>
+#include <mfd/syscon.h>
+#include <linux/pci.h>
+#include <linux/phy/phy.h>
+#include <linux/reset.h>
+#include <linux/sizes.h>
+
+#include "pcie-designware.h"
+
+/* PEX1/2 Misc Ports Status Register */
+#define SCFG_PEXMSCPORTSR(pex_idx) (0x94 + (pex_idx) * 4)
+#define LTSSM_STATE_SHIFT 20
+#define LTSSM_STATE_MASK 0x3f
+#define LTSSM_PCIE_L0 0x11 /* L0 state */
+
+/* PEX Internal Configuration Registers */
+#define PCIE_STRFMR1 0x71c /* Symbol Timer & Filter Mask Register1 */
+#define PCIE_ABSERR 0x8d0 /* Bridge Slave Error Response Register */
+#define PCIE_ABSERR_SETTING 0x9401 /* Forward error of non-posted request */
+
+#define PCIE_IATU_NUM 6
+
+#define PCIE_LUT_UDR(n) (0x800 + (n) * 8)
+#define PCIE_LUT_ENABLE (1 << 31)
+#define PCIE_LUT_LDR(n) (0x804 + (n) * 8)
+
+struct ls_pcie_drvdata {
+ u32 lut_offset;
+ u32 ltssm_shift;
+ u32 lut_dbg;
+ int pex_stream_id_start;
+ int pex_stream_id_end;
+ const struct dw_pcie_host_ops *ops;
+ const struct dw_pcie_ops *dw_pcie_ops;
+};
+
+struct ls_pcie {
+ struct dw_pcie pci;
+ void __iomem *lut;
+ struct regmap *scfg;
+ const char *compatible;
+ const struct ls_pcie_drvdata *drvdata;
+ int index;
+ int next_lut_index;
+};
+
+static struct ls_pcie *to_ls_pcie(struct dw_pcie *pci)
+{
+ return container_of(pci, struct ls_pcie, pci);
+}
+
+static u32 lut_readl(struct ls_pcie *pcie, unsigned int offset)
+{
+ return in_be32(pcie->lut + offset);
+}
+
+static void lut_writel(struct ls_pcie *pcie, unsigned int value,
+ unsigned int offset)
+{
+ out_be32(pcie->lut + offset, value);
+}
+
+static int ls_pcie_next_streamid(struct ls_pcie *pcie)
+{
+ static int next_stream_id;
+ int first = pcie->drvdata->pex_stream_id_start;
+ int last = pcie->drvdata->pex_stream_id_end;
+ int current = next_stream_id + first;
+
+ if (current > last)
+ return -EINVAL;
+
+ next_stream_id++;
+
+ return current;
+}
+
+#define PCIE_LUT_ENTRY_COUNT 32
+
+static int ls_pcie_next_lut_index(struct ls_pcie *pcie)
+{
+ if (pcie->next_lut_index < PCIE_LUT_ENTRY_COUNT)
+ return pcie->next_lut_index++;
+ else
+ return -ENOSPC; /* LUT is full */
+}
+
+static void ls_pcie_lut_set_mapping(struct ls_pcie *pcie, int index, u32 devid,
+ u32 stream_id)
+{
+ /* leave mask as all zeroes, want to match all bits */
+ lut_writel(pcie, devid << 16, PCIE_LUT_UDR(index));
+ lut_writel(pcie, stream_id | PCIE_LUT_ENABLE, PCIE_LUT_LDR(index));
+}
+
+static bool ls_pcie_is_bridge(struct ls_pcie *pcie)
+{
+ struct dw_pcie *pci = &pcie->pci;
+ u32 header_type;
+
+ header_type = ioread8(pci->dbi_base + PCI_HEADER_TYPE);
+ header_type &= 0x7f;
+
+ return header_type == PCI_HEADER_TYPE_BRIDGE;
+}
+
+/* Clear multi-function bit */
+static void ls_pcie_clear_multifunction(struct ls_pcie *pcie)
+{
+ struct dw_pcie *pci = &pcie->pci;
+
+ iowrite8(PCI_HEADER_TYPE_BRIDGE, pci->dbi_base + PCI_HEADER_TYPE);
+}
+
+/* Drop MSG TLP except for Vendor MSG */
+static void ls_pcie_drop_msg_tlp(struct ls_pcie *pcie)
+{
+ u32 val;
+ struct dw_pcie *pci = &pcie->pci;
+
+ val = ioread32(pci->dbi_base + PCIE_STRFMR1);
+ val &= 0xDFFFFFFF;
+ iowrite32(val, pci->dbi_base + PCIE_STRFMR1);
+}
+
+static void ls_pcie_disable_outbound_atus(struct ls_pcie *pcie)
+{
+ int i;
+
+ for (i = 0; i < PCIE_IATU_NUM; i++)
+ dw_pcie_disable_atu(&pcie->pci, i, DW_PCIE_REGION_OUTBOUND);
+}
+
+static int ls1021_pcie_link_up(struct dw_pcie *pci)
+{
+ u32 state;
+ struct ls_pcie *pcie = to_ls_pcie(pci);
+
+ if (!pcie->scfg)
+ return 0;
+
+ regmap_read(pcie->scfg, SCFG_PEXMSCPORTSR(pcie->index), &state);
+ state = (state >> LTSSM_STATE_SHIFT) & LTSSM_STATE_MASK;
+
+ if (state < LTSSM_PCIE_L0)
+ return 0;
+
+ return 1;
+}
+
+static int ls_pcie_link_up(struct dw_pcie *pci)
+{
+ struct ls_pcie *pcie = to_ls_pcie(pci);
+ u32 state;
+
+ state = (ioread32(pcie->lut + pcie->drvdata->lut_dbg) >>
+ pcie->drvdata->ltssm_shift) &
+ LTSSM_STATE_MASK;
+
+ if (state < LTSSM_PCIE_L0)
+ return 0;
+
+ return 1;
+}
+
+/* Forward error response of outbound non-posted requests */
+static void ls_pcie_fix_error_response(struct ls_pcie *pcie)
+{
+ struct dw_pcie *pci = &pcie->pci;
+
+ iowrite32(PCIE_ABSERR_SETTING, pci->dbi_base + PCIE_ABSERR);
+}
+
+static int ls_pcie_host_init(struct pcie_port *pp)
+{
+ struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+ struct ls_pcie *pcie = to_ls_pcie(pci);
+
+ /*
+ * Disable outbound windows configured by the bootloader to avoid
+ * one transaction hitting multiple outbound windows.
+ * dw_pcie_setup_rc() will reconfigure the outbound windows.
+ */
+ ls_pcie_disable_outbound_atus(pcie);
+ ls_pcie_fix_error_response(pcie);
+
+ dw_pcie_dbi_ro_wr_en(pci);
+ ls_pcie_clear_multifunction(pcie);
+ dw_pcie_dbi_ro_wr_dis(pci);
+
+ ls_pcie_drop_msg_tlp(pcie);
+
+ dw_pcie_setup_rc(pp);
+
+ return 0;
+}
+
+static int ls1021_pcie_host_init(struct pcie_port *pp)
+{
+ struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+ struct ls_pcie *pcie = to_ls_pcie(pci);
+ struct device_d *dev = pci->dev;
+ u32 index[2];
+ int ret;
+
+ pcie->scfg = syscon_regmap_lookup_by_phandle(dev->device_node,
+ "fsl,pcie-scfg");
+ if (IS_ERR(pcie->scfg)) {
+ ret = PTR_ERR(pcie->scfg);
+ dev_err(dev, "No syscfg phandle specified\n");
+ pcie->scfg = NULL;
+ return ret;
+ }
+
+ if (of_property_read_u32_array(dev->device_node,
+ "fsl,pcie-scfg", index, 2)) {
+ pcie->scfg = NULL;
+ return -EINVAL;
+ }
+ pcie->index = index[1];
+
+ return ls_pcie_host_init(pp);
+}
+
+static const struct dw_pcie_host_ops ls1021_pcie_host_ops = {
+ .host_init = ls1021_pcie_host_init,
+};
+
+static const struct dw_pcie_host_ops ls_pcie_host_ops = {
+ .host_init = ls_pcie_host_init,
+};
+
+static const struct dw_pcie_ops dw_ls1021_pcie_ops = {
+ .link_up = ls1021_pcie_link_up,
+};
+
+static const struct dw_pcie_ops dw_ls_pcie_ops = {
+ .link_up = ls_pcie_link_up,
+};
+
+static const struct ls_pcie_drvdata ls1021_drvdata = {
+ .ops = &ls1021_pcie_host_ops,
+ .dw_pcie_ops = &dw_ls1021_pcie_ops,
+};
+
+static const struct ls_pcie_drvdata ls1043_drvdata = {
+ .lut_offset = 0x10000,
+ .ltssm_shift = 24,
+ .lut_dbg = 0x7fc,
+ .pex_stream_id_start = 11,
+ .pex_stream_id_end = 26,
+ .ops = &ls_pcie_host_ops,
+ .dw_pcie_ops = &dw_ls_pcie_ops,
+};
+
+static const struct ls_pcie_drvdata ls1046_drvdata = {
+ .lut_offset = 0x80000,
+ .ltssm_shift = 24,
+ .lut_dbg = 0x407fc,
+ .pex_stream_id_start = 11,
+ .pex_stream_id_end = 26,
+ .ops = &ls_pcie_host_ops,
+ .dw_pcie_ops = &dw_ls_pcie_ops,
+};
+
+static const struct ls_pcie_drvdata ls2080_drvdata = {
+ .lut_offset = 0x80000,
+ .ltssm_shift = 0,
+ .lut_dbg = 0x7fc,
+ .pex_stream_id_start = 7,
+ .pex_stream_id_end = 22,
+ .ops = &ls_pcie_host_ops,
+ .dw_pcie_ops = &dw_ls_pcie_ops,
+};
+
+static const struct ls_pcie_drvdata ls2088_drvdata = {
+ .lut_offset = 0x80000,
+ .ltssm_shift = 0,
+ .lut_dbg = 0x407fc,
+ .pex_stream_id_start = 7,
+ .pex_stream_id_end = 18,
+ .ops = &ls_pcie_host_ops,
+ .dw_pcie_ops = &dw_ls_pcie_ops,
+};
+
+static const struct of_device_id ls_pcie_of_match[] = {
+ { .compatible = "fsl,ls1012a-pcie", .data = &ls1046_drvdata },
+ { .compatible = "fsl,ls1021a-pcie", .data = &ls1021_drvdata },
+ { .compatible = "fsl,ls1043a-pcie", .data = &ls1043_drvdata },
+ { .compatible = "fsl,ls1046a-pcie", .data = &ls1046_drvdata },
+ { .compatible = "fsl,ls2080a-pcie", .data = &ls2080_drvdata },
+ { .compatible = "fsl,ls2085a-pcie", .data = &ls2080_drvdata },
+ { .compatible = "fsl,ls2088a-pcie", .data = &ls2088_drvdata },
+ { .compatible = "fsl,ls1088a-pcie", .data = &ls2088_drvdata },
+ { },
+};
+
+static int __init ls_add_pcie_port(struct ls_pcie *pcie)
+{
+ struct dw_pcie *pci = &pcie->pci;
+ struct pcie_port *pp = &pci->pp;
+ struct device_d *dev = pci->dev;
+ int ret;
+
+ pp->ops = pcie->drvdata->ops;
+
+ ret = dw_pcie_host_init(pp);
+ if (ret) {
+ dev_err(dev, "failed to initialize host\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static int ls_pcie_of_fixup(struct device_node *root, void *ctx)
+{
+ struct ls_pcie *pcie = ctx;
+ struct device_d *dev = pcie->pci.dev;
+ struct device_node *np;
+ char *name;
+ u32 *arr, phandle;
+ int nluts;
+ int ret, i;
+ u32 devid, stream_id;
+
+ name = of_get_reproducible_name(dev->device_node);
+
+ np = root;
+ do {
+ np = of_find_node_by_reproducible_name(np, name);
+ if (!np)
+ return -ENODEV;
+ } while (!of_device_is_compatible(np, pcie->compatible));
+
+ nluts = pcie->next_lut_index;
+
+ ret = of_property_read_u32(np, "msi-parent", &phandle);
+ if (ret) {
+ dev_err(pcie->pci.dev, "Unable to get \"msi-parent\" phandle\n");
+ return ret;
+ }
+
+ arr = xmalloc(nluts * sizeof(u32) * 4);
+
+ for (i = 0; i < nluts; i++) {
+ u32 udr = lut_readl(pcie, PCIE_LUT_UDR(i));
+ u32 ldr = lut_readl(pcie, PCIE_LUT_LDR(i));
+
+ if (!(ldr & PCIE_LUT_ENABLE))
+ break;
+
+ devid = udr >> 16;
+ stream_id = ldr & 0x7fff;
+
+ arr[i * 4] = devid;
+ arr[i * 4 + 1] = phandle;
+ arr[i * 4 + 2] = stream_id;
+ arr[i * 4 + 3] = 1;
+ }
+
+ /*
+ * An msi-map is a property to be added to the pci controller
+ * node. It is a table, where each entry consists of 4 fields
+ * e.g.:
+ *
+ * msi-map = <[devid] [phandle-to-msi-ctrl] [stream-id] [count]
+ * [devid] [phandle-to-msi-ctrl] [stream-id] [count]>;
+ */
+
+ ret = of_property_write_u32_array(np, "msi-map", arr, nluts * 4);
+ if (ret)
+ goto out;
+
+ of_device_enable(np);
+
+ ret = 0;
+
+out:
+ free(arr);
+ return ret;
+}
+
+static int __init ls_pcie_probe(struct device_d *dev)
+{
+ struct dw_pcie *pci;
+ struct ls_pcie *pcie;
+ struct resource *dbi_base;
+ const struct of_device_id *match;
+ int ret;
+
+ pcie = xzalloc(sizeof(*pcie));
+ if (!pcie)
+ return -ENOMEM;
+
+ pci = &pcie->pci;
+
+ match = of_match_device(dev->driver->of_compatible, dev);
+ if (!match)
+ return -ENODEV;
+
+ pcie->drvdata = match->data;
+ pcie->compatible = match->compatible;
+
+ pci->dev = dev;
+ pci->ops = pcie->drvdata->dw_pcie_ops;
+
+ dbi_base = dev_request_mem_resource(dev, 0);
+ if (IS_ERR(dbi_base))
+ return PTR_ERR(dbi_base);
+
+ pci->dbi_base = IOMEM(dbi_base->start);
+
+ pcie->lut = pci->dbi_base + pcie->drvdata->lut_offset;
+
+ if (!ls_pcie_is_bridge(pcie))
+ return -ENODEV;
+
+ dev->priv = pcie;
+
+ ret = ls_add_pcie_port(pcie);
+ if (ret < 0)
+ return ret;
+
+ of_register_fixup(ls_pcie_of_fixup, pcie);
+
+ return 0;
+}
+
+static struct driver_d ls_pcie_driver = {
+ .name = "layerscape-pcie",
+ .of_compatible = DRV_OF_COMPAT(ls_pcie_of_match),
+ .probe = ls_pcie_probe,
+};
+device_platform_driver(ls_pcie_driver);
+
+static void ls_pcie_fixup(struct pci_dev *pcidev)
+{
+ struct pci_bus *bus = pcidev->bus, *p;
+ struct pci_controller *host = bus->host;
+ struct pcie_port *pp = container_of(host, struct pcie_port, pci);
+ struct dw_pcie *dwpcie = container_of(pp, struct dw_pcie, pp);
+ struct ls_pcie *lspcie = container_of(dwpcie, struct ls_pcie, pci);
+ int stream_id, index;
+ int base_bus_num = 0;
+
+ stream_id = ls_pcie_next_streamid(lspcie);
+ index = ls_pcie_next_lut_index(lspcie);
+
+ p = pcidev->bus;
+ while (p) {
+ base_bus_num = p->number;
+ p = p->parent_bus;
+ }
+
+ ls_pcie_lut_set_mapping(lspcie, index,
+ (pcidev->bus->number - base_bus_num) << 8 | pcidev->devfn,
+ stream_id);
+}
+
+DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, ls_pcie_fixup);
diff --git a/drivers/pci/pcie-designware-host.c b/drivers/pci/pcie-designware-host.c
index 7a95b2a092..b2d46d38f8 100644
--- a/drivers/pci/pcie-designware-host.c
+++ b/drivers/pci/pcie-designware-host.c
@@ -340,17 +340,6 @@ static const struct pci_ops dw_pcie_ops = {
.write = dw_pcie_wr_conf,
};
-static u8 dw_pcie_iatu_unroll_enabled(struct dw_pcie *pci)
-{
- u32 val;
-
- val = dw_pcie_readl_dbi(pci, PCIE_ATU_VIEWPORT);
- if (val == 0xffffffff)
- return 1;
-
- return 0;
-}
-
void dw_pcie_setup_rc(struct pcie_port *pp)
{
u32 val;
@@ -381,11 +370,6 @@ void dw_pcie_setup_rc(struct pcie_port *pp)
* we should not program the ATU here.
*/
if (!pp->ops->rd_other_conf) {
- /* get iATU unroll support */
- pci->iatu_unroll_enabled = dw_pcie_iatu_unroll_enabled(pci);
- dev_dbg(pci->dev, "iATU unroll: %s\n",
- pci->iatu_unroll_enabled ? "enabled" : "disabled");
-
dw_pcie_prog_outbound_atu(pci, PCIE_ATU_REGION_INDEX0,
PCIE_ATU_TYPE_MEM, pp->mem_mod_base,
pp->mem_bus_addr, pp->mem_size);
diff --git a/drivers/pci/pcie-designware.c b/drivers/pci/pcie-designware.c
index c6d19559f4..e2007dba6d 100644
--- a/drivers/pci/pcie-designware.c
+++ b/drivers/pci/pcie-designware.c
@@ -29,7 +29,7 @@
int dw_pcie_read(void __iomem *addr, int size, u32 *val)
{
- if ((uintptr_t)addr & (size - 1)) {
+ if (!IS_ALIGNED((uintptr_t)addr, size)) {
*val = 0;
return PCIBIOS_BAD_REGISTER_NUMBER;
}
@@ -50,7 +50,7 @@ int dw_pcie_read(void __iomem *addr, int size, u32 *val)
int dw_pcie_write(void __iomem *addr, int size, u32 val)
{
- if ((uintptr_t)addr & (size - 1))
+ if (!IS_ALIGNED((uintptr_t)addr, size))
return PCIBIOS_BAD_REGISTER_NUMBER;
if (size == 4)
@@ -65,42 +65,69 @@ int dw_pcie_write(void __iomem *addr, int size, u32 val)
return PCIBIOS_SUCCESSFUL;
}
-u32 __dw_pcie_readl_dbi(struct dw_pcie *pci, void __iomem *base, u32 reg,
- size_t size)
+u32 dw_pcie_read_dbi(struct dw_pcie *pci, u32 reg, size_t size)
{
int ret;
u32 val;
- if (pci->ops->readl_dbi)
- return pci->ops->readl_dbi(pci, base, reg, size);
+ if (pci->ops->read_dbi)
+ return pci->ops->read_dbi(pci, pci->dbi_base, reg, size);
- ret = dw_pcie_read(base + reg, size, &val);
+ ret = dw_pcie_read(pci->dbi_base + reg, size, &val);
if (ret)
dev_err(pci->dev, "Read DBI address failed\n");
return val;
}
-void __dw_pcie_writel_dbi(struct dw_pcie *pci, void __iomem *base, u32 reg,
- size_t size, u32 val)
+void dw_pcie_write_dbi(struct dw_pcie *pci, u32 reg, size_t size, u32 val)
{
int ret;
- if (pci->ops->writel_dbi) {
- pci->ops->writel_dbi(pci, base, reg, size, val);
+ if (pci->ops->write_dbi) {
+ pci->ops->write_dbi(pci, pci->dbi_base, reg, size, val);
return;
}
- ret = dw_pcie_write(base + reg, size, val);
+ ret = dw_pcie_write(pci->dbi_base + reg, size, val);
if (ret)
dev_err(pci->dev, "Write DBI address failed\n");
}
+u32 dw_pcie_read_atu(struct dw_pcie *pci, u32 reg, size_t size)
+{
+ int ret;
+ u32 val;
+
+ if (pci->ops->read_dbi)
+ return pci->ops->read_dbi(pci, pci->atu_base, reg, size);
+
+ ret = dw_pcie_read(pci->atu_base + reg, size, &val);
+ if (ret)
+ dev_err(pci->dev, "Read ATU address failed\n");
+
+ return val;
+}
+
+void dw_pcie_write_atu(struct dw_pcie *pci, u32 reg, size_t size, u32 val)
+{
+ int ret;
+
+ if (pci->ops->write_dbi) {
+ pci->ops->write_dbi(pci, pci->atu_base, reg, size, val);
+ return;
+ }
+
+ ret = dw_pcie_write(pci->atu_base + reg, size, val);
+ if (ret)
+ dev_err(pci->dev, "Write ATU address failed\n");
+}
+
static u32 dw_pcie_readl_ob_unroll(struct dw_pcie *pci, u32 index, u32 reg)
{
u32 offset = PCIE_GET_ATU_OUTB_UNR_REG_OFFSET(index);
- return dw_pcie_readl_dbi(pci, offset + reg);
+ return dw_pcie_readl_atu(pci, offset + reg);
}
static void dw_pcie_writel_ob_unroll(struct dw_pcie *pci, u32 index,
@@ -108,7 +135,7 @@ static void dw_pcie_writel_ob_unroll(struct dw_pcie *pci, u32 index,
{
u32 offset = PCIE_GET_ATU_OUTB_UNR_REG_OFFSET(index);
- dw_pcie_writel_dbi(pci, offset + reg, val);
+ dw_pcie_writel_atu(pci, offset + reg, val);
}
static void dw_pcie_prog_outbound_atu_unroll(struct dw_pcie *pci, int index,
@@ -188,6 +215,26 @@ void dw_pcie_prog_outbound_atu(struct dw_pcie *pci, int index,
dev_err(pci->dev, "Outbound iATU is not being enabled\n");
}
+void dw_pcie_disable_atu(struct dw_pcie *pci, int index,
+ enum dw_pcie_region_type type)
+{
+ int region;
+
+ switch (type) {
+ case DW_PCIE_REGION_INBOUND:
+ region = PCIE_ATU_REGION_INBOUND;
+ break;
+ case DW_PCIE_REGION_OUTBOUND:
+ region = PCIE_ATU_REGION_OUTBOUND;
+ break;
+ default:
+ return;
+ }
+
+ dw_pcie_writel_dbi(pci, PCIE_ATU_VIEWPORT, region | index);
+ dw_pcie_writel_dbi(pci, PCIE_ATU_CR2, (u32)~PCIE_ATU_ENABLE);
+}
+
int dw_pcie_wait_for_link(struct dw_pcie *pci)
{
int retries;
@@ -213,9 +260,20 @@ int dw_pcie_link_up(struct dw_pcie *pci)
if (pci->ops->link_up)
return pci->ops->link_up(pci);
- val = readl(pci->dbi_base + PCIE_PHY_DEBUG_R1);
- return ((val & PCIE_PHY_DEBUG_R1_LINK_UP) &&
- !(val & PCIE_PHY_DEBUG_R1_LINK_IN_TRAINING));
+ val = readl(pci->dbi_base + PCIE_PORT_DEBUG1);
+ return ((val & PCIE_PORT_DEBUG1_LINK_UP) &&
+ (!(val & PCIE_PORT_DEBUG1_LINK_IN_TRAINING)));
+}
+
+static u8 dw_pcie_iatu_unroll_enabled(struct dw_pcie *pci)
+{
+ u32 val;
+
+ val = dw_pcie_readl_dbi(pci, PCIE_ATU_VIEWPORT);
+ if (val == 0xffffffff)
+ return 1;
+
+ return 0;
}
void dw_pcie_setup(struct dw_pcie *pci)
@@ -226,9 +284,21 @@ void dw_pcie_setup(struct dw_pcie *pci)
struct device_d *dev = pci->dev;
struct device_node *np = dev->device_node;
+ if (pci->version >= 0x480A || (!pci->version &&
+ dw_pcie_iatu_unroll_enabled(pci))) {
+ pci->iatu_unroll_enabled = true;
+ if (!pci->atu_base)
+ pci->atu_base = pci->dbi_base + DEFAULT_DBI_ATU_OFFSET;
+ }
+ dev_dbg(pci->dev, "iATU unroll: %s\n", pci->iatu_unroll_enabled ?
+ "enabled" : "disabled");
+
+
ret = of_property_read_u32(np, "num-lanes", &lanes);
- if (ret)
- lanes = 0;
+ if (ret) {
+ dev_dbg(pci->dev, "property num-lanes isn't found\n");
+ return;
+ }
/* Set the number of lanes */
val = dw_pcie_readl_dbi(pci, PCIE_PORT_LINK_CONTROL);
diff --git a/drivers/pci/pcie-designware.h b/drivers/pci/pcie-designware.h
index 058a0acbb2..de20654e42 100644
--- a/drivers/pci/pcie-designware.h
+++ b/drivers/pci/pcie-designware.h
@@ -11,6 +11,8 @@
#ifndef _PCIE_DESIGNWARE_H
#define _PCIE_DESIGNWARE_H
+#include <linux/bitfield.h>
+
/* Parameters for the waiting for link up routine */
#define LINK_WAIT_MAX_RETRIES 10
#define LINK_WAIT_USLEEP_MAX 100000
@@ -19,19 +21,30 @@
#define LINK_WAIT_MAX_IATU_RETRIES 5
#define LINK_WAIT_IATU_MAX 10000
-/* Synopsis specific PCIE configuration registers */
+/* Synopsys-specific PCIe configuration registers */
#define PCIE_PORT_LINK_CONTROL 0x710
-#define PORT_LINK_MODE_MASK (0x3f << 16)
-#define PORT_LINK_MODE_1_LANES (0x1 << 16)
-#define PORT_LINK_MODE_2_LANES (0x3 << 16)
-#define PORT_LINK_MODE_4_LANES (0x7 << 16)
+#define PORT_LINK_MODE_MASK GENMASK(21, 16)
+#define PORT_LINK_MODE(n) FIELD_PREP(PORT_LINK_MODE_MASK, n)
+#define PORT_LINK_MODE_1_LANES PORT_LINK_MODE(0x1)
+#define PORT_LINK_MODE_2_LANES PORT_LINK_MODE(0x3)
+#define PORT_LINK_MODE_4_LANES PORT_LINK_MODE(0x7)
+#define PORT_LINK_MODE_8_LANES PORT_LINK_MODE(0xf)
+
+#define PCIE_PORT_DEBUG0 0x728
+#define PORT_LOGIC_LTSSM_STATE_MASK 0x1f
+#define PORT_LOGIC_LTSSM_STATE_L0 0x11
+#define PCIE_PORT_DEBUG1 0x72C
+#define PCIE_PORT_DEBUG1_LINK_UP BIT(4)
+#define PCIE_PORT_DEBUG1_LINK_IN_TRAINING BIT(29)
#define PCIE_LINK_WIDTH_SPEED_CONTROL 0x80C
-#define PORT_LOGIC_SPEED_CHANGE (0x1 << 17)
-#define PORT_LOGIC_LINK_WIDTH_MASK (0x1f << 8)
-#define PORT_LOGIC_LINK_WIDTH_1_LANES (0x1 << 8)
-#define PORT_LOGIC_LINK_WIDTH_2_LANES (0x2 << 8)
-#define PORT_LOGIC_LINK_WIDTH_4_LANES (0x4 << 8)
+#define PORT_LOGIC_SPEED_CHANGE BIT(17)
+#define PORT_LOGIC_LINK_WIDTH_MASK GENMASK(12, 8)
+#define PORT_LOGIC_LINK_WIDTH(n) FIELD_PREP(PORT_LOGIC_LINK_WIDTH_MASK, n)
+#define PORT_LOGIC_LINK_WIDTH_1_LANES PORT_LOGIC_LINK_WIDTH(0x1)
+#define PORT_LOGIC_LINK_WIDTH_2_LANES PORT_LOGIC_LINK_WIDTH(0x2)
+#define PORT_LOGIC_LINK_WIDTH_4_LANES PORT_LOGIC_LINK_WIDTH(0x4)
+#define PORT_LOGIC_LINK_WIDTH_8_LANES PORT_LOGIC_LINK_WIDTH(0x8)
#define PCIE_MSI_ADDR_LO 0x820
#define PCIE_MSI_ADDR_HI 0x824
@@ -40,61 +53,86 @@
#define PCIE_MSI_INTR0_STATUS 0x830
#define PCIE_ATU_VIEWPORT 0x900
-#define PCIE_ATU_REGION_INBOUND (0x1 << 31)
-#define PCIE_ATU_REGION_OUTBOUND (0x0 << 31)
-#define PCIE_ATU_REGION_INDEX2 (0x2 << 0)
-#define PCIE_ATU_REGION_INDEX1 (0x1 << 0)
-#define PCIE_ATU_REGION_INDEX0 (0x0 << 0)
+#define PCIE_ATU_REGION_INBOUND BIT(31)
+#define PCIE_ATU_REGION_OUTBOUND 0
+#define PCIE_ATU_REGION_INDEX2 0x2
+#define PCIE_ATU_REGION_INDEX1 0x1
+#define PCIE_ATU_REGION_INDEX0 0x0
#define PCIE_ATU_CR1 0x904
-#define PCIE_ATU_TYPE_MEM (0x0 << 0)
-#define PCIE_ATU_TYPE_IO (0x2 << 0)
-#define PCIE_ATU_TYPE_CFG0 (0x4 << 0)
-#define PCIE_ATU_TYPE_CFG1 (0x5 << 0)
+#define PCIE_ATU_TYPE_MEM 0x0
+#define PCIE_ATU_TYPE_IO 0x2
+#define PCIE_ATU_TYPE_CFG0 0x4
+#define PCIE_ATU_TYPE_CFG1 0x5
#define PCIE_ATU_CR2 0x908
-#define PCIE_ATU_ENABLE (0x1 << 31)
-#define PCIE_ATU_BAR_MODE_ENABLE (0x1 << 30)
+#define PCIE_ATU_ENABLE BIT(31)
+#define PCIE_ATU_BAR_MODE_ENABLE BIT(30)
#define PCIE_ATU_LOWER_BASE 0x90C
#define PCIE_ATU_UPPER_BASE 0x910
#define PCIE_ATU_LIMIT 0x914
#define PCIE_ATU_LOWER_TARGET 0x918
-#define PCIE_ATU_BUS(x) (((x) & 0xff) << 24)
-#define PCIE_ATU_DEV(x) (((x) & 0x1f) << 19)
-#define PCIE_ATU_FUNC(x) (((x) & 0x7) << 16)
+#define PCIE_ATU_BUS(x) FIELD_PREP(GENMASK(31, 24), x)
+#define PCIE_ATU_DEV(x) FIELD_PREP(GENMASK(23, 19), x)
+#define PCIE_ATU_FUNC(x) FIELD_PREP(GENMASK(18, 16), x)
#define PCIE_ATU_UPPER_TARGET 0x91C
+#define PCIE_MISC_CONTROL_1_OFF 0x8BC
+#define PCIE_DBI_RO_WR_EN BIT(0)
+
+#define PCIE_PL_CHK_REG_CONTROL_STATUS 0xB20
+#define PCIE_PL_CHK_REG_CHK_REG_START BIT(0)
+#define PCIE_PL_CHK_REG_CHK_REG_CONTINUOUS BIT(1)
+#define PCIE_PL_CHK_REG_CHK_REG_COMPARISON_ERROR BIT(16)
+#define PCIE_PL_CHK_REG_CHK_REG_LOGIC_ERROR BIT(17)
+#define PCIE_PL_CHK_REG_CHK_REG_COMPLETE BIT(18)
+
+#define PCIE_PL_CHK_REG_ERR_ADDR 0xB28
+
/*
* iATU Unroll-specific register definitions
* From 4.80 core version the address translation will be made by unroll
*/
#define PCIE_ATU_UNR_REGION_CTRL1 0x00
#define PCIE_ATU_UNR_REGION_CTRL2 0x04
-#define PCIE_ATU_UNR_LOWER_BASE 0x08
-#define PCIE_ATU_UNR_UPPER_BASE 0x0C
+#define PCIE_ATU_UNR_LOWER_BASE 0x08
+#define PCIE_ATU_UNR_UPPER_BASE 0x0C
#define PCIE_ATU_UNR_LIMIT 0x10
#define PCIE_ATU_UNR_LOWER_TARGET 0x14
#define PCIE_ATU_UNR_UPPER_TARGET 0x18
+/*
+ * The default address offset between dbi_base and atu_base. Root controller
+ * drivers are not required to initialize atu_base if the offset matches this
+ * default; the driver core automatically derives atu_base from dbi_base using
+ * this offset, if atu_base not set.
+ */
+#define DEFAULT_DBI_ATU_OFFSET (0x3 << 20)
+
/* Register address builder */
-#define PCIE_GET_ATU_OUTB_UNR_REG_OFFSET(region) ((0x3 << 20) | (region << 9))
+#define PCIE_GET_ATU_OUTB_UNR_REG_OFFSET(region) \
+ ((region) << 9)
-/* PCIe Port Logic registers */
-#define PLR_OFFSET 0x700
-#define PCIE_PHY_DEBUG_R1 (PLR_OFFSET + 0x2c)
-#define PCIE_PHY_DEBUG_R1_LINK_UP (0x1 << 4)
-#define PCIE_PHY_DEBUG_R1_LINK_IN_TRAINING (0x1 << 29)
+#define PCIE_GET_ATU_INB_UNR_REG_OFFSET(region) \
+ (((region) << 9) | BIT(8))
-#define PCIE_MISC_CONTROL_1_OFF 0x8BC
-#define PCIE_DBI_RO_WR_EN (0x1 << 0)
+#define MAX_MSI_IRQS 256
+#define MAX_MSI_IRQS_PER_CTRL 32
+#define MAX_MSI_CTRLS (MAX_MSI_IRQS / MAX_MSI_IRQS_PER_CTRL)
+#define MSI_REG_CTRL_BLOCK_SIZE 12
+#define MSI_DEF_NUM_VECTORS 32
-/* PCIe Port Logic registers */
-#define PLR_OFFSET 0x700
-#define PCIE_PHY_DEBUG_R1 (PLR_OFFSET + 0x2c)
-#define PCIE_PHY_DEBUG_R1_LINK_UP (0x1 << 4)
-#define PCIE_PHY_DEBUG_R1_LINK_IN_TRAINING (0x1 << 29)
+/* Maximum number of inbound/outbound iATUs */
+#define MAX_IATU_IN 256
+#define MAX_IATU_OUT 256
struct pcie_port;
struct dw_pcie;
+enum dw_pcie_region_type {
+ DW_PCIE_REGION_UNKNOWN,
+ DW_PCIE_REGION_INBOUND,
+ DW_PCIE_REGION_OUTBOUND,
+};
+
struct dw_pcie_host_ops {
int (*rd_own_conf)(struct pcie_port *pp, int where, int size, u32 *val);
int (*wr_own_conf)(struct pcie_port *pp, int where, int size, u32 val);
@@ -134,20 +172,23 @@ struct pcie_port {
};
struct dw_pcie_ops {
- u32 (*readl_dbi)(struct dw_pcie *pcie, void __iomem *base, u32 reg,
- size_t size);
- void (*writel_dbi)(struct dw_pcie *pcie, void __iomem *base, u32 reg,
- size_t size, u32 val);
+ u32 (*read_dbi)(struct dw_pcie *pcie, void __iomem *base, u32 reg,
+ size_t size);
+ void (*write_dbi)(struct dw_pcie *pcie, void __iomem *base, u32 reg,
+ size_t size, u32 val);
int (*link_up)(struct dw_pcie *pcie);
};
struct dw_pcie {
struct device_d *dev;
void __iomem *dbi_base;
+ /* Used when iatu_unroll_enabled is true */
+ void __iomem *atu_base;
u32 num_viewport;
u8 iatu_unroll_enabled;
struct pcie_port pp;
const struct dw_pcie_ops *ops;
+ unsigned int version;
};
#define to_dw_pcie_from_pp(port) container_of((port), struct dw_pcie, pp)
@@ -156,26 +197,37 @@ int dw_pcie_read(void __iomem *addr, int size, u32 *val);
int dw_pcie_write(void __iomem *addr, int size, u32 val);
void dw_pcie_setup_rc(struct pcie_port *pp);
int dw_pcie_host_init(struct pcie_port *pp);
-
-u32 __dw_pcie_readl_dbi(struct dw_pcie *pci, void __iomem *addr, u32 reg,
- size_t size);
-void __dw_pcie_writel_dbi(struct dw_pcie *pci, void __iomem *addr, u32 reg,
- size_t size, u32 val);
+u32 dw_pcie_read_dbi(struct dw_pcie *pci, u32 reg, size_t size);
+void dw_pcie_write_dbi(struct dw_pcie *pci, u32 reg, size_t size, u32 val);
+u32 dw_pcie_read_atu(struct dw_pcie *pci, u32 reg, size_t size);
+void dw_pcie_write_atu(struct dw_pcie *pci, u32 reg, size_t size, u32 val);
int dw_pcie_link_up(struct dw_pcie *pci);
int dw_pcie_wait_for_link(struct dw_pcie *pci);
void dw_pcie_prog_outbound_atu(struct dw_pcie *pci, int index,
int type, u64 cpu_addr, u64 pci_addr,
u32 size);
+void dw_pcie_disable_atu(struct dw_pcie *pci, int index,
+ enum dw_pcie_region_type type);
void dw_pcie_setup(struct dw_pcie *pci);
static inline void dw_pcie_writel_dbi(struct dw_pcie *pci, u32 reg, u32 val)
{
- __dw_pcie_writel_dbi(pci, pci->dbi_base, reg, 0x4, val);
+ dw_pcie_write_dbi(pci, reg, 0x4, val);
}
static inline u32 dw_pcie_readl_dbi(struct dw_pcie *pci, u32 reg)
{
- return __dw_pcie_readl_dbi(pci, pci->dbi_base, reg, 0x4);
+ return dw_pcie_read_dbi(pci, reg, 0x4);
+}
+
+static inline void dw_pcie_writel_atu(struct dw_pcie *pci, u32 reg, u32 val)
+{
+ dw_pcie_write_atu(pci, reg, 0x4, val);
+}
+
+static inline u32 dw_pcie_readl_atu(struct dw_pcie *pci, u32 reg)
+{
+ return dw_pcie_read_atu(pci, reg, 0x4);
}
static inline void dw_pcie_dbi_ro_wr_en(struct dw_pcie *pci)
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 7a411d456e..bd02fe2137 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -97,6 +97,14 @@ config DRIVER_SERIAL_NS16550_OMAP_EXTENSIONS
help
Say Y here if you are using OMAP extensions to NS16550
+config DRIVER_SERIAL_NS16550_PCI
+ depends on DRIVER_SERIAL_NS16550
+ depends on PCI
+ default y
+ bool "NS16550 PCI serial driver"
+ help
+ Enable this to get support for NS16550 UARTs connected over PCI
+
config DRIVER_SERIAL_PL010
depends on ARCH_EP93XX
default y
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index 6f9e3b7835..8a2abbbe45 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_DRIVER_SERIAL_LINUX_CONSOLE) += linux_console.o
obj-$(CONFIG_DRIVER_SERIAL_MPC5XXX) += serial_mpc5xxx.o
obj-$(CONFIG_DRIVER_SERIAL_CLPS711X) += serial_clps711x.o
obj-$(CONFIG_DRIVER_SERIAL_NS16550) += serial_ns16550.o
+obj-$(CONFIG_DRIVER_SERIAL_NS16550_PCI) += serial_ns16550_pci.o
obj-$(CONFIG_DRIVER_SERIAL_PL010) += serial_pl010.o
obj-$(CONFIG_DRIVER_SERIAL_S3C) += serial_s3c.o
obj-$(CONFIG_DRIVER_SERIAL_STM32) += serial_stm32.o
diff --git a/drivers/serial/serial_ns16550_pci.c b/drivers/serial/serial_ns16550_pci.c
new file mode 100644
index 0000000000..d4b5bd8898
--- /dev/null
+++ b/drivers/serial/serial_ns16550_pci.c
@@ -0,0 +1,5311 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Probe module for 8250/16550-type PCI serial ports.
+ *
+ * Based on Linux drivers/tty/serial/8250_pci.c
+ * Itself based on Linux drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
+ *
+ * Copyright (C) 2001 Russell King, All Rights Reserved.
+ * Copyright (C) 2019 Ahmad Fatoum, Pengutronix
+ */
+
+#include <common.h>
+#include <init.h>
+#include <linux/pci.h>
+#include <driver.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/bitops.h>
+
+#include <asm/byteorder.h>
+#include <asm/io.h>
+
+#include <platform_data/serial-ns16550.h>
+#include "serial_ns16550.h"
+
+#define PCI_NUM_BAR_RESOURCES 6
+
+#define FL_BASE_MASK 0x0007
+#define FL_BASE0 0x0000
+#define FL_BASE1 0x0001
+#define FL_BASE2 0x0002
+#define FL_BASE3 0x0003
+#define FL_BASE4 0x0004
+#define FL_GET_BASE(x) (x & FL_BASE_MASK)
+
+/* Use successive BARs (PCI base address registers),
+ else use offset into some specified BAR */
+#define FL_BASE_BARS 0x0008
+
+/* do not assign an irq; no-op, we use no irqs */
+#define FL_NOIRQ 0x0080
+
+/* Use the Base address register size to cap number of ports */
+#define FL_REGION_SZ_CAP 0x0100
+
+
+struct uart_8250_port {
+ struct NS16550_plat *pdata;
+ struct resource resource;
+
+};
+
+struct pciserial_board {
+ unsigned int flags;
+ unsigned int num_ports;
+ unsigned int base_baud;
+ unsigned int uart_offset;
+ unsigned int reg_shift;
+ unsigned int first_offset;
+};
+
+struct serial_private;
+
+/*
+ * init function returns:
+ * > 0 - number of ports
+ * = 0 - use board->num_ports
+ * < 0 - error
+ */
+struct pci_serial_quirk {
+ u32 vendor;
+ u32 device;
+ u32 subvendor;
+ u32 subdevice;
+ int (*probe)(struct pci_dev *dev);
+ int (*init)(struct pci_dev *dev);
+ int (*setup)(struct serial_private *,
+ const struct pciserial_board *,
+ struct uart_8250_port *, int);
+ void (*exit)(struct pci_dev *dev);
+};
+
+#define PCI_NUM_BAR_RESOURCES 6
+
+struct serial_private {
+ struct pci_dev *dev;
+ unsigned int nr;
+ struct pci_serial_quirk *quirk;
+ const struct pciserial_board *board;
+ void *private_data; /* for use by quirks */
+};
+
+static int pci_default_setup(struct serial_private*,
+ const struct pciserial_board*, struct uart_8250_port *, int);
+
+static void moan_device(const char *str, struct pci_dev *dev)
+{
+ dev_err(&dev->dev,
+ "%s: %s\n"
+ "Please send the output of lspci -vv, this\n"
+ "message (0x%04x,0x%04x,0x%04x,0x%04x), the\n"
+ "manufacturer and name of serial board or\n"
+ "modem board to <linux-serial@vger.kernel.org>.\n",
+ dev_name(&dev->dev), str, dev->vendor, dev->device,
+ dev->subsystem_vendor, dev->subsystem_device);
+}
+
+static int
+setup_port(struct serial_private *priv, struct uart_8250_port *port,
+ int bar, int offset, int regshift)
+{
+ struct pci_dev *dev = priv->dev;
+
+ if (bar >= PCI_NUM_BAR_RESOURCES)
+ return -EINVAL;
+
+ port->resource.flags = IORESOURCE_MEM_8BIT;
+
+ if (pci_resource_flags(dev, bar) & IORESOURCE_MEM) {
+ if (!pci_iomap(dev, bar))
+ return -ENOMEM;
+
+ port->resource.flags |= IORESOURCE_MEM;
+ } else {
+ port->resource.flags |= IORESOURCE_IO;
+ }
+
+ port->resource.start = pci_resource_start(dev, bar) + offset;
+ port->resource.end = port->resource.start + pci_resource_len(dev, bar) - 1;
+
+ port->pdata->shift = regshift;
+
+ return 0;
+}
+
+/*
+ * ADDI-DATA GmbH communication cards <info@addi-data.com>
+ */
+static int addidata_apci7800_setup(struct serial_private *priv,
+ const struct pciserial_board *board,
+ struct uart_8250_port *port, int idx)
+{
+ unsigned int bar = 0, offset = board->first_offset;
+ bar = FL_GET_BASE(board->flags);
+
+ if (idx < 2) {
+ offset += idx * board->uart_offset;
+ } else if ((idx >= 2) && (idx < 4)) {
+ bar += 1;
+ offset += ((idx - 2) * board->uart_offset);
+ } else if ((idx >= 4) && (idx < 6)) {
+ bar += 2;
+ offset += ((idx - 4) * board->uart_offset);
+ } else if (idx >= 6) {
+ bar += 3;
+ offset += ((idx - 6) * board->uart_offset);
+ }
+
+ return setup_port(priv, port, bar, offset, board->reg_shift);
+}
+
+/*
+ * AFAVLAB uses a different mixture of BARs and offsets
+ * Not that ugly ;) -- HW
+ */
+static int
+afavlab_setup(struct serial_private *priv, const struct pciserial_board *board,
+ struct uart_8250_port *port, int idx)
+{
+ unsigned int bar, offset = board->first_offset;
+
+ bar = FL_GET_BASE(board->flags);
+ if (idx < 4)
+ bar += idx;
+ else {
+ bar = 4;
+ offset += (idx - 4) * board->uart_offset;
+ }
+
+ return setup_port(priv, port, bar, offset, board->reg_shift);
+}
+
+/*
+ * HP's Remote Management Console. The Diva chip came in several
+ * different versions. N-class, L2000 and A500 have two Diva chips, each
+ * with 3 UARTs (the third UART on the second chip is unused). Superdome
+ * and Keystone have one Diva chip with 3 UARTs. Some later machines have
+ * one Diva chip, but it has been expanded to 5 UARTs.
+ */
+static int pci_hp_diva_init(struct pci_dev *dev)
+{
+ int rc = 0;
+
+ switch (dev->subsystem_device) {
+ case PCI_DEVICE_ID_HP_DIVA_TOSCA1:
+ case PCI_DEVICE_ID_HP_DIVA_HALFDOME:
+ case PCI_DEVICE_ID_HP_DIVA_KEYSTONE:
+ case PCI_DEVICE_ID_HP_DIVA_EVEREST:
+ rc = 3;
+ break;
+ case PCI_DEVICE_ID_HP_DIVA_TOSCA2:
+ rc = 2;
+ break;
+ case PCI_DEVICE_ID_HP_DIVA_MAESTRO:
+ rc = 4;
+ break;
+ case PCI_DEVICE_ID_HP_DIVA_POWERBAR:
+ case PCI_DEVICE_ID_HP_DIVA_HURRICANE:
+ rc = 1;
+ break;
+ }
+
+ return rc;
+}
+
+/*
+ * HP's Diva chip puts the 4th/5th serial port further out, and
+ * some serial ports are supposed to be hidden on certain models.
+ */
+static int
+pci_hp_diva_setup(struct serial_private *priv,
+ const struct pciserial_board *board,
+ struct uart_8250_port *port, int idx)
+{
+ unsigned int offset = board->first_offset;
+ unsigned int bar = FL_GET_BASE(board->flags);
+
+ switch (priv->dev->subsystem_device) {
+ case PCI_DEVICE_ID_HP_DIVA_MAESTRO:
+ if (idx == 3)
+ idx++;
+ break;
+ case PCI_DEVICE_ID_HP_DIVA_EVEREST:
+ if (idx > 0)
+ idx++;
+ if (idx > 2)
+ idx++;
+ break;
+ }
+ if (idx > 2)
+ offset = 0x18;
+
+ offset += idx * board->uart_offset;
+
+ return setup_port(priv, port, bar, offset, board->reg_shift);
+}
+
+/*
+ * Added for EKF Intel i960 serial boards
+ */
+static int pci_inteli960ni_init(struct pci_dev *dev)
+{
+ u32 oldval;
+
+ if (!(dev->subsystem_device & 0x1000))
+ return -ENODEV;
+
+ /* is firmware started? */
+ pci_read_config_dword(dev, 0x44, &oldval);
+ if (oldval == 0x00001000L) { /* RESET value */
+ dev_dbg(&dev->dev, "Local i960 firmware missing\n");
+ return -ENODEV;
+ }
+ return 0;
+}
+
+/*
+ * Some PCI serial cards using the PLX 9050 PCI interface chip require
+ * that the card interrupt be explicitly enabled or disabled. This
+ * seems to be mainly needed on card using the PLX which also use I/O
+ * mapped memory.
+ */
+static int pci_plx9050_init(struct pci_dev *dev)
+{
+ void __iomem *p;
+
+ if ((pci_resource_flags(dev, 0) & IORESOURCE_MEM) == 0) {
+ moan_device("no memory in bar 0", dev);
+ return 0;
+ }
+
+ /*
+ * disable interrupts
+ */
+ p = pci_iomap(dev, 0);
+ if (p == NULL)
+ return -ENOMEM;
+
+ writel(0, p + 0x4c);
+
+ /*
+ * Read the register back to ensure that it took effect.
+ */
+ readl(p + 0x4c);
+
+ return 0;
+}
+
+#define NI8420_INT_ENABLE_REG 0x38
+#define NI8420_INT_ENABLE_BIT 0x2000
+
+/* MITE registers */
+#define MITE_IOWBSR1 0xc4
+#define MITE_IOWCR1 0xf4
+#define MITE_LCIMR1 0x08
+#define MITE_LCIMR2 0x10
+
+#define MITE_LCIMR2_CLR_CPU_IE (1 << 30)
+
+/* SBS Technologies Inc. PMC-OCTPRO and P-OCTAL cards */
+static int
+sbs_setup(struct serial_private *priv, const struct pciserial_board *board,
+ struct uart_8250_port *port, int idx)
+{
+ unsigned int bar, offset = board->first_offset;
+
+ bar = 0;
+
+ if (idx < 4) {
+ /* first four channels map to 0, 0x100, 0x200, 0x300 */
+ offset += idx * board->uart_offset;
+ } else if (idx < 8) {
+ /* last four channels map to 0x1000, 0x1100, 0x1200, 0x1300 */
+ offset += idx * board->uart_offset + 0xC00;
+ } else /* we have only 8 ports on PMC-OCTALPRO */
+ return 1;
+
+ return setup_port(priv, port, bar, offset, board->reg_shift);
+}
+
+/*
+* This does initialization for PMC OCTALPRO cards:
+* maps the device memory, resets the UARTs (needed, bc
+* if the module is removed and inserted again, the card
+* is in the sleep mode) and enables global interrupt.
+*/
+
+/* global control register offset for SBS PMC-OctalPro */
+#define OCT_REG_CR_OFF 0x500
+
+static int sbs_init(struct pci_dev *dev)
+{
+ u8 __iomem *p;
+
+ p = pci_iomap(dev, 0);
+
+ if (p == NULL)
+ return -ENOMEM;
+ /* Set bit-4 Control Register (UART RESET) in to reset the uarts */
+ writeb(0x10, p + OCT_REG_CR_OFF);
+ udelay(50);
+ writeb(0x0, p + OCT_REG_CR_OFF);
+
+ /* Clear especially bit-2 (INTENABLE) of Control Register */
+ writeb(0, p + OCT_REG_CR_OFF);
+
+ return 0;
+}
+
+/*
+ * SIIG serial cards have an PCI interface chip which also controls
+ * the UART clocking frequency. Each UART can be clocked independently
+ * (except cards equipped with 4 UARTs) and initial clocking settings
+ * are stored in the EEPROM chip. It can cause problems because this
+ * version of serial driver doesn't support differently clocked UART's
+ * on single PCI card. To prevent this, initialization functions set
+ * high frequency clocking for all UART's on given card. It is safe (I
+ * hope) because it doesn't touch EEPROM settings to prevent conflicts
+ * with other OSes (like M$ DOS).
+ *
+ * SIIG support added by Andrey Panin <pazke@donpac.ru>, 10/1999
+ *
+ * There is two family of SIIG serial cards with different PCI
+ * interface chip and different configuration methods:
+ * - 10x cards have control registers in IO and/or memory space;
+ * - 20x cards have control registers in standard PCI configuration space.
+ *
+ * Note: all 10x cards have PCI device ids 0x10..
+ * all 20x cards have PCI device ids 0x20..
+ *
+ * There are also Quartet Serial cards which use Oxford Semiconductor
+ * 16954 quad UART PCI chip clocked by 18.432 MHz quartz.
+ *
+ * Note: some SIIG cards are probed by the parport_serial object.
+ */
+
+#define PCI_DEVICE_ID_SIIG_1S_10x (PCI_DEVICE_ID_SIIG_1S_10x_550 & 0xfffc)
+#define PCI_DEVICE_ID_SIIG_2S_10x (PCI_DEVICE_ID_SIIG_2S_10x_550 & 0xfff8)
+
+static int pci_siig10x_init(struct pci_dev *dev)
+{
+ u16 data;
+ void __iomem *p;
+
+ switch (dev->device & 0xfff8) {
+ case PCI_DEVICE_ID_SIIG_1S_10x: /* 1S */
+ data = 0xffdf;
+ break;
+ case PCI_DEVICE_ID_SIIG_2S_10x: /* 2S, 2S1P */
+ data = 0xf7ff;
+ break;
+ default: /* 1S1P, 4S */
+ data = 0xfffb;
+ break;
+ }
+
+ p = pci_iomap(dev, 0);
+ if (p == NULL)
+ return -ENOMEM;
+
+ writew(readw(p + 0x28) & data, p + 0x28);
+ readw(p + 0x28);
+
+
+ return 0;
+}
+
+#define PCI_DEVICE_ID_SIIG_2S_20x (PCI_DEVICE_ID_SIIG_2S_20x_550 & 0xfffc)
+#define PCI_DEVICE_ID_SIIG_2S1P_20x (PCI_DEVICE_ID_SIIG_2S1P_20x_550 & 0xfffc)
+
+static int pci_siig20x_init(struct pci_dev *dev)
+{
+ u8 data;
+
+ /* Change clock frequency for the first UART. */
+ pci_read_config_byte(dev, 0x6f, &data);
+ pci_write_config_byte(dev, 0x6f, data & 0xef);
+
+ /* If this card has 2 UART, we have to do the same with second UART. */
+ if (((dev->device & 0xfffc) == PCI_DEVICE_ID_SIIG_2S_20x) ||
+ ((dev->device & 0xfffc) == PCI_DEVICE_ID_SIIG_2S1P_20x)) {
+ pci_read_config_byte(dev, 0x73, &data);
+ pci_write_config_byte(dev, 0x73, data & 0xef);
+ }
+ return 0;
+}
+
+static int pci_siig_init(struct pci_dev *dev)
+{
+ unsigned int type = dev->device & 0xff00;
+
+ if (type == 0x1000)
+ return pci_siig10x_init(dev);
+ else if (type == 0x2000)
+ return pci_siig20x_init(dev);
+
+ moan_device("Unknown SIIG card", dev);
+ return -ENODEV;
+}
+
+static int pci_siig_setup(struct serial_private *priv,
+ const struct pciserial_board *board,
+ struct uart_8250_port *port, int idx)
+{
+ unsigned int bar = FL_GET_BASE(board->flags) + idx, offset = 0;
+
+ if (idx > 3) {
+ bar = 4;
+ offset = (idx - 4) * 8;
+ }
+
+ return setup_port(priv, port, bar, offset, 0);
+}
+
+/*
+ * Timedia has an explosion of boards, and to avoid the PCI table from
+ * growing *huge*, we use this function to collapse some 70 entries
+ * in the PCI table into one, for sanity's and compactness's sake.
+ */
+static const unsigned short timedia_single_port[] = {
+ 0x4025, 0x4027, 0x4028, 0x5025, 0x5027, 0
+};
+
+static const unsigned short timedia_dual_port[] = {
+ 0x0002, 0x4036, 0x4037, 0x4038, 0x4078, 0x4079, 0x4085,
+ 0x4088, 0x4089, 0x5037, 0x5078, 0x5079, 0x5085, 0x6079,
+ 0x7079, 0x8079, 0x8137, 0x8138, 0x8237, 0x8238, 0x9079,
+ 0x9137, 0x9138, 0x9237, 0x9238, 0xA079, 0xB079, 0xC079,
+ 0xD079, 0
+};
+
+static const unsigned short timedia_quad_port[] = {
+ 0x4055, 0x4056, 0x4095, 0x4096, 0x5056, 0x8156, 0x8157,
+ 0x8256, 0x8257, 0x9056, 0x9156, 0x9157, 0x9158, 0x9159,
+ 0x9256, 0x9257, 0xA056, 0xA157, 0xA158, 0xA159, 0xB056,
+ 0xB157, 0
+};
+
+static const unsigned short timedia_eight_port[] = {
+ 0x4065, 0x4066, 0x5065, 0x5066, 0x8166, 0x9066, 0x9166,
+ 0x9167, 0x9168, 0xA066, 0xA167, 0xA168, 0
+};
+
+static const struct timedia_struct {
+ int num;
+ const unsigned short *ids;
+} timedia_data[] = {
+ { 1, timedia_single_port },
+ { 2, timedia_dual_port },
+ { 4, timedia_quad_port },
+ { 8, timedia_eight_port }
+};
+
+/*
+ * There are nearly 70 different Timedia/SUNIX PCI serial devices. Instead of
+ * listing them individually, this driver merely grabs them all with
+ * PCI_ANY_ID. Some of these devices, however, also feature a parallel port,
+ * and should be left free to be claimed by parport_serial instead.
+ */
+static int pci_timedia_probe(struct pci_dev *dev)
+{
+ /*
+ * Check the third digit of the subdevice ID
+ * (0,2,3,5,6: serial only -- 7,8,9: serial + parallel)
+ */
+ if ((dev->subsystem_device & 0x00f0) >= 0x70) {
+ dev_info(&dev->dev,
+ "ignoring Timedia subdevice %04x for parport_serial\n",
+ dev->subsystem_device);
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+static int pci_timedia_init(struct pci_dev *dev)
+{
+ const unsigned short *ids;
+ int i, j;
+
+ for (i = 0; i < ARRAY_SIZE(timedia_data); i++) {
+ ids = timedia_data[i].ids;
+ for (j = 0; ids[j]; j++)
+ if (dev->subsystem_device == ids[j])
+ return timedia_data[i].num;
+ }
+ return 0;
+}
+
+/*
+ * Timedia/SUNIX uses a mixture of BARs and offsets
+ * Ugh, this is ugly as all hell --- TYT
+ */
+static int
+pci_timedia_setup(struct serial_private *priv,
+ const struct pciserial_board *board,
+ struct uart_8250_port *port, int idx)
+{
+ unsigned int bar = 0, offset = board->first_offset;
+
+ switch (idx) {
+ case 0:
+ bar = 0;
+ break;
+ case 1:
+ offset = board->uart_offset;
+ bar = 0;
+ break;
+ case 2:
+ bar = 1;
+ break;
+ case 3:
+ offset = board->uart_offset;
+ /* FALLTHROUGH */
+ case 4: /* BAR 2 */
+ case 5: /* BAR 3 */
+ case 6: /* BAR 4 */
+ case 7: /* BAR 5 */
+ bar = idx - 2;
+ }
+
+ return setup_port(priv, port, bar, offset, board->reg_shift);
+}
+
+/*
+ * Some Titan cards are also a little weird
+ */
+static int
+titan_400l_800l_setup(struct serial_private *priv,
+ const struct pciserial_board *board,
+ struct uart_8250_port *port, int idx)
+{
+ unsigned int bar, offset = board->first_offset;
+
+ switch (idx) {
+ case 0:
+ bar = 1;
+ break;
+ case 1:
+ bar = 2;
+ break;
+ default:
+ bar = 4;
+ offset = (idx - 2) * board->uart_offset;
+ }
+
+ return setup_port(priv, port, bar, offset, board->reg_shift);
+}
+
+static int pci_xircom_init(struct pci_dev *dev)
+{
+ mdelay(100);
+ return 0;
+}
+
+static int pci_ni8420_init(struct pci_dev *dev)
+{
+ void __iomem *p;
+ unsigned int bar = 0;
+
+ if ((pci_resource_flags(dev, bar) & IORESOURCE_MEM) == 0) {
+ moan_device("no memory in bar", dev);
+ return 0;
+ }
+
+ p = pci_iomap(dev, bar);
+ if (p == NULL)
+ return -ENOMEM;
+
+ /* Disable the CPU Interrupt */
+ writel(readl(p + NI8420_INT_ENABLE_REG) & ~(NI8420_INT_ENABLE_BIT),
+ p + NI8420_INT_ENABLE_REG);
+
+ return 0;
+}
+
+static int pci_ni8430_init(struct pci_dev *dev)
+{
+ return -ENOSYS;
+}
+
+/* UART Port Control Register */
+#define NI16550_PCR_OFFSET 0x0f
+#define NI16550_PCR_RS422 0x00
+#define NI16550_PCR_ECHO_RS485 0x01
+#define NI16550_PCR_DTR_RS485 0x02
+#define NI16550_PCR_AUTO_RS485 0x03
+#define NI16550_PCR_WIRE_MODE_MASK 0x03
+#define NI16550_PCR_TXVR_ENABLE_BIT BIT(3)
+#define NI16550_PCR_RS485_TERMINATION_BIT BIT(6)
+#define NI16550_ACR_DTR_AUTO_DTR (0x2 << 3)
+#define NI16550_ACR_DTR_MANUAL_DTR (0x0 << 3)
+
+static int
+pci_ni8430_setup(struct serial_private *priv,
+ const struct pciserial_board *board,
+ struct uart_8250_port *port, int idx)
+{
+ struct pci_dev *dev = priv->dev;
+ void __iomem *p;
+ unsigned int bar, offset = board->first_offset;
+
+ if (idx >= board->num_ports)
+ return 1;
+
+ bar = FL_GET_BASE(board->flags);
+ offset += idx * board->uart_offset;
+
+ p = pci_iomap(dev, bar);
+ if (!p)
+ return -ENOMEM;
+
+ /* enable the transceiver */
+ writeb(readb(p + offset + NI16550_PCR_OFFSET) | NI16550_PCR_TXVR_ENABLE_BIT,
+ p + offset + NI16550_PCR_OFFSET);
+
+ return setup_port(priv, port, bar, offset, board->reg_shift);
+}
+
+static int pci_ni8431_setup(struct serial_private *priv,
+ const struct pciserial_board *board,
+ struct uart_8250_port *uart, int idx)
+{
+ return -ENOSYS;
+}
+
+static int pci_netmos_9900_setup(struct serial_private *priv,
+ const struct pciserial_board *board,
+ struct uart_8250_port *port, int idx)
+{
+ unsigned int bar;
+
+ if ((priv->dev->device != PCI_DEVICE_ID_NETMOS_9865) &&
+ (priv->dev->subsystem_device & 0xff00) == 0x3000) {
+ /* netmos apparently orders BARs by datasheet layout, so serial
+ * ports get BARs 0 and 3 (or 1 and 4 for memmapped)
+ */
+ bar = 3 * idx;
+
+ return setup_port(priv, port, bar, 0, board->reg_shift);
+ } else {
+ return pci_default_setup(priv, board, port, idx);
+ }
+}
+
+/* the 99xx series comes with a range of device IDs and a variety
+ * of capabilities:
+ *
+ * 9900 has varying capabilities and can cascade to sub-controllers
+ * (cascading should be purely internal)
+ * 9904 is hardwired with 4 serial ports
+ * 9912 and 9922 are hardwired with 2 serial ports
+ */
+static int pci_netmos_9900_numports(struct pci_dev *dev)
+{
+ unsigned int c = dev->class;
+ unsigned int pi;
+ unsigned short sub_serports;
+
+ pi = c & 0xff;
+
+ if (pi == 2)
+ return 1;
+
+ if ((pi == 0) && (dev->device == PCI_DEVICE_ID_NETMOS_9900)) {
+ /* two possibilities: 0x30ps encodes number of parallel and
+ * serial ports, or 0x1000 indicates *something*. This is not
+ * immediately obvious, since the 2s1p+4s configuration seems
+ * to offer all functionality on functions 0..2, while still
+ * advertising the same function 3 as the 4s+2s1p config.
+ */
+ sub_serports = dev->subsystem_device & 0xf;
+ if (sub_serports > 0)
+ return sub_serports;
+
+ dev_err(&dev->dev,
+ "NetMos/Mostech serial driver ignoring port on ambiguous config.\n");
+ return 0;
+ }
+
+ moan_device("unknown NetMos/Mostech program interface", dev);
+ return 0;
+}
+
+static int pci_netmos_init(struct pci_dev *dev)
+{
+ /* subdevice 0x00PS means <P> parallel, <S> serial */
+ unsigned int num_serial = dev->subsystem_device & 0xf;
+
+ if ((dev->device == PCI_DEVICE_ID_NETMOS_9901) ||
+ (dev->device == PCI_DEVICE_ID_NETMOS_9865))
+ return 0;
+
+ if (dev->subsystem_vendor == PCI_VENDOR_ID_IBM &&
+ dev->subsystem_device == 0x0299)
+ return 0;
+
+ switch (dev->device) { /* FALLTHROUGH on all */
+ case PCI_DEVICE_ID_NETMOS_9904:
+ case PCI_DEVICE_ID_NETMOS_9912:
+ case PCI_DEVICE_ID_NETMOS_9922:
+ case PCI_DEVICE_ID_NETMOS_9900:
+ num_serial = pci_netmos_9900_numports(dev);
+ break;
+
+ default:
+ break;
+ }
+
+ if (num_serial == 0) {
+ moan_device("unknown NetMos/Mostech device", dev);
+ return -ENODEV;
+ }
+
+ return num_serial;
+}
+
+/*
+ * These chips are available with optionally one parallel port and up to
+ * two serial ports. Unfortunately they all have the same product id.
+ *
+ * Basic configuration is done over a region of 32 I/O ports. The base
+ * ioport is called INTA or INTC, depending on docs/other drivers.
+ *
+ * The region of the 32 I/O ports is configured in POSIO0R...
+ */
+
+/* registers */
+#define ITE_887x_MISCR 0x9c
+#define ITE_887x_INTCBAR 0x78
+#define ITE_887x_UARTBAR 0x7c
+#define ITE_887x_PS0BAR 0x10
+#define ITE_887x_POSIO0 0x60
+
+/* I/O space size */
+#define ITE_887x_IOSIZE 32
+/* I/O space size (bits 26-24; 8 bytes = 011b) */
+#define ITE_887x_POSIO_IOSIZE_8 (3 << 24)
+/* I/O space size (bits 26-24; 32 bytes = 101b) */
+#define ITE_887x_POSIO_IOSIZE_32 (5 << 24)
+/* Decoding speed (1 = slow, 2 = medium, 3 = fast) */
+#define ITE_887x_POSIO_SPEED (3 << 29)
+/* enable IO_Space bit */
+#define ITE_887x_POSIO_ENABLE (1 << 31)
+
+static int pci_ite887x_init(struct pci_dev *dev)
+{
+ struct serial_private *priv;
+ /* inta_addr are the configuration addresses of the ITE */
+ static const short inta_addr[] = { 0x2a0, 0x2c0, 0x220, 0x240, 0x1e0,
+ 0x200, 0x280, 0 };
+ int ret, i, type;
+ struct resource *iobase = NULL;
+ u32 miscr, uartbar, ioport;
+
+ /* search for the base-ioport */
+ i = 0;
+ while (inta_addr[i] && iobase == NULL) {
+ iobase = request_ioport_region("ite887x",
+ inta_addr[i],
+ inta_addr[i] + ITE_887x_IOSIZE - 1);
+ if (!IS_ERR(iobase)) {
+ /* write POSIO0R - speed | size | ioport */
+ pci_write_config_dword(dev, ITE_887x_POSIO0,
+ ITE_887x_POSIO_ENABLE | ITE_887x_POSIO_SPEED |
+ ITE_887x_POSIO_IOSIZE_32 | inta_addr[i]);
+ /* write INTCBAR - ioport */
+ pci_write_config_dword(dev, ITE_887x_INTCBAR,
+ inta_addr[i]);
+ ret = inb(inta_addr[i]);
+ if (ret != 0xff) {
+ /* ioport connected */
+ break;
+ }
+ release_region(iobase);
+ iobase = NULL;
+ }
+ i++;
+ }
+
+ if (!inta_addr[i]) {
+ dev_err(&dev->dev, "ite887x: could not find iobase\n");
+ return -ENODEV;
+ }
+
+ /* start of undocumented type checking (see parport_pc.c) */
+ type = inb(iobase->start + 0x18) & 0x0f;
+
+ switch (type) {
+ case 0x2: /* ITE8871 (1P) */
+ case 0xa: /* ITE8875 (1P) */
+ ret = 0;
+ break;
+ case 0xe: /* ITE8872 (2S1P) */
+ ret = 2;
+ break;
+ case 0x6: /* ITE8873 (1S) */
+ ret = 1;
+ break;
+ case 0x8: /* ITE8874 (2S) */
+ ret = 2;
+ break;
+ default:
+ moan_device("Unknown ITE887x", dev);
+ ret = -ENODEV;
+ }
+
+ /* configure all serial ports */
+ for (i = 0; i < ret; i++) {
+ /* read the I/O port from the device */
+ pci_read_config_dword(dev, ITE_887x_PS0BAR + (0x4 * (i + 1)),
+ &ioport);
+ ioport &= 0x0000FF00; /* the actual base address */
+ pci_write_config_dword(dev, ITE_887x_POSIO0 + (0x4 * (i + 1)),
+ ITE_887x_POSIO_ENABLE | ITE_887x_POSIO_SPEED |
+ ITE_887x_POSIO_IOSIZE_8 | ioport);
+
+ /* write the ioport to the UARTBAR */
+ pci_read_config_dword(dev, ITE_887x_UARTBAR, &uartbar);
+ uartbar &= ~(0xffff << (16 * i)); /* clear half the reg */
+ uartbar |= (ioport << (16 * i)); /* set the ioport */
+ pci_write_config_dword(dev, ITE_887x_UARTBAR, uartbar);
+
+ /* get current config */
+ pci_read_config_dword(dev, ITE_887x_MISCR, &miscr);
+ /* disable interrupts (UARTx_Routing[3:0]) */
+ miscr &= ~(0xf << (12 - 4 * i));
+ /* activate the UART (UARTx_En) */
+ miscr |= 1 << (23 - i);
+ /* write new config with activated UART */
+ pci_write_config_dword(dev, ITE_887x_MISCR, miscr);
+ }
+
+ if (ret <= 0) {
+ /* the device has no UARTs if we get here */
+ release_region(iobase);
+ }
+
+ priv = dev->dev.priv;
+ priv->private_data = iobase;
+
+ return ret;
+}
+
+static void pci_ite887x_exit(struct pci_dev *dev)
+{
+ struct serial_private *priv;
+ u32 ioport;
+ /* the ioport is bit 0-15 in POSIO0R */
+ pci_read_config_dword(dev, ITE_887x_POSIO0, &ioport);
+ ioport &= 0xffff;
+
+ priv = dev->dev.priv;
+ if (priv->private_data)
+ release_region(priv->private_data);
+}
+
+/*
+ * EndRun Technologies.
+ * Determine the number of ports available on the device.
+ */
+#define PCI_VENDOR_ID_ENDRUN 0x7401
+#define PCI_DEVICE_ID_ENDRUN_1588 0xe100
+
+static int pci_endrun_init(struct pci_dev *dev)
+{
+ u8 __iomem *p;
+ unsigned long deviceID;
+ unsigned int number_uarts = 0;
+
+ /* EndRun device is all 0xexxx */
+ if (dev->vendor == PCI_VENDOR_ID_ENDRUN &&
+ (dev->device & 0xf000) != 0xe000)
+ return 0;
+
+ p = pci_iomap(dev, 0);
+ if (p == NULL)
+ return -ENOMEM;
+
+ deviceID = ioread32(p);
+ /* EndRun device */
+ if (deviceID == 0x07000200) {
+ number_uarts = ioread8(p + 4);
+ dev_dbg(&dev->dev,
+ "%d ports detected on EndRun PCI Express device\n",
+ number_uarts);
+ }
+
+ return number_uarts;
+}
+
+/*
+ * Oxford Semiconductor Inc.
+ * Check that device is part of the Tornado range of devices, then determine
+ * the number of ports available on the device.
+ */
+static int pci_oxsemi_tornado_init(struct pci_dev *dev)
+{
+ u8 __iomem *p;
+ unsigned long deviceID;
+ unsigned int number_uarts = 0;
+
+ /* OxSemi Tornado devices are all 0xCxxx */
+ if (dev->vendor == PCI_VENDOR_ID_OXSEMI &&
+ (dev->device & 0xF000) != 0xC000)
+ return 0;
+
+ p = pci_iomap(dev, 0);
+ if (p == NULL)
+ return -ENOMEM;
+
+ deviceID = ioread32(p);
+ /* Tornado device */
+ if (deviceID == 0x07000200) {
+ number_uarts = ioread8(p + 4);
+ dev_dbg(&dev->dev,
+ "%d ports detected on Oxford PCI Express device\n",
+ number_uarts);
+ }
+
+ return number_uarts;
+}
+
+static int pci_asix_setup(struct serial_private *priv,
+ const struct pciserial_board *board,
+ struct uart_8250_port *port, int idx)
+{
+ return -ENOSYS;
+}
+
+/* Quatech devices have their own extra interface features */
+
+struct quatech_feature {
+ u16 devid;
+ bool amcc;
+};
+
+#define QPCR_TEST_FOR1 0x3F
+#define QPCR_TEST_GET1 0x00
+#define QPCR_TEST_FOR2 0x40
+#define QPCR_TEST_GET2 0x40
+#define QPCR_TEST_FOR3 0x80
+#define QPCR_TEST_GET3 0x40
+#define QPCR_TEST_FOR4 0xC0
+#define QPCR_TEST_GET4 0x80
+
+#define QOPR_CLOCK_X1 0x0000
+#define QOPR_CLOCK_X2 0x0001
+#define QOPR_CLOCK_X4 0x0002
+#define QOPR_CLOCK_X8 0x0003
+#define QOPR_CLOCK_RATE_MASK 0x0003
+
+
+static struct quatech_feature quatech_cards[] = {
+ { PCI_DEVICE_ID_QUATECH_QSC100, 1 },
+ { PCI_DEVICE_ID_QUATECH_DSC100, 1 },
+ { PCI_DEVICE_ID_QUATECH_DSC100E, 0 },
+ { PCI_DEVICE_ID_QUATECH_DSC200, 1 },
+ { PCI_DEVICE_ID_QUATECH_DSC200E, 0 },
+ { PCI_DEVICE_ID_QUATECH_ESC100D, 1 },
+ { PCI_DEVICE_ID_QUATECH_ESC100M, 1 },
+ { PCI_DEVICE_ID_QUATECH_QSCP100, 1 },
+ { PCI_DEVICE_ID_QUATECH_DSCP100, 1 },
+ { PCI_DEVICE_ID_QUATECH_QSCP200, 1 },
+ { PCI_DEVICE_ID_QUATECH_DSCP200, 1 },
+ { PCI_DEVICE_ID_QUATECH_ESCLP100, 0 },
+ { PCI_DEVICE_ID_QUATECH_QSCLP100, 0 },
+ { PCI_DEVICE_ID_QUATECH_DSCLP100, 0 },
+ { PCI_DEVICE_ID_QUATECH_SSCLP100, 0 },
+ { PCI_DEVICE_ID_QUATECH_QSCLP200, 0 },
+ { PCI_DEVICE_ID_QUATECH_DSCLP200, 0 },
+ { PCI_DEVICE_ID_QUATECH_SSCLP200, 0 },
+ { PCI_DEVICE_ID_QUATECH_SPPXP_100, 0 },
+ { 0, }
+};
+
+static int pci_quatech_amcc(u16 devid)
+{
+ struct quatech_feature *qf = &quatech_cards[0];
+ while (qf->devid) {
+ if (qf->devid == devid)
+ return qf->amcc;
+ qf++;
+ }
+ pr_err("quatech: unknown port type '0x%04X'.\n", devid);
+ return 0;
+};
+
+static int pci_quatech_rqopr(struct uart_8250_port *port)
+{
+ unsigned long base = port->resource.start;
+ u8 LCR, val;
+
+ LCR = inb(base + lcr);
+ outb(0xBF, base + lcr);
+ val = inb(base + scr);
+ outb(LCR, base + lcr);
+ return val;
+}
+
+static void pci_quatech_wqopr(struct uart_8250_port *port, u8 qopr)
+{
+ unsigned long base = port->resource.start;
+ u8 LCR;
+
+ LCR = inb(base + lcr);
+ outb(0xBF, base + lcr);
+ inb(base + scr);
+ outb(qopr, base + scr);
+ outb(LCR, base + lcr);
+}
+
+static int pci_quatech_rqmcr(struct uart_8250_port *port)
+{
+ unsigned long base = port->resource.start;
+ u8 LCR, val, qmcr;
+
+ LCR = inb(base + lcr);
+ outb(0xBF, base + lcr);
+ val = inb(base + scr);
+ outb(val | 0x10, base + scr);
+ qmcr = inb(base + mcr);
+ outb(val, base + scr);
+ outb(LCR, base + lcr);
+
+ return qmcr;
+}
+
+static void pci_quatech_wqmcr(struct uart_8250_port *port, u8 qmcr)
+{
+ unsigned long base = port->resource.start;
+ u8 LCR, val;
+
+ LCR = inb(base + lcr);
+ outb(0xBF, base + lcr);
+ val = inb(base + scr);
+ outb(val | 0x10, base + scr);
+ outb(qmcr, base + mcr);
+ outb(val, base + scr);
+ outb(LCR, base + lcr);
+}
+
+static int pci_quatech_has_qmcr(struct uart_8250_port *port)
+{
+ unsigned long base = port->resource.start;
+ u8 LCR, val;
+
+ LCR = inb(base + lcr);
+ outb(0xBF, base + lcr);
+ val = inb(base + scr);
+ if (val & 0x20) {
+ outb(0x80, lcr);
+ if (!(inb(scr) & 0x20)) {
+ outb(LCR, base + lcr);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static int pci_quatech_test(struct uart_8250_port *port)
+{
+ u8 reg, qopr;
+
+ qopr = pci_quatech_rqopr(port);
+ pci_quatech_wqopr(port, qopr & QPCR_TEST_FOR1);
+ reg = pci_quatech_rqopr(port) & 0xC0;
+ if (reg != QPCR_TEST_GET1)
+ return -EINVAL;
+ pci_quatech_wqopr(port, (qopr & QPCR_TEST_FOR1)|QPCR_TEST_FOR2);
+ reg = pci_quatech_rqopr(port) & 0xC0;
+ if (reg != QPCR_TEST_GET2)
+ return -EINVAL;
+ pci_quatech_wqopr(port, (qopr & QPCR_TEST_FOR1)|QPCR_TEST_FOR3);
+ reg = pci_quatech_rqopr(port) & 0xC0;
+ if (reg != QPCR_TEST_GET3)
+ return -EINVAL;
+ pci_quatech_wqopr(port, (qopr & QPCR_TEST_FOR1)|QPCR_TEST_FOR4);
+ reg = pci_quatech_rqopr(port) & 0xC0;
+ if (reg != QPCR_TEST_GET4)
+ return -EINVAL;
+
+ pci_quatech_wqopr(port, qopr);
+ return 0;
+}
+
+static int pci_quatech_clock(struct uart_8250_port *port)
+{
+ u8 qopr, reg, set;
+ unsigned long clock;
+
+ if (pci_quatech_test(port) < 0)
+ return 1843200;
+
+ qopr = pci_quatech_rqopr(port);
+
+ pci_quatech_wqopr(port, qopr & ~QOPR_CLOCK_X8);
+ reg = pci_quatech_rqopr(port);
+ if (reg & QOPR_CLOCK_X8) {
+ clock = 1843200;
+ goto out;
+ }
+ pci_quatech_wqopr(port, qopr | QOPR_CLOCK_X8);
+ reg = pci_quatech_rqopr(port);
+ if (!(reg & QOPR_CLOCK_X8)) {
+ clock = 1843200;
+ goto out;
+ }
+ reg &= QOPR_CLOCK_X8;
+ if (reg == QOPR_CLOCK_X2) {
+ clock = 3685400;
+ set = QOPR_CLOCK_X2;
+ } else if (reg == QOPR_CLOCK_X4) {
+ clock = 7372800;
+ set = QOPR_CLOCK_X4;
+ } else if (reg == QOPR_CLOCK_X8) {
+ clock = 14745600;
+ set = QOPR_CLOCK_X8;
+ } else {
+ clock = 1843200;
+ set = QOPR_CLOCK_X1;
+ }
+ qopr &= ~QOPR_CLOCK_RATE_MASK;
+ qopr |= set;
+
+out:
+ pci_quatech_wqopr(port, qopr);
+ return clock;
+}
+
+static int pci_quatech_rs422(struct uart_8250_port *port)
+{
+ u8 qmcr;
+ int rs422 = 0;
+
+ if (!pci_quatech_has_qmcr(port))
+ return 0;
+ qmcr = pci_quatech_rqmcr(port);
+ pci_quatech_wqmcr(port, 0xFF);
+ if (pci_quatech_rqmcr(port))
+ rs422 = 1;
+ pci_quatech_wqmcr(port, qmcr);
+ return rs422;
+}
+
+static int pci_quatech_init(struct pci_dev *dev)
+{
+ if (pci_quatech_amcc(dev->device)) {
+ unsigned long base = pci_resource_start(dev, 0);
+ if (base) {
+ u32 tmp;
+
+ outl(inl(base + 0x38) | 0x00002000, base + 0x38);
+ tmp = inl(base + 0x3c);
+ outl(tmp | 0x01000000, base + 0x3c);
+ outl(tmp &= ~0x01000000, base + 0x3c);
+ }
+ }
+ return 0;
+}
+
+static int pci_quatech_setup(struct serial_private *priv,
+ const struct pciserial_board *board,
+ struct uart_8250_port *port, int idx)
+{
+ /* Needed by pci_quatech calls below */
+ port->resource.start = pci_resource_start(priv->dev, FL_GET_BASE(board->flags));
+ /* Set up the clocking */
+ port->pdata->clock = pci_quatech_clock(port);
+ /* For now just warn about RS422 */
+ if (pci_quatech_rs422(port))
+ pr_warn("quatech: software control of RS422 features not currently supported.\n");
+ return pci_default_setup(priv, board, port, idx);
+}
+
+static int pci_default_setup(struct serial_private *priv,
+ const struct pciserial_board *board,
+ struct uart_8250_port *port, int idx)
+{
+ unsigned int bar, offset = board->first_offset, maxnr;
+
+ bar = FL_GET_BASE(board->flags);
+ if (board->flags & FL_BASE_BARS)
+ bar += idx;
+ else
+ offset += idx * board->uart_offset;
+
+ maxnr = (pci_resource_len(priv->dev, bar) - board->first_offset) >>
+ (board->reg_shift + 3);
+
+ if (board->flags & FL_REGION_SZ_CAP && idx >= maxnr)
+ return 1;
+
+ return setup_port(priv, port, bar, offset, board->reg_shift);
+}
+static int pci_pericom_setup(struct serial_private *priv,
+ const struct pciserial_board *board,
+ struct uart_8250_port *port, int idx)
+{
+ return -ENOSYS;
+}
+
+static int pci_pericom_setup_four_at_eight(struct serial_private *priv,
+ const struct pciserial_board *board,
+ struct uart_8250_port *port, int idx)
+{
+ return -ENOSYS;
+}
+
+static int
+ce4100_serial_setup(struct serial_private *priv,
+ const struct pciserial_board *board,
+ struct uart_8250_port *port, int idx)
+{
+ return -ENOSYS;
+}
+
+static int
+pci_omegapci_setup(struct serial_private *priv,
+ const struct pciserial_board *board,
+ struct uart_8250_port *port, int idx)
+{
+ return setup_port(priv, port, 2, idx * 8, 0);
+}
+
+static int
+pci_brcm_trumanage_setup(struct serial_private *priv,
+ const struct pciserial_board *board,
+ struct uart_8250_port *port, int idx)
+{
+ return -ENOSYS;
+}
+
+/* RTS will control by MCR if this bit is 0 */
+#define FINTEK_RTS_CONTROL_BY_HW BIT(4)
+/* only worked with FINTEK_RTS_CONTROL_BY_HW on */
+#define FINTEK_RTS_INVERT BIT(5)
+
+static int pci_fintek_setup(struct serial_private *priv,
+ const struct pciserial_board *board,
+ struct uart_8250_port *port, int idx)
+{
+ struct pci_dev *pdev = priv->dev;
+ u8 config_base;
+ u16 iobase;
+
+ config_base = 0x40 + 0x08 * idx;
+
+ /* Get the io address from configuration space */
+ pci_read_config_word(pdev, config_base + 4, &iobase);
+
+ dev_dbg(&pdev->dev, "%s: idx=%d iobase=0x%x", __func__, idx, iobase);
+
+ port->resource.flags = IORESOURCE_IO;
+ port->resource.start = iobase;
+ port->resource.end = iobase + 8 - 1;
+
+ return 0;
+}
+
+static int pci_fintek_init(struct pci_dev *dev)
+{
+ unsigned long iobase;
+ u32 max_port, i;
+ resource_size_t bar_data[3];
+ u8 config_base;
+
+ if (!(pci_resource_flags(dev, 5) & IORESOURCE_IO) ||
+ !(pci_resource_flags(dev, 4) & IORESOURCE_IO) ||
+ !(pci_resource_flags(dev, 3) & IORESOURCE_IO))
+ return -ENODEV;
+
+ switch (dev->device) {
+ case 0x1104: /* 4 ports */
+ case 0x1108: /* 8 ports */
+ max_port = dev->device & 0xff;
+ break;
+ case 0x1112: /* 12 ports */
+ max_port = 12;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* Get the io address dispatch from the BIOS */
+ bar_data[0] = pci_resource_start(dev, 5);
+ bar_data[1] = pci_resource_start(dev, 4);
+ bar_data[2] = pci_resource_start(dev, 3);
+
+ for (i = 0; i < max_port; ++i) {
+ /* UART0 configuration offset start from 0x40 */
+ config_base = 0x40 + 0x08 * i;
+
+ /* Calculate Real IO Port */
+ iobase = (bar_data[i / 4] & 0xffffffe0) + (i % 4) * 8;
+
+ /* Enable UART I/O port */
+ pci_write_config_byte(dev, config_base + 0x00, 0x01);
+
+ /* Select 128-byte FIFO and 8x FIFO threshold */
+ pci_write_config_byte(dev, config_base + 0x01, 0x33);
+
+ /* LSB UART */
+ pci_write_config_byte(dev, config_base + 0x04,
+ (u8)(iobase & 0xff));
+
+ /* MSB UART */
+ pci_write_config_byte(dev, config_base + 0x05,
+ (u8)((iobase & 0xff00) >> 8));
+
+ /* First init without port data
+ * force init to RS232 Mode
+ */
+ pci_write_config_byte(dev, config_base + 0x07, 0x01);
+ }
+
+ return max_port;
+}
+
+static int pci_fintek_f815xxa_setup(struct serial_private *priv,
+ const struct pciserial_board *board,
+ struct uart_8250_port *port, int idx)
+{
+ return -ENOSYS;
+}
+
+static int pci_fintek_f815xxa_init(struct pci_dev *dev)
+{
+ u32 max_port, i;
+ int config_base;
+
+ if (!(pci_resource_flags(dev, 0) & IORESOURCE_MEM))
+ return -ENODEV;
+
+ switch (dev->device) {
+ case 0x1204: /* 4 ports */
+ case 0x1208: /* 8 ports */
+ max_port = dev->device & 0xff;
+ break;
+ case 0x1212: /* 12 ports */
+ max_port = 12;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* Set to mmio decode */
+ pci_write_config_byte(dev, 0x209, 0x40);
+
+ for (i = 0; i < max_port; ++i) {
+ /* UART0 configuration offset start from 0x2A0 */
+ config_base = 0x2A0 + 0x08 * i;
+
+ /* Select 128-byte FIFO and 8x FIFO threshold */
+ pci_write_config_byte(dev, config_base + 0x01, 0x33);
+
+ /* Enable UART I/O port */
+ pci_write_config_byte(dev, config_base + 0, 0x01);
+ }
+
+ return max_port;
+}
+
+static int skip_tx_en_setup(struct serial_private *priv,
+ const struct pciserial_board *board,
+ struct uart_8250_port *port, int idx)
+{
+ return -ENOSYS;
+}
+
+static int kt_serial_setup(struct serial_private *priv,
+ const struct pciserial_board *board,
+ struct uart_8250_port *port, int idx)
+{
+ return -ENOSYS;
+}
+
+static int
+pci_wch_ch353_setup(struct serial_private *priv,
+ const struct pciserial_board *board,
+ struct uart_8250_port *port, int idx)
+{
+ return -ENOSYS;
+}
+
+static int
+pci_wch_ch355_setup(struct serial_private *priv,
+ const struct pciserial_board *board,
+ struct uart_8250_port *port, int idx)
+{
+ return -ENOSYS;
+}
+
+static int
+pci_wch_ch38x_setup(struct serial_private *priv,
+ const struct pciserial_board *board,
+ struct uart_8250_port *port, int idx)
+{
+ return -ENOSYS;
+}
+
+static int
+pci_sunix_setup(struct serial_private *priv,
+ const struct pciserial_board *board,
+ struct uart_8250_port *port, int idx)
+{
+ return -ENOSYS;
+}
+
+static int
+pci_moxa_setup(struct serial_private *priv,
+ const struct pciserial_board *board,
+ struct uart_8250_port *port, int idx)
+{
+ unsigned int bar = FL_GET_BASE(board->flags);
+ int offset;
+
+ if (board->num_ports == 4 && idx == 3)
+ offset = 7 * board->uart_offset;
+ else
+ offset = idx * board->uart_offset;
+
+ return setup_port(priv, port, bar, offset, 0);
+}
+
+#define PCI_VENDOR_ID_SBSMODULARIO 0x124B
+#define PCI_SUBVENDOR_ID_SBSMODULARIO 0x124B
+#define PCI_DEVICE_ID_OCTPRO 0x0001
+#define PCI_SUBDEVICE_ID_OCTPRO232 0x0108
+#define PCI_SUBDEVICE_ID_OCTPRO422 0x0208
+#define PCI_SUBDEVICE_ID_POCTAL232 0x0308
+#define PCI_SUBDEVICE_ID_POCTAL422 0x0408
+#define PCI_SUBDEVICE_ID_SIIG_DUAL_00 0x2500
+#define PCI_SUBDEVICE_ID_SIIG_DUAL_30 0x2530
+#define PCI_VENDOR_ID_ADVANTECH 0x13fe
+#define PCI_DEVICE_ID_INTEL_CE4100_UART 0x2e66
+#define PCI_DEVICE_ID_ADVANTECH_PCI3620 0x3620
+#define PCI_DEVICE_ID_ADVANTECH_PCI3618 0x3618
+#define PCI_DEVICE_ID_ADVANTECH_PCIf618 0xf618
+#define PCI_DEVICE_ID_TITAN_200I 0x8028
+#define PCI_DEVICE_ID_TITAN_400I 0x8048
+#define PCI_DEVICE_ID_TITAN_800I 0x8088
+#define PCI_DEVICE_ID_TITAN_800EH 0xA007
+#define PCI_DEVICE_ID_TITAN_800EHB 0xA008
+#define PCI_DEVICE_ID_TITAN_400EH 0xA009
+#define PCI_DEVICE_ID_TITAN_100E 0xA010
+#define PCI_DEVICE_ID_TITAN_200E 0xA012
+#define PCI_DEVICE_ID_TITAN_400E 0xA013
+#define PCI_DEVICE_ID_TITAN_800E 0xA014
+#define PCI_DEVICE_ID_TITAN_200EI 0xA016
+#define PCI_DEVICE_ID_TITAN_200EISI 0xA017
+#define PCI_DEVICE_ID_TITAN_200V3 0xA306
+#define PCI_DEVICE_ID_TITAN_400V3 0xA310
+#define PCI_DEVICE_ID_TITAN_410V3 0xA312
+#define PCI_DEVICE_ID_TITAN_800V3 0xA314
+#define PCI_DEVICE_ID_TITAN_800V3B 0xA315
+#define PCI_DEVICE_ID_OXSEMI_16PCI958 0x9538
+#define PCIE_DEVICE_ID_NEO_2_OX_IBM 0x00F6
+#define PCI_DEVICE_ID_PLX_CRONYX_OMEGA 0xc001
+#define PCI_DEVICE_ID_INTEL_PATSBURG_KT 0x1d3d
+#define PCI_VENDOR_ID_WCH 0x4348
+#define PCI_DEVICE_ID_WCH_CH352_2S 0x3253
+#define PCI_DEVICE_ID_WCH_CH353_4S 0x3453
+#define PCI_DEVICE_ID_WCH_CH353_2S1PF 0x5046
+#define PCI_DEVICE_ID_WCH_CH353_1S1P 0x5053
+#define PCI_DEVICE_ID_WCH_CH353_2S1P 0x7053
+#define PCI_DEVICE_ID_WCH_CH355_4S 0x7173
+#define PCI_VENDOR_ID_AGESTAR 0x5372
+#define PCI_DEVICE_ID_AGESTAR_9375 0x6872
+#define PCI_VENDOR_ID_ASIX 0x9710
+#define PCI_DEVICE_ID_BROADCOM_TRUMANAGE 0x160a
+#define PCI_DEVICE_ID_AMCC_ADDIDATA_APCI7800 0x818e
+
+#define PCIE_VENDOR_ID_WCH 0x1c00
+#define PCIE_DEVICE_ID_WCH_CH382_2S1P 0x3250
+#define PCIE_DEVICE_ID_WCH_CH384_4S 0x3470
+#define PCIE_DEVICE_ID_WCH_CH382_2S 0x3253
+
+#define PCI_VENDOR_ID_PERICOM 0x12D8
+#define PCI_DEVICE_ID_PERICOM_PI7C9X7951 0x7951
+#define PCI_DEVICE_ID_PERICOM_PI7C9X7952 0x7952
+#define PCI_DEVICE_ID_PERICOM_PI7C9X7954 0x7954
+#define PCI_DEVICE_ID_PERICOM_PI7C9X7958 0x7958
+
+#define PCI_VENDOR_ID_ACCESIO 0x494f
+#define PCI_DEVICE_ID_ACCESIO_PCIE_COM_2SDB 0x1051
+#define PCI_DEVICE_ID_ACCESIO_MPCIE_COM_2S 0x1053
+#define PCI_DEVICE_ID_ACCESIO_PCIE_COM_4SDB 0x105C
+#define PCI_DEVICE_ID_ACCESIO_MPCIE_COM_4S 0x105E
+#define PCI_DEVICE_ID_ACCESIO_PCIE_COM232_2DB 0x1091
+#define PCI_DEVICE_ID_ACCESIO_MPCIE_COM232_2 0x1093
+#define PCI_DEVICE_ID_ACCESIO_PCIE_COM232_4DB 0x1099
+#define PCI_DEVICE_ID_ACCESIO_MPCIE_COM232_4 0x109B
+#define PCI_DEVICE_ID_ACCESIO_PCIE_COM_2SMDB 0x10D1
+#define PCI_DEVICE_ID_ACCESIO_MPCIE_COM_2SM 0x10D3
+#define PCI_DEVICE_ID_ACCESIO_PCIE_COM_4SMDB 0x10DA
+#define PCI_DEVICE_ID_ACCESIO_MPCIE_COM_4SM 0x10DC
+#define PCI_DEVICE_ID_ACCESIO_MPCIE_ICM485_1 0x1108
+#define PCI_DEVICE_ID_ACCESIO_MPCIE_ICM422_2 0x1110
+#define PCI_DEVICE_ID_ACCESIO_MPCIE_ICM485_2 0x1111
+#define PCI_DEVICE_ID_ACCESIO_MPCIE_ICM422_4 0x1118
+#define PCI_DEVICE_ID_ACCESIO_MPCIE_ICM485_4 0x1119
+#define PCI_DEVICE_ID_ACCESIO_PCIE_ICM_2S 0x1152
+#define PCI_DEVICE_ID_ACCESIO_PCIE_ICM_4S 0x115A
+#define PCI_DEVICE_ID_ACCESIO_PCIE_ICM232_2 0x1190
+#define PCI_DEVICE_ID_ACCESIO_MPCIE_ICM232_2 0x1191
+#define PCI_DEVICE_ID_ACCESIO_PCIE_ICM232_4 0x1198
+#define PCI_DEVICE_ID_ACCESIO_MPCIE_ICM232_4 0x1199
+#define PCI_DEVICE_ID_ACCESIO_PCIE_ICM_2SM 0x11D0
+#define PCI_DEVICE_ID_ACCESIO_PCIE_COM422_4 0x105A
+#define PCI_DEVICE_ID_ACCESIO_PCIE_COM485_4 0x105B
+#define PCI_DEVICE_ID_ACCESIO_PCIE_COM422_8 0x106A
+#define PCI_DEVICE_ID_ACCESIO_PCIE_COM485_8 0x106B
+#define PCI_DEVICE_ID_ACCESIO_PCIE_COM232_4 0x1098
+#define PCI_DEVICE_ID_ACCESIO_PCIE_COM232_8 0x10A9
+#define PCI_DEVICE_ID_ACCESIO_PCIE_COM_4SM 0x10D9
+#define PCI_DEVICE_ID_ACCESIO_PCIE_COM_8SM 0x10E9
+#define PCI_DEVICE_ID_ACCESIO_PCIE_ICM_4SM 0x11D8
+
+#define PCIE_DEVICE_ID_NI_PXIE8430_2328 0x74C2
+#define PCIE_DEVICE_ID_NI_PXIE8430_23216 0x74C1
+#define PCI_DEVICE_ID_NI_PXI8431_4852 0x7081
+#define PCI_DEVICE_ID_NI_PXI8431_4854 0x70DE
+#define PCI_DEVICE_ID_NI_PXI8431_4858 0x70E3
+#define PCI_DEVICE_ID_NI_PXI8433_4852 0x70E9
+#define PCI_DEVICE_ID_NI_PXI8433_4854 0x70ED
+#define PCIE_DEVICE_ID_NI_PXIE8431_4858 0x74C4
+#define PCIE_DEVICE_ID_NI_PXIE8431_48516 0x74C3
+
+#define PCI_DEVICE_ID_MOXA_CP102E 0x1024
+#define PCI_DEVICE_ID_MOXA_CP102EL 0x1025
+#define PCI_DEVICE_ID_MOXA_CP104EL_A 0x1045
+#define PCI_DEVICE_ID_MOXA_CP114EL 0x1144
+#define PCI_DEVICE_ID_MOXA_CP116E_A_A 0x1160
+#define PCI_DEVICE_ID_MOXA_CP116E_A_B 0x1161
+#define PCI_DEVICE_ID_MOXA_CP118EL_A 0x1182
+#define PCI_DEVICE_ID_MOXA_CP118E_A_I 0x1183
+#define PCI_DEVICE_ID_MOXA_CP132EL 0x1322
+#define PCI_DEVICE_ID_MOXA_CP134EL_A 0x1342
+#define PCI_DEVICE_ID_MOXA_CP138E_A 0x1381
+#define PCI_DEVICE_ID_MOXA_CP168EL_A 0x1683
+
+/* Unknown vendors/cards - this should not be in linux/pci_ids.h */
+#define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584
+#define PCI_SUBDEVICE_ID_UNKNOWN_0x1588 0x1588
+
+/*
+ * Master list of serial port init/setup/exit quirks.
+ * This does not describe the general nature of the port.
+ * (ie, baud base, number and location of ports, etc)
+ *
+ * This list is ordered alphabetically by vendor then device.
+ * Specific entries must come before more generic entries.
+ */
+static struct pci_serial_quirk pci_serial_quirks[] = {
+ /*
+ * ADDI-DATA GmbH communication cards <info@addi-data.com>
+ */
+ {
+ .vendor = PCI_VENDOR_ID_AMCC,
+ .device = PCI_DEVICE_ID_AMCC_ADDIDATA_APCI7800,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = addidata_apci7800_setup,
+ },
+ /*
+ * AFAVLAB cards - these may be called via parport_serial
+ * It is not clear whether this applies to all products.
+ */
+ {
+ .vendor = PCI_VENDOR_ID_AFAVLAB,
+ .device = PCI_ANY_ID,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = afavlab_setup,
+ },
+ /*
+ * HP Diva
+ */
+ {
+ .vendor = PCI_VENDOR_ID_HP,
+ .device = PCI_DEVICE_ID_HP_DIVA,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .init = pci_hp_diva_init,
+ .setup = pci_hp_diva_setup,
+ },
+ /*
+ * Intel
+ */
+ {
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_80960_RP,
+ .subvendor = 0xe4bf,
+ .subdevice = PCI_ANY_ID,
+ .init = pci_inteli960ni_init,
+ .setup = pci_default_setup,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_8257X_SOL,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = skip_tx_en_setup,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_82573L_SOL,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = skip_tx_en_setup,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_82573E_SOL,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = skip_tx_en_setup,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_CE4100_UART,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = ce4100_serial_setup,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_PATSBURG_KT,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = kt_serial_setup,
+ },
+ /*
+ * ITE
+ */
+ {
+ .vendor = PCI_VENDOR_ID_ITE,
+ .device = PCI_DEVICE_ID_ITE_8872,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .init = pci_ite887x_init,
+ .setup = pci_default_setup,
+ .exit = pci_ite887x_exit,
+ },
+ /*
+ * National Instruments
+ */
+ {
+ .vendor = PCI_VENDOR_ID_NI,
+ .device = PCI_DEVICE_ID_NI_PCI23216,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .init = pci_ni8420_init,
+ .setup = pci_default_setup,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_NI,
+ .device = PCI_DEVICE_ID_NI_PCI2328,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .init = pci_ni8420_init,
+ .setup = pci_default_setup,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_NI,
+ .device = PCI_DEVICE_ID_NI_PCI2324,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .init = pci_ni8420_init,
+ .setup = pci_default_setup,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_NI,
+ .device = PCI_DEVICE_ID_NI_PCI2322,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .init = pci_ni8420_init,
+ .setup = pci_default_setup,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_NI,
+ .device = PCI_DEVICE_ID_NI_PCI2324I,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .init = pci_ni8420_init,
+ .setup = pci_default_setup,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_NI,
+ .device = PCI_DEVICE_ID_NI_PCI2322I,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .init = pci_ni8420_init,
+ .setup = pci_default_setup,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_NI,
+ .device = PCI_DEVICE_ID_NI_PXI8420_23216,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .init = pci_ni8420_init,
+ .setup = pci_default_setup,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_NI,
+ .device = PCI_DEVICE_ID_NI_PXI8420_2328,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .init = pci_ni8420_init,
+ .setup = pci_default_setup,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_NI,
+ .device = PCI_DEVICE_ID_NI_PXI8420_2324,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .init = pci_ni8420_init,
+ .setup = pci_default_setup,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_NI,
+ .device = PCI_DEVICE_ID_NI_PXI8420_2322,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .init = pci_ni8420_init,
+ .setup = pci_default_setup,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_NI,
+ .device = PCI_DEVICE_ID_NI_PXI8422_2324,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .init = pci_ni8420_init,
+ .setup = pci_default_setup,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_NI,
+ .device = PCI_DEVICE_ID_NI_PXI8422_2322,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .init = pci_ni8420_init,
+ .setup = pci_default_setup,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_NI,
+ .device = PCI_ANY_ID,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .init = pci_ni8430_init,
+ .setup = pci_ni8430_setup,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_NI,
+ .device = PCIE_DEVICE_ID_NI_PXIE8430_2328,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .init = pci_ni8430_init,
+ .setup = pci_ni8430_setup,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_NI,
+ .device = PCIE_DEVICE_ID_NI_PXIE8430_23216,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .init = pci_ni8430_init,
+ .setup = pci_ni8430_setup,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_NI,
+ .device = PCI_DEVICE_ID_NI_PXI8431_4852,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .init = pci_ni8430_init,
+ .setup = pci_ni8431_setup,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_NI,
+ .device = PCI_DEVICE_ID_NI_PXI8431_4854,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .init = pci_ni8430_init,
+ .setup = pci_ni8431_setup,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_NI,
+ .device = PCI_DEVICE_ID_NI_PXI8431_4858,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .init = pci_ni8430_init,
+ .setup = pci_ni8431_setup,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_NI,
+ .device = PCI_DEVICE_ID_NI_PXI8433_4852,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .init = pci_ni8430_init,
+ .setup = pci_ni8431_setup,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_NI,
+ .device = PCI_DEVICE_ID_NI_PXI8433_4854,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .init = pci_ni8430_init,
+ .setup = pci_ni8431_setup,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_NI,
+ .device = PCIE_DEVICE_ID_NI_PXIE8431_4858,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .init = pci_ni8430_init,
+ .setup = pci_ni8431_setup,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_NI,
+ .device = PCIE_DEVICE_ID_NI_PXIE8431_48516,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .init = pci_ni8430_init,
+ .setup = pci_ni8431_setup,
+ },
+ /* Quatech */
+ {
+ .vendor = PCI_VENDOR_ID_QUATECH,
+ .device = PCI_ANY_ID,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .init = pci_quatech_init,
+ .setup = pci_quatech_setup,
+ },
+ /*
+ * Panacom
+ */
+ {
+ .vendor = PCI_VENDOR_ID_PANACOM,
+ .device = PCI_DEVICE_ID_PANACOM_QUADMODEM,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .init = pci_plx9050_init,
+ .setup = pci_default_setup,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_PANACOM,
+ .device = PCI_DEVICE_ID_PANACOM_DUALMODEM,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .init = pci_plx9050_init,
+ .setup = pci_default_setup,
+ },
+ /*
+ * Pericom (Only 7954 - It have a offset jump for port 4)
+ */
+ {
+ .vendor = PCI_VENDOR_ID_PERICOM,
+ .device = PCI_DEVICE_ID_PERICOM_PI7C9X7954,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = pci_pericom_setup_four_at_eight,
+ },
+ /*
+ * PLX
+ */
+ {
+ .vendor = PCI_VENDOR_ID_PLX,
+ .device = PCI_DEVICE_ID_PLX_9050,
+ .subvendor = PCI_SUBVENDOR_ID_EXSYS,
+ .subdevice = PCI_SUBDEVICE_ID_EXSYS_4055,
+ .init = pci_plx9050_init,
+ .setup = pci_default_setup,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_PLX,
+ .device = PCI_DEVICE_ID_PLX_9050,
+ .subvendor = PCI_SUBVENDOR_ID_KEYSPAN,
+ .subdevice = PCI_SUBDEVICE_ID_KEYSPAN_SX2,
+ .init = pci_plx9050_init,
+ .setup = pci_default_setup,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_PLX,
+ .device = PCI_DEVICE_ID_PLX_ROMULUS,
+ .subvendor = PCI_VENDOR_ID_PLX,
+ .subdevice = PCI_DEVICE_ID_PLX_ROMULUS,
+ .init = pci_plx9050_init,
+ .setup = pci_default_setup,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_ACCESIO,
+ .device = PCI_DEVICE_ID_ACCESIO_PCIE_COM_4SDB,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = pci_pericom_setup_four_at_eight,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_ACCESIO,
+ .device = PCI_DEVICE_ID_ACCESIO_MPCIE_COM_4S,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = pci_pericom_setup_four_at_eight,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_ACCESIO,
+ .device = PCI_DEVICE_ID_ACCESIO_PCIE_COM232_4DB,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = pci_pericom_setup_four_at_eight,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_ACCESIO,
+ .device = PCI_DEVICE_ID_ACCESIO_MPCIE_COM232_4,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = pci_pericom_setup_four_at_eight,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_ACCESIO,
+ .device = PCI_DEVICE_ID_ACCESIO_PCIE_COM_4SMDB,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = pci_pericom_setup_four_at_eight,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_ACCESIO,
+ .device = PCI_DEVICE_ID_ACCESIO_MPCIE_COM_4SM,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = pci_pericom_setup_four_at_eight,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_ACCESIO,
+ .device = PCI_DEVICE_ID_ACCESIO_MPCIE_ICM422_4,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = pci_pericom_setup_four_at_eight,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_ACCESIO,
+ .device = PCI_DEVICE_ID_ACCESIO_MPCIE_ICM485_4,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = pci_pericom_setup_four_at_eight,
+ },
+ {
+ .vendor = PCI_DEVICE_ID_ACCESIO_PCIE_ICM_4S,
+ .device = PCI_DEVICE_ID_ACCESIO_PCIE_ICM232_4,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = pci_pericom_setup_four_at_eight,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_ACCESIO,
+ .device = PCI_DEVICE_ID_ACCESIO_MPCIE_ICM232_4,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = pci_pericom_setup_four_at_eight,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_ACCESIO,
+ .device = PCI_DEVICE_ID_ACCESIO_PCIE_COM422_4,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = pci_pericom_setup_four_at_eight,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_ACCESIO,
+ .device = PCI_DEVICE_ID_ACCESIO_PCIE_COM485_4,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = pci_pericom_setup_four_at_eight,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_ACCESIO,
+ .device = PCI_DEVICE_ID_ACCESIO_PCIE_COM232_4,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = pci_pericom_setup_four_at_eight,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_ACCESIO,
+ .device = PCI_DEVICE_ID_ACCESIO_PCIE_COM_4SM,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = pci_pericom_setup_four_at_eight,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_ACCESIO,
+ .device = PCI_DEVICE_ID_ACCESIO_PCIE_ICM_4SM,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = pci_pericom_setup_four_at_eight,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_ACCESIO,
+ .device = PCI_ANY_ID,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = pci_pericom_setup,
+ }, /*
+ * SBS Technologies, Inc., PMC-OCTALPRO 232
+ */
+ {
+ .vendor = PCI_VENDOR_ID_SBSMODULARIO,
+ .device = PCI_DEVICE_ID_OCTPRO,
+ .subvendor = PCI_SUBVENDOR_ID_SBSMODULARIO,
+ .subdevice = PCI_SUBDEVICE_ID_OCTPRO232,
+ .init = sbs_init,
+ .setup = sbs_setup,
+ },
+ /*
+ * SBS Technologies, Inc., PMC-OCTALPRO 422
+ */
+ {
+ .vendor = PCI_VENDOR_ID_SBSMODULARIO,
+ .device = PCI_DEVICE_ID_OCTPRO,
+ .subvendor = PCI_SUBVENDOR_ID_SBSMODULARIO,
+ .subdevice = PCI_SUBDEVICE_ID_OCTPRO422,
+ .init = sbs_init,
+ .setup = sbs_setup,
+ },
+ /*
+ * SBS Technologies, Inc., P-Octal 232
+ */
+ {
+ .vendor = PCI_VENDOR_ID_SBSMODULARIO,
+ .device = PCI_DEVICE_ID_OCTPRO,
+ .subvendor = PCI_SUBVENDOR_ID_SBSMODULARIO,
+ .subdevice = PCI_SUBDEVICE_ID_POCTAL232,
+ .init = sbs_init,
+ .setup = sbs_setup,
+ },
+ /*
+ * SBS Technologies, Inc., P-Octal 422
+ */
+ {
+ .vendor = PCI_VENDOR_ID_SBSMODULARIO,
+ .device = PCI_DEVICE_ID_OCTPRO,
+ .subvendor = PCI_SUBVENDOR_ID_SBSMODULARIO,
+ .subdevice = PCI_SUBDEVICE_ID_POCTAL422,
+ .init = sbs_init,
+ .setup = sbs_setup,
+ },
+ /*
+ * SIIG cards - these may be called via parport_serial
+ */
+ {
+ .vendor = PCI_VENDOR_ID_SIIG,
+ .device = PCI_ANY_ID,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .init = pci_siig_init,
+ .setup = pci_siig_setup,
+ },
+ /*
+ * Titan cards
+ */
+ {
+ .vendor = PCI_VENDOR_ID_TITAN,
+ .device = PCI_DEVICE_ID_TITAN_400L,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = titan_400l_800l_setup,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_TITAN,
+ .device = PCI_DEVICE_ID_TITAN_800L,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = titan_400l_800l_setup,
+ },
+ /*
+ * Timedia cards
+ */
+ {
+ .vendor = PCI_VENDOR_ID_TIMEDIA,
+ .device = PCI_DEVICE_ID_TIMEDIA_1889,
+ .subvendor = PCI_VENDOR_ID_TIMEDIA,
+ .subdevice = PCI_ANY_ID,
+ .probe = pci_timedia_probe,
+ .init = pci_timedia_init,
+ .setup = pci_timedia_setup,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_TIMEDIA,
+ .device = PCI_ANY_ID,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = pci_timedia_setup,
+ },
+ /*
+ * Sunix PCI serial boards
+ */
+ {
+ .vendor = PCI_VENDOR_ID_SUNIX,
+ .device = PCI_DEVICE_ID_SUNIX_1999,
+ .subvendor = PCI_VENDOR_ID_SUNIX,
+ .subdevice = PCI_ANY_ID,
+ .setup = pci_sunix_setup,
+ },
+ /*
+ * Xircom cards
+ */
+ {
+ .vendor = PCI_VENDOR_ID_XIRCOM,
+ .device = PCI_DEVICE_ID_XIRCOM_X3201_MDM,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .init = pci_xircom_init,
+ .setup = pci_default_setup,
+ },
+ /*
+ * Netmos cards - these may be called via parport_serial
+ */
+ {
+ .vendor = PCI_VENDOR_ID_NETMOS,
+ .device = PCI_ANY_ID,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .init = pci_netmos_init,
+ .setup = pci_netmos_9900_setup,
+ },
+ /*
+ * EndRun Technologies
+ */
+ {
+ .vendor = PCI_VENDOR_ID_ENDRUN,
+ .device = PCI_ANY_ID,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .init = pci_endrun_init,
+ .setup = pci_default_setup,
+ },
+ /*
+ * For Oxford Semiconductor Tornado based devices
+ */
+ {
+ .vendor = PCI_VENDOR_ID_OXSEMI,
+ .device = PCI_ANY_ID,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .init = pci_oxsemi_tornado_init,
+ .setup = pci_default_setup,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_MAINPINE,
+ .device = PCI_ANY_ID,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .init = pci_oxsemi_tornado_init,
+ .setup = pci_default_setup,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_DIGI,
+ .device = PCIE_DEVICE_ID_NEO_2_OX_IBM,
+ .subvendor = PCI_SUBVENDOR_ID_IBM,
+ .subdevice = PCI_ANY_ID,
+ .init = pci_oxsemi_tornado_init,
+ .setup = pci_default_setup,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = 0x8811,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = pci_default_setup,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = 0x8812,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = pci_default_setup,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = 0x8813,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = pci_default_setup,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = 0x8814,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = pci_default_setup,
+ },
+ {
+ .vendor = 0x10DB,
+ .device = 0x8027,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = pci_default_setup,
+ },
+ {
+ .vendor = 0x10DB,
+ .device = 0x8028,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = pci_default_setup,
+ },
+ {
+ .vendor = 0x10DB,
+ .device = 0x8029,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = pci_default_setup,
+ },
+ {
+ .vendor = 0x10DB,
+ .device = 0x800C,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = pci_default_setup,
+ },
+ {
+ .vendor = 0x10DB,
+ .device = 0x800D,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = pci_default_setup,
+ },
+ /*
+ * Cronyx Omega PCI (PLX-chip based)
+ */
+ {
+ .vendor = PCI_VENDOR_ID_PLX,
+ .device = PCI_DEVICE_ID_PLX_CRONYX_OMEGA,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = pci_omegapci_setup,
+ },
+ /* WCH CH353 1S1P card (16550 clone) */
+ {
+ .vendor = PCI_VENDOR_ID_WCH,
+ .device = PCI_DEVICE_ID_WCH_CH353_1S1P,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = pci_wch_ch353_setup,
+ },
+ /* WCH CH353 2S1P card (16550 clone) */
+ {
+ .vendor = PCI_VENDOR_ID_WCH,
+ .device = PCI_DEVICE_ID_WCH_CH353_2S1P,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = pci_wch_ch353_setup,
+ },
+ /* WCH CH353 4S card (16550 clone) */
+ {
+ .vendor = PCI_VENDOR_ID_WCH,
+ .device = PCI_DEVICE_ID_WCH_CH353_4S,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = pci_wch_ch353_setup,
+ },
+ /* WCH CH353 2S1PF card (16550 clone) */
+ {
+ .vendor = PCI_VENDOR_ID_WCH,
+ .device = PCI_DEVICE_ID_WCH_CH353_2S1PF,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = pci_wch_ch353_setup,
+ },
+ /* WCH CH352 2S card (16550 clone) */
+ {
+ .vendor = PCI_VENDOR_ID_WCH,
+ .device = PCI_DEVICE_ID_WCH_CH352_2S,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = pci_wch_ch353_setup,
+ },
+ /* WCH CH355 4S card (16550 clone) */
+ {
+ .vendor = PCI_VENDOR_ID_WCH,
+ .device = PCI_DEVICE_ID_WCH_CH355_4S,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = pci_wch_ch355_setup,
+ },
+ /* WCH CH382 2S card (16850 clone) */
+ {
+ .vendor = PCIE_VENDOR_ID_WCH,
+ .device = PCIE_DEVICE_ID_WCH_CH382_2S,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = pci_wch_ch38x_setup,
+ },
+ /* WCH CH382 2S1P card (16850 clone) */
+ {
+ .vendor = PCIE_VENDOR_ID_WCH,
+ .device = PCIE_DEVICE_ID_WCH_CH382_2S1P,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = pci_wch_ch38x_setup,
+ },
+ /* WCH CH384 4S card (16850 clone) */
+ {
+ .vendor = PCIE_VENDOR_ID_WCH,
+ .device = PCIE_DEVICE_ID_WCH_CH384_4S,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = pci_wch_ch38x_setup,
+ },
+ /*
+ * ASIX devices with FIFO bug
+ */
+ {
+ .vendor = PCI_VENDOR_ID_ASIX,
+ .device = PCI_ANY_ID,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = pci_asix_setup,
+ },
+ /*
+ * Broadcom TruManage (NetXtreme)
+ */
+ {
+ .vendor = PCI_VENDOR_ID_BROADCOM,
+ .device = PCI_DEVICE_ID_BROADCOM_TRUMANAGE,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = pci_brcm_trumanage_setup,
+ },
+ {
+ .vendor = 0x1c29,
+ .device = 0x1104,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = pci_fintek_setup,
+ .init = pci_fintek_init,
+ },
+ {
+ .vendor = 0x1c29,
+ .device = 0x1108,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = pci_fintek_setup,
+ .init = pci_fintek_init,
+ },
+ {
+ .vendor = 0x1c29,
+ .device = 0x1112,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = pci_fintek_setup,
+ .init = pci_fintek_init,
+ },
+ /*
+ * MOXA
+ */
+ {
+ .vendor = PCI_VENDOR_ID_MOXA,
+ .device = PCI_ANY_ID,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = pci_moxa_setup,
+ },
+ {
+ .vendor = 0x1c29,
+ .device = 0x1204,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = pci_fintek_f815xxa_setup,
+ .init = pci_fintek_f815xxa_init,
+ },
+ {
+ .vendor = 0x1c29,
+ .device = 0x1208,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = pci_fintek_f815xxa_setup,
+ .init = pci_fintek_f815xxa_init,
+ },
+ {
+ .vendor = 0x1c29,
+ .device = 0x1212,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = pci_fintek_f815xxa_setup,
+ .init = pci_fintek_f815xxa_init,
+ },
+
+ /*
+ * Default "match everything" terminator entry
+ */
+ {
+ .vendor = PCI_ANY_ID,
+ .device = PCI_ANY_ID,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = pci_default_setup,
+ }
+};
+
+static inline int quirk_id_matches(u32 quirk_id, u32 dev_id)
+{
+ return quirk_id == PCI_ANY_ID || quirk_id == dev_id;
+}
+
+static struct pci_serial_quirk *find_quirk(struct pci_dev *dev)
+{
+ struct pci_serial_quirk *quirk;
+
+ for (quirk = pci_serial_quirks; ; quirk++)
+ if (quirk_id_matches(quirk->vendor, dev->vendor) &&
+ quirk_id_matches(quirk->device, dev->device) &&
+ quirk_id_matches(quirk->subvendor, dev->subsystem_vendor) &&
+ quirk_id_matches(quirk->subdevice, dev->subsystem_device))
+ break;
+ return quirk;
+}
+
+/*
+ * This is the configuration table for all of the PCI serial boards
+ * which we support. It is directly indexed by the pci_board_num_t enum
+ * value, which is encoded in the pci_device_id PCI probe table's
+ * driver_data member.
+ *
+ * The makeup of these names are:
+ * pbn_bn{_bt}_n_baud{_offsetinhex}
+ *
+ * bn = PCI BAR number
+ * bt = Index using PCI BARs
+ * n = number of serial ports
+ * baud = baud rate
+ * offsetinhex = offset for each sequential port (in hex)
+ *
+ * This table is sorted by (in order): bn, bt, baud, offsetindex, n.
+ *
+ * Please note: in theory if n = 1, _bt infix should make no difference.
+ * ie, pbn_b0_1_115200 is the same as pbn_b0_bt_1_115200
+ */
+enum pci_board_num_t {
+ pbn_default = 0,
+
+ pbn_b0_1_115200,
+ pbn_b0_2_115200,
+ pbn_b0_4_115200,
+ pbn_b0_5_115200,
+ pbn_b0_8_115200,
+
+ pbn_b0_1_921600,
+ pbn_b0_2_921600,
+ pbn_b0_4_921600,
+
+ pbn_b0_2_1130000,
+
+ pbn_b0_4_1152000,
+
+ pbn_b0_4_1250000,
+
+ pbn_b0_2_1843200,
+ pbn_b0_4_1843200,
+
+ pbn_b0_1_4000000,
+
+ pbn_b0_bt_1_115200,
+ pbn_b0_bt_2_115200,
+ pbn_b0_bt_4_115200,
+ pbn_b0_bt_8_115200,
+
+ pbn_b0_bt_1_460800,
+ pbn_b0_bt_2_460800,
+ pbn_b0_bt_4_460800,
+
+ pbn_b0_bt_1_921600,
+ pbn_b0_bt_2_921600,
+ pbn_b0_bt_4_921600,
+ pbn_b0_bt_8_921600,
+
+ pbn_b1_1_115200,
+ pbn_b1_2_115200,
+ pbn_b1_4_115200,
+ pbn_b1_8_115200,
+ pbn_b1_16_115200,
+
+ pbn_b1_1_921600,
+ pbn_b1_2_921600,
+ pbn_b1_4_921600,
+ pbn_b1_8_921600,
+
+ pbn_b1_2_1250000,
+
+ pbn_b1_bt_1_115200,
+ pbn_b1_bt_2_115200,
+ pbn_b1_bt_4_115200,
+
+ pbn_b1_bt_2_921600,
+
+ pbn_b1_1_1382400,
+ pbn_b1_2_1382400,
+ pbn_b1_4_1382400,
+ pbn_b1_8_1382400,
+
+ pbn_b2_1_115200,
+ pbn_b2_2_115200,
+ pbn_b2_4_115200,
+ pbn_b2_8_115200,
+
+ pbn_b2_1_460800,
+ pbn_b2_4_460800,
+ pbn_b2_8_460800,
+ pbn_b2_16_460800,
+
+ pbn_b2_1_921600,
+ pbn_b2_4_921600,
+ pbn_b2_8_921600,
+
+ pbn_b2_8_1152000,
+
+ pbn_b2_bt_1_115200,
+ pbn_b2_bt_2_115200,
+ pbn_b2_bt_4_115200,
+
+ pbn_b2_bt_2_921600,
+ pbn_b2_bt_4_921600,
+
+ pbn_b3_2_115200,
+ pbn_b3_4_115200,
+ pbn_b3_8_115200,
+
+ pbn_b4_bt_2_921600,
+ pbn_b4_bt_4_921600,
+ pbn_b4_bt_8_921600,
+
+ /*
+ * Board-specific versions.
+ */
+ pbn_panacom,
+ pbn_panacom2,
+ pbn_panacom4,
+ pbn_plx_romulus,
+ pbn_endrun_2_4000000,
+ pbn_oxsemi,
+ pbn_oxsemi_1_4000000,
+ pbn_oxsemi_2_4000000,
+ pbn_oxsemi_4_4000000,
+ pbn_oxsemi_8_4000000,
+ pbn_intel_i960,
+ pbn_sgi_ioc3,
+ pbn_computone_4,
+ pbn_computone_6,
+ pbn_computone_8,
+ pbn_sbsxrsio,
+ pbn_pasemi_1682M,
+ pbn_ni8430_2,
+ pbn_ni8430_4,
+ pbn_ni8430_8,
+ pbn_ni8430_16,
+ pbn_ni8430_pxie_8,
+ pbn_ni8430_pxie_16,
+ pbn_ni8431_2,
+ pbn_ni8431_4,
+ pbn_ni8431_8,
+ pbn_ni8431_pxie_8,
+ pbn_ni8431_pxie_16,
+ pbn_ADDIDATA_PCIe_1_3906250,
+ pbn_ADDIDATA_PCIe_2_3906250,
+ pbn_ADDIDATA_PCIe_4_3906250,
+ pbn_ADDIDATA_PCIe_8_3906250,
+ pbn_ce4100_1_115200,
+ pbn_omegapci,
+ pbn_NETMOS9900_2s_115200,
+ pbn_brcm_trumanage,
+ pbn_fintek_4,
+ pbn_fintek_8,
+ pbn_fintek_12,
+ pbn_fintek_F81504A,
+ pbn_fintek_F81508A,
+ pbn_fintek_F81512A,
+ pbn_wch382_2,
+ pbn_wch384_4,
+ pbn_pericom_PI7C9X7951,
+ pbn_pericom_PI7C9X7952,
+ pbn_pericom_PI7C9X7954,
+ pbn_pericom_PI7C9X7958,
+ pbn_sunix_pci_1s,
+ pbn_sunix_pci_2s,
+ pbn_sunix_pci_4s,
+ pbn_sunix_pci_8s,
+ pbn_sunix_pci_16s,
+ pbn_moxa8250_2p,
+ pbn_moxa8250_4p,
+ pbn_moxa8250_8p,
+};
+
+/*
+ * uart_offset - the space between channels
+ * reg_shift - describes how the UART registers are mapped
+ * to PCI memory by the card.
+ * For example IER register on SBS, Inc. PMC-OctPro is located at
+ * offset 0x10 from the UART base, while UART_IER is defined as 1
+ * in include/linux/serial_reg.h,
+ * see first lines of serial_in() and serial_out() in 8250.c
+*/
+
+static struct pciserial_board pci_boards[] = {
+ [pbn_default] = {
+ .flags = FL_BASE0,
+ .num_ports = 1,
+ .base_baud = 115200,
+ .uart_offset = 8,
+ },
+ [pbn_b0_1_115200] = {
+ .flags = FL_BASE0,
+ .num_ports = 1,
+ .base_baud = 115200,
+ .uart_offset = 8,
+ },
+ [pbn_b0_2_115200] = {
+ .flags = FL_BASE0,
+ .num_ports = 2,
+ .base_baud = 115200,
+ .uart_offset = 8,
+ },
+ [pbn_b0_4_115200] = {
+ .flags = FL_BASE0,
+ .num_ports = 4,
+ .base_baud = 115200,
+ .uart_offset = 8,
+ },
+ [pbn_b0_5_115200] = {
+ .flags = FL_BASE0,
+ .num_ports = 5,
+ .base_baud = 115200,
+ .uart_offset = 8,
+ },
+ [pbn_b0_8_115200] = {
+ .flags = FL_BASE0,
+ .num_ports = 8,
+ .base_baud = 115200,
+ .uart_offset = 8,
+ },
+ [pbn_b0_1_921600] = {
+ .flags = FL_BASE0,
+ .num_ports = 1,
+ .base_baud = 921600,
+ .uart_offset = 8,
+ },
+ [pbn_b0_2_921600] = {
+ .flags = FL_BASE0,
+ .num_ports = 2,
+ .base_baud = 921600,
+ .uart_offset = 8,
+ },
+ [pbn_b0_4_921600] = {
+ .flags = FL_BASE0,
+ .num_ports = 4,
+ .base_baud = 921600,
+ .uart_offset = 8,
+ },
+
+ [pbn_b0_2_1130000] = {
+ .flags = FL_BASE0,
+ .num_ports = 2,
+ .base_baud = 1130000,
+ .uart_offset = 8,
+ },
+
+ [pbn_b0_4_1152000] = {
+ .flags = FL_BASE0,
+ .num_ports = 4,
+ .base_baud = 1152000,
+ .uart_offset = 8,
+ },
+
+ [pbn_b0_4_1250000] = {
+ .flags = FL_BASE0,
+ .num_ports = 4,
+ .base_baud = 1250000,
+ .uart_offset = 8,
+ },
+
+ [pbn_b0_2_1843200] = {
+ .flags = FL_BASE0,
+ .num_ports = 2,
+ .base_baud = 1843200,
+ .uart_offset = 8,
+ },
+ [pbn_b0_4_1843200] = {
+ .flags = FL_BASE0,
+ .num_ports = 4,
+ .base_baud = 1843200,
+ .uart_offset = 8,
+ },
+
+ [pbn_b0_1_4000000] = {
+ .flags = FL_BASE0,
+ .num_ports = 1,
+ .base_baud = 4000000,
+ .uart_offset = 8,
+ },
+
+ [pbn_b0_bt_1_115200] = {
+ .flags = FL_BASE0|FL_BASE_BARS,
+ .num_ports = 1,
+ .base_baud = 115200,
+ .uart_offset = 8,
+ },
+ [pbn_b0_bt_2_115200] = {
+ .flags = FL_BASE0|FL_BASE_BARS,
+ .num_ports = 2,
+ .base_baud = 115200,
+ .uart_offset = 8,
+ },
+ [pbn_b0_bt_4_115200] = {
+ .flags = FL_BASE0|FL_BASE_BARS,
+ .num_ports = 4,
+ .base_baud = 115200,
+ .uart_offset = 8,
+ },
+ [pbn_b0_bt_8_115200] = {
+ .flags = FL_BASE0|FL_BASE_BARS,
+ .num_ports = 8,
+ .base_baud = 115200,
+ .uart_offset = 8,
+ },
+
+ [pbn_b0_bt_1_460800] = {
+ .flags = FL_BASE0|FL_BASE_BARS,
+ .num_ports = 1,
+ .base_baud = 460800,
+ .uart_offset = 8,
+ },
+ [pbn_b0_bt_2_460800] = {
+ .flags = FL_BASE0|FL_BASE_BARS,
+ .num_ports = 2,
+ .base_baud = 460800,
+ .uart_offset = 8,
+ },
+ [pbn_b0_bt_4_460800] = {
+ .flags = FL_BASE0|FL_BASE_BARS,
+ .num_ports = 4,
+ .base_baud = 460800,
+ .uart_offset = 8,
+ },
+
+ [pbn_b0_bt_1_921600] = {
+ .flags = FL_BASE0|FL_BASE_BARS,
+ .num_ports = 1,
+ .base_baud = 921600,
+ .uart_offset = 8,
+ },
+ [pbn_b0_bt_2_921600] = {
+ .flags = FL_BASE0|FL_BASE_BARS,
+ .num_ports = 2,
+ .base_baud = 921600,
+ .uart_offset = 8,
+ },
+ [pbn_b0_bt_4_921600] = {
+ .flags = FL_BASE0|FL_BASE_BARS,
+ .num_ports = 4,
+ .base_baud = 921600,
+ .uart_offset = 8,
+ },
+ [pbn_b0_bt_8_921600] = {
+ .flags = FL_BASE0|FL_BASE_BARS,
+ .num_ports = 8,
+ .base_baud = 921600,
+ .uart_offset = 8,
+ },
+
+ [pbn_b1_1_115200] = {
+ .flags = FL_BASE1,
+ .num_ports = 1,
+ .base_baud = 115200,
+ .uart_offset = 8,
+ },
+ [pbn_b1_2_115200] = {
+ .flags = FL_BASE1,
+ .num_ports = 2,
+ .base_baud = 115200,
+ .uart_offset = 8,
+ },
+ [pbn_b1_4_115200] = {
+ .flags = FL_BASE1,
+ .num_ports = 4,
+ .base_baud = 115200,
+ .uart_offset = 8,
+ },
+ [pbn_b1_8_115200] = {
+ .flags = FL_BASE1,
+ .num_ports = 8,
+ .base_baud = 115200,
+ .uart_offset = 8,
+ },
+ [pbn_b1_16_115200] = {
+ .flags = FL_BASE1,
+ .num_ports = 16,
+ .base_baud = 115200,
+ .uart_offset = 8,
+ },
+
+ [pbn_b1_1_921600] = {
+ .flags = FL_BASE1,
+ .num_ports = 1,
+ .base_baud = 921600,
+ .uart_offset = 8,
+ },
+ [pbn_b1_2_921600] = {
+ .flags = FL_BASE1,
+ .num_ports = 2,
+ .base_baud = 921600,
+ .uart_offset = 8,
+ },
+ [pbn_b1_4_921600] = {
+ .flags = FL_BASE1,
+ .num_ports = 4,
+ .base_baud = 921600,
+ .uart_offset = 8,
+ },
+ [pbn_b1_8_921600] = {
+ .flags = FL_BASE1,
+ .num_ports = 8,
+ .base_baud = 921600,
+ .uart_offset = 8,
+ },
+ [pbn_b1_2_1250000] = {
+ .flags = FL_BASE1,
+ .num_ports = 2,
+ .base_baud = 1250000,
+ .uart_offset = 8,
+ },
+
+ [pbn_b1_bt_1_115200] = {
+ .flags = FL_BASE1|FL_BASE_BARS,
+ .num_ports = 1,
+ .base_baud = 115200,
+ .uart_offset = 8,
+ },
+ [pbn_b1_bt_2_115200] = {
+ .flags = FL_BASE1|FL_BASE_BARS,
+ .num_ports = 2,
+ .base_baud = 115200,
+ .uart_offset = 8,
+ },
+ [pbn_b1_bt_4_115200] = {
+ .flags = FL_BASE1|FL_BASE_BARS,
+ .num_ports = 4,
+ .base_baud = 115200,
+ .uart_offset = 8,
+ },
+
+ [pbn_b1_bt_2_921600] = {
+ .flags = FL_BASE1|FL_BASE_BARS,
+ .num_ports = 2,
+ .base_baud = 921600,
+ .uart_offset = 8,
+ },
+
+ [pbn_b1_1_1382400] = {
+ .flags = FL_BASE1,
+ .num_ports = 1,
+ .base_baud = 1382400,
+ .uart_offset = 8,
+ },
+ [pbn_b1_2_1382400] = {
+ .flags = FL_BASE1,
+ .num_ports = 2,
+ .base_baud = 1382400,
+ .uart_offset = 8,
+ },
+ [pbn_b1_4_1382400] = {
+ .flags = FL_BASE1,
+ .num_ports = 4,
+ .base_baud = 1382400,
+ .uart_offset = 8,
+ },
+ [pbn_b1_8_1382400] = {
+ .flags = FL_BASE1,
+ .num_ports = 8,
+ .base_baud = 1382400,
+ .uart_offset = 8,
+ },
+
+ [pbn_b2_1_115200] = {
+ .flags = FL_BASE2,
+ .num_ports = 1,
+ .base_baud = 115200,
+ .uart_offset = 8,
+ },
+ [pbn_b2_2_115200] = {
+ .flags = FL_BASE2,
+ .num_ports = 2,
+ .base_baud = 115200,
+ .uart_offset = 8,
+ },
+ [pbn_b2_4_115200] = {
+ .flags = FL_BASE2,
+ .num_ports = 4,
+ .base_baud = 115200,
+ .uart_offset = 8,
+ },
+ [pbn_b2_8_115200] = {
+ .flags = FL_BASE2,
+ .num_ports = 8,
+ .base_baud = 115200,
+ .uart_offset = 8,
+ },
+
+ [pbn_b2_1_460800] = {
+ .flags = FL_BASE2,
+ .num_ports = 1,
+ .base_baud = 460800,
+ .uart_offset = 8,
+ },
+ [pbn_b2_4_460800] = {
+ .flags = FL_BASE2,
+ .num_ports = 4,
+ .base_baud = 460800,
+ .uart_offset = 8,
+ },
+ [pbn_b2_8_460800] = {
+ .flags = FL_BASE2,
+ .num_ports = 8,
+ .base_baud = 460800,
+ .uart_offset = 8,
+ },
+ [pbn_b2_16_460800] = {
+ .flags = FL_BASE2,
+ .num_ports = 16,
+ .base_baud = 460800,
+ .uart_offset = 8,
+ },
+
+ [pbn_b2_1_921600] = {
+ .flags = FL_BASE2,
+ .num_ports = 1,
+ .base_baud = 921600,
+ .uart_offset = 8,
+ },
+ [pbn_b2_4_921600] = {
+ .flags = FL_BASE2,
+ .num_ports = 4,
+ .base_baud = 921600,
+ .uart_offset = 8,
+ },
+ [pbn_b2_8_921600] = {
+ .flags = FL_BASE2,
+ .num_ports = 8,
+ .base_baud = 921600,
+ .uart_offset = 8,
+ },
+
+ [pbn_b2_8_1152000] = {
+ .flags = FL_BASE2,
+ .num_ports = 8,
+ .base_baud = 1152000,
+ .uart_offset = 8,
+ },
+
+ [pbn_b2_bt_1_115200] = {
+ .flags = FL_BASE2|FL_BASE_BARS,
+ .num_ports = 1,
+ .base_baud = 115200,
+ .uart_offset = 8,
+ },
+ [pbn_b2_bt_2_115200] = {
+ .flags = FL_BASE2|FL_BASE_BARS,
+ .num_ports = 2,
+ .base_baud = 115200,
+ .uart_offset = 8,
+ },
+ [pbn_b2_bt_4_115200] = {
+ .flags = FL_BASE2|FL_BASE_BARS,
+ .num_ports = 4,
+ .base_baud = 115200,
+ .uart_offset = 8,
+ },
+
+ [pbn_b2_bt_2_921600] = {
+ .flags = FL_BASE2|FL_BASE_BARS,
+ .num_ports = 2,
+ .base_baud = 921600,
+ .uart_offset = 8,
+ },
+ [pbn_b2_bt_4_921600] = {
+ .flags = FL_BASE2|FL_BASE_BARS,
+ .num_ports = 4,
+ .base_baud = 921600,
+ .uart_offset = 8,
+ },
+
+ [pbn_b3_2_115200] = {
+ .flags = FL_BASE3,
+ .num_ports = 2,
+ .base_baud = 115200,
+ .uart_offset = 8,
+ },
+ [pbn_b3_4_115200] = {
+ .flags = FL_BASE3,
+ .num_ports = 4,
+ .base_baud = 115200,
+ .uart_offset = 8,
+ },
+ [pbn_b3_8_115200] = {
+ .flags = FL_BASE3,
+ .num_ports = 8,
+ .base_baud = 115200,
+ .uart_offset = 8,
+ },
+
+ [pbn_b4_bt_2_921600] = {
+ .flags = FL_BASE4,
+ .num_ports = 2,
+ .base_baud = 921600,
+ .uart_offset = 8,
+ },
+ [pbn_b4_bt_4_921600] = {
+ .flags = FL_BASE4,
+ .num_ports = 4,
+ .base_baud = 921600,
+ .uart_offset = 8,
+ },
+ [pbn_b4_bt_8_921600] = {
+ .flags = FL_BASE4,
+ .num_ports = 8,
+ .base_baud = 921600,
+ .uart_offset = 8,
+ },
+
+ /*
+ * Entries following this are board-specific.
+ */
+
+ /*
+ * Panacom - IOMEM
+ */
+ [pbn_panacom] = {
+ .flags = FL_BASE2,
+ .num_ports = 2,
+ .base_baud = 921600,
+ .uart_offset = 0x400,
+ .reg_shift = 7,
+ },
+ [pbn_panacom2] = {
+ .flags = FL_BASE2|FL_BASE_BARS,
+ .num_ports = 2,
+ .base_baud = 921600,
+ .uart_offset = 0x400,
+ .reg_shift = 7,
+ },
+ [pbn_panacom4] = {
+ .flags = FL_BASE2|FL_BASE_BARS,
+ .num_ports = 4,
+ .base_baud = 921600,
+ .uart_offset = 0x400,
+ .reg_shift = 7,
+ },
+
+ /* I think this entry is broken - the first_offset looks wrong --rmk */
+ [pbn_plx_romulus] = {
+ .flags = FL_BASE2,
+ .num_ports = 4,
+ .base_baud = 921600,
+ .uart_offset = 8 << 2,
+ .reg_shift = 2,
+ .first_offset = 0x03,
+ },
+
+ /*
+ * EndRun Technologies
+ * Uses the size of PCI Base region 0 to
+ * signal now many ports are available
+ * 2 port 952 Uart support
+ */
+ [pbn_endrun_2_4000000] = {
+ .flags = FL_BASE0,
+ .num_ports = 2,
+ .base_baud = 4000000,
+ .uart_offset = 0x200,
+ .first_offset = 0x1000,
+ },
+
+ /*
+ * This board uses the size of PCI Base region 0 to
+ * signal now many ports are available
+ */
+ [pbn_oxsemi] = {
+ .flags = FL_BASE0|FL_REGION_SZ_CAP,
+ .num_ports = 32,
+ .base_baud = 115200,
+ .uart_offset = 8,
+ },
+ [pbn_oxsemi_1_4000000] = {
+ .flags = FL_BASE0,
+ .num_ports = 1,
+ .base_baud = 4000000,
+ .uart_offset = 0x200,
+ .first_offset = 0x1000,
+ },
+ [pbn_oxsemi_2_4000000] = {
+ .flags = FL_BASE0,
+ .num_ports = 2,
+ .base_baud = 4000000,
+ .uart_offset = 0x200,
+ .first_offset = 0x1000,
+ },
+ [pbn_oxsemi_4_4000000] = {
+ .flags = FL_BASE0,
+ .num_ports = 4,
+ .base_baud = 4000000,
+ .uart_offset = 0x200,
+ .first_offset = 0x1000,
+ },
+ [pbn_oxsemi_8_4000000] = {
+ .flags = FL_BASE0,
+ .num_ports = 8,
+ .base_baud = 4000000,
+ .uart_offset = 0x200,
+ .first_offset = 0x1000,
+ },
+
+
+ /*
+ * EKF addition for i960 Boards form EKF with serial port.
+ * Max 256 ports.
+ */
+ [pbn_intel_i960] = {
+ .flags = FL_BASE0,
+ .num_ports = 32,
+ .base_baud = 921600,
+ .uart_offset = 8 << 2,
+ .reg_shift = 2,
+ .first_offset = 0x10000,
+ },
+ [pbn_sgi_ioc3] = {
+ .flags = FL_BASE0|FL_NOIRQ,
+ .num_ports = 1,
+ .base_baud = 458333,
+ .uart_offset = 8,
+ .reg_shift = 0,
+ .first_offset = 0x20178,
+ },
+
+ /*
+ * Computone - uses IOMEM.
+ */
+ [pbn_computone_4] = {
+ .flags = FL_BASE0,
+ .num_ports = 4,
+ .base_baud = 921600,
+ .uart_offset = 0x40,
+ .reg_shift = 2,
+ .first_offset = 0x200,
+ },
+ [pbn_computone_6] = {
+ .flags = FL_BASE0,
+ .num_ports = 6,
+ .base_baud = 921600,
+ .uart_offset = 0x40,
+ .reg_shift = 2,
+ .first_offset = 0x200,
+ },
+ [pbn_computone_8] = {
+ .flags = FL_BASE0,
+ .num_ports = 8,
+ .base_baud = 921600,
+ .uart_offset = 0x40,
+ .reg_shift = 2,
+ .first_offset = 0x200,
+ },
+ [pbn_sbsxrsio] = {
+ .flags = FL_BASE0,
+ .num_ports = 8,
+ .base_baud = 460800,
+ .uart_offset = 256,
+ .reg_shift = 4,
+ },
+ /*
+ * PA Semi PWRficient PA6T-1682M on-chip UART
+ */
+ [pbn_pasemi_1682M] = {
+ .flags = FL_BASE0,
+ .num_ports = 1,
+ .base_baud = 8333333,
+ },
+ /*
+ * National Instruments 843x
+ */
+ [pbn_ni8430_16] = {
+ .flags = FL_BASE0,
+ .num_ports = 16,
+ .base_baud = 3686400,
+ .uart_offset = 0x10,
+ .first_offset = 0x800,
+ },
+ [pbn_ni8430_8] = {
+ .flags = FL_BASE0,
+ .num_ports = 8,
+ .base_baud = 3686400,
+ .uart_offset = 0x10,
+ .first_offset = 0x800,
+ },
+ [pbn_ni8430_4] = {
+ .flags = FL_BASE0,
+ .num_ports = 4,
+ .base_baud = 3686400,
+ .uart_offset = 0x10,
+ .first_offset = 0x800,
+ },
+ [pbn_ni8430_2] = {
+ .flags = FL_BASE0,
+ .num_ports = 2,
+ .base_baud = 3686400,
+ .uart_offset = 0x10,
+ .first_offset = 0x800,
+ },
+ [pbn_ni8430_pxie_16] = {
+ .flags = FL_BASE0,
+ .num_ports = 16,
+ .base_baud = 3125000,
+ .uart_offset = 0x10,
+ .first_offset = 0x800,
+ },
+ [pbn_ni8430_pxie_8] = {
+ .flags = FL_BASE0,
+ .num_ports = 8,
+ .base_baud = 3125000,
+ .uart_offset = 0x10,
+ .first_offset = 0x800,
+ },
+ [pbn_ni8431_8] = {
+ .flags = FL_BASE0,
+ .num_ports = 8,
+ .base_baud = 3686400,
+ .uart_offset = 0x10,
+ .first_offset = 0x800,
+ },
+ [pbn_ni8431_4] = {
+ .flags = FL_BASE0,
+ .num_ports = 4,
+ .base_baud = 3686400,
+ .uart_offset = 0x10,
+ .first_offset = 0x800,
+ },
+ [pbn_ni8431_2] = {
+ .flags = FL_BASE0,
+ .num_ports = 2,
+ .base_baud = 3686400,
+ .uart_offset = 0x10,
+ .first_offset = 0x800,
+ },
+ [pbn_ni8431_pxie_16] = {
+ .flags = FL_BASE0,
+ .num_ports = 16,
+ .base_baud = 3125000,
+ .uart_offset = 0x10,
+ .first_offset = 0x800,
+ },
+ [pbn_ni8431_pxie_8] = {
+ .flags = FL_BASE0,
+ .num_ports = 8,
+ .base_baud = 3125000,
+ .uart_offset = 0x10,
+ .first_offset = 0x800,
+ },
+ /*
+ * ADDI-DATA GmbH PCI-Express communication cards <info@addi-data.com>
+ */
+ [pbn_ADDIDATA_PCIe_1_3906250] = {
+ .flags = FL_BASE0,
+ .num_ports = 1,
+ .base_baud = 3906250,
+ .uart_offset = 0x200,
+ .first_offset = 0x1000,
+ },
+ [pbn_ADDIDATA_PCIe_2_3906250] = {
+ .flags = FL_BASE0,
+ .num_ports = 2,
+ .base_baud = 3906250,
+ .uart_offset = 0x200,
+ .first_offset = 0x1000,
+ },
+ [pbn_ADDIDATA_PCIe_4_3906250] = {
+ .flags = FL_BASE0,
+ .num_ports = 4,
+ .base_baud = 3906250,
+ .uart_offset = 0x200,
+ .first_offset = 0x1000,
+ },
+ [pbn_ADDIDATA_PCIe_8_3906250] = {
+ .flags = FL_BASE0,
+ .num_ports = 8,
+ .base_baud = 3906250,
+ .uart_offset = 0x200,
+ .first_offset = 0x1000,
+ },
+ [pbn_ce4100_1_115200] = {
+ .flags = FL_BASE_BARS,
+ .num_ports = 2,
+ .base_baud = 921600,
+ .reg_shift = 2,
+ },
+ [pbn_omegapci] = {
+ .flags = FL_BASE0,
+ .num_ports = 8,
+ .base_baud = 115200,
+ .uart_offset = 0x200,
+ },
+ [pbn_NETMOS9900_2s_115200] = {
+ .flags = FL_BASE0,
+ .num_ports = 2,
+ .base_baud = 115200,
+ },
+ [pbn_brcm_trumanage] = {
+ .flags = FL_BASE0,
+ .num_ports = 1,
+ .reg_shift = 2,
+ .base_baud = 115200,
+ },
+ [pbn_fintek_4] = {
+ .num_ports = 4,
+ .uart_offset = 8,
+ .base_baud = 115200,
+ .first_offset = 0x40,
+ },
+ [pbn_fintek_8] = {
+ .num_ports = 8,
+ .uart_offset = 8,
+ .base_baud = 115200,
+ .first_offset = 0x40,
+ },
+ [pbn_fintek_12] = {
+ .num_ports = 12,
+ .uart_offset = 8,
+ .base_baud = 115200,
+ .first_offset = 0x40,
+ },
+ [pbn_fintek_F81504A] = {
+ .num_ports = 4,
+ .uart_offset = 8,
+ .base_baud = 115200,
+ },
+ [pbn_fintek_F81508A] = {
+ .num_ports = 8,
+ .uart_offset = 8,
+ .base_baud = 115200,
+ },
+ [pbn_fintek_F81512A] = {
+ .num_ports = 12,
+ .uart_offset = 8,
+ .base_baud = 115200,
+ },
+ [pbn_wch382_2] = {
+ .flags = FL_BASE0,
+ .num_ports = 2,
+ .base_baud = 115200,
+ .uart_offset = 8,
+ .first_offset = 0xC0,
+ },
+ [pbn_wch384_4] = {
+ .flags = FL_BASE0,
+ .num_ports = 4,
+ .base_baud = 115200,
+ .uart_offset = 8,
+ .first_offset = 0xC0,
+ },
+ /*
+ * Pericom PI7C9X795[1248] Uno/Dual/Quad/Octal UART
+ */
+ [pbn_pericom_PI7C9X7951] = {
+ .flags = FL_BASE0,
+ .num_ports = 1,
+ .base_baud = 921600,
+ .uart_offset = 0x8,
+ },
+ [pbn_pericom_PI7C9X7952] = {
+ .flags = FL_BASE0,
+ .num_ports = 2,
+ .base_baud = 921600,
+ .uart_offset = 0x8,
+ },
+ [pbn_pericom_PI7C9X7954] = {
+ .flags = FL_BASE0,
+ .num_ports = 4,
+ .base_baud = 921600,
+ .uart_offset = 0x8,
+ },
+ [pbn_pericom_PI7C9X7958] = {
+ .flags = FL_BASE0,
+ .num_ports = 8,
+ .base_baud = 921600,
+ .uart_offset = 0x8,
+ },
+ [pbn_sunix_pci_1s] = {
+ .num_ports = 1,
+ .base_baud = 921600,
+ .uart_offset = 0x8,
+ },
+ [pbn_sunix_pci_2s] = {
+ .num_ports = 2,
+ .base_baud = 921600,
+ .uart_offset = 0x8,
+ },
+ [pbn_sunix_pci_4s] = {
+ .num_ports = 4,
+ .base_baud = 921600,
+ .uart_offset = 0x8,
+ },
+ [pbn_sunix_pci_8s] = {
+ .num_ports = 8,
+ .base_baud = 921600,
+ .uart_offset = 0x8,
+ },
+ [pbn_sunix_pci_16s] = {
+ .num_ports = 16,
+ .base_baud = 921600,
+ .uart_offset = 0x8,
+ },
+ [pbn_moxa8250_2p] = {
+ .flags = FL_BASE1,
+ .num_ports = 2,
+ .base_baud = 921600,
+ .uart_offset = 0x200,
+ },
+ [pbn_moxa8250_4p] = {
+ .flags = FL_BASE1,
+ .num_ports = 4,
+ .base_baud = 921600,
+ .uart_offset = 0x200,
+ },
+ [pbn_moxa8250_8p] = {
+ .flags = FL_BASE1,
+ .num_ports = 8,
+ .base_baud = 921600,
+ .uart_offset = 0x200,
+ },
+};
+
+static const struct pci_device_id blacklist[] = {
+ /* softmodems */
+ { PCI_VDEVICE(AL, 0x5457), }, /* ALi Corporation M5457 AC'97 Modem */
+ { PCI_VDEVICE(MOTOROLA, 0x3052), }, /* Motorola Si3052-based modem */
+ { PCI_DEVICE(0x1543, 0x3052), }, /* Si3052-based modem, default IDs */
+
+ /* multi-io cards handled by parport_serial */
+ { PCI_DEVICE(0x4348, 0x7053), }, /* WCH CH353 2S1P */
+ { PCI_DEVICE(0x4348, 0x5053), }, /* WCH CH353 1S1P */
+ { PCI_DEVICE(0x1c00, 0x3250), }, /* WCH CH382 2S1P */
+
+ /* Intel platforms with MID UART */
+ { PCI_VDEVICE(INTEL, 0x081b), },
+ { PCI_VDEVICE(INTEL, 0x081c), },
+ { PCI_VDEVICE(INTEL, 0x081d), },
+ { PCI_VDEVICE(INTEL, 0x1191), },
+ { PCI_VDEVICE(INTEL, 0x18d8), },
+ { PCI_VDEVICE(INTEL, 0x19d8), },
+
+ /* Intel platforms with DesignWare UART */
+ { PCI_VDEVICE(INTEL, 0x0936), },
+ { PCI_VDEVICE(INTEL, 0x0f0a), },
+ { PCI_VDEVICE(INTEL, 0x0f0c), },
+ { PCI_VDEVICE(INTEL, 0x228a), },
+ { PCI_VDEVICE(INTEL, 0x228c), },
+ { PCI_VDEVICE(INTEL, 0x9ce3), },
+ { PCI_VDEVICE(INTEL, 0x9ce4), },
+
+ /* Exar devices */
+ { PCI_VDEVICE(EXAR, PCI_ANY_ID), },
+ { PCI_VDEVICE(COMMTECH, PCI_ANY_ID), },
+
+ /* End of the black list */
+ { }
+};
+
+static int serial_pci_is_class_communication(struct pci_dev *dev)
+{
+ /*
+ * If it is not a communications device or the programming
+ * interface is greater than 6, give up.
+ */
+ if ((((dev->class >> 8) != PCI_CLASS_COMMUNICATION_SERIAL) &&
+ ((dev->class >> 8) != PCI_CLASS_COMMUNICATION_MULTISERIAL) &&
+ ((dev->class >> 8) != PCI_CLASS_COMMUNICATION_MODEM)) ||
+ (dev->class & 0xff) > 6)
+ return -ENODEV;
+
+ return 0;
+}
+
+/*
+ * Given a complete unknown PCI device, try to use some heuristics to
+ * guess what the configuration might be, based on the pitiful PCI
+ * serial specs. Returns 0 on success, -ENODEV on failure.
+ */
+static int
+serial_pci_guess_board(struct pci_dev *dev, struct pciserial_board *board)
+{
+ int num_iomem, num_port, first_port = -1, i;
+ int rc;
+
+ rc = serial_pci_is_class_communication(dev);
+ if (rc)
+ return rc;
+
+ /*
+ * Should we try to make guesses for multiport serial devices later?
+ */
+ if ((dev->class >> 8) == PCI_CLASS_COMMUNICATION_MULTISERIAL)
+ return -ENODEV;
+
+ num_iomem = num_port = 0;
+ for (i = 0; i < PCI_NUM_BAR_RESOURCES; i++) {
+ if (pci_resource_flags(dev, i) & IORESOURCE_IO) {
+ num_port++;
+ if (first_port == -1)
+ first_port = i;
+ }
+ if (pci_resource_flags(dev, i) & IORESOURCE_MEM)
+ num_iomem++;
+ }
+
+ /*
+ * If there is 1 or 0 iomem regions, and exactly one port,
+ * use it. We guess the number of ports based on the IO
+ * region size.
+ */
+ if (num_iomem <= 1 && num_port == 1) {
+ board->flags = first_port;
+ board->num_ports = pci_resource_len(dev, first_port) / 8;
+ return 0;
+ }
+
+ /*
+ * Now guess if we've got a board which indexes by BARs.
+ * Each IO BAR should be 8 bytes, and they should follow
+ * consecutively.
+ */
+ first_port = -1;
+ num_port = 0;
+ for (i = 0; i < PCI_NUM_BAR_RESOURCES; i++) {
+ if (pci_resource_flags(dev, i) & IORESOURCE_IO &&
+ pci_resource_len(dev, i) == 8 &&
+ (first_port == -1 || (first_port + num_port) == i)) {
+ num_port++;
+ if (first_port == -1)
+ first_port = i;
+ }
+ }
+
+ if (num_port > 1) {
+ board->flags = first_port | FL_BASE_BARS;
+ board->num_ports = num_port;
+ return 0;
+ }
+
+ return -ENODEV;
+}
+
+static inline int
+serial_pci_matches(const struct pciserial_board *board,
+ const struct pciserial_board *guessed)
+{
+ return
+ board->num_ports == guessed->num_ports &&
+ board->base_baud == guessed->base_baud &&
+ board->uart_offset == guessed->uart_offset &&
+ board->reg_shift == guessed->reg_shift &&
+ board->first_offset == guessed->first_offset;
+}
+
+static struct serial_private *
+pciserial_init_ports(struct pci_dev *dev, const struct pciserial_board *board)
+{
+ struct uart_8250_port uart;
+ struct serial_private *priv;
+ struct pci_serial_quirk *quirk;
+ int rc, nr_ports, i;
+
+ nr_ports = board->num_ports;
+
+ /*
+ * Find an init and setup quirks.
+ */
+ quirk = find_quirk(dev);
+
+ /*
+ * Run the new-style initialization function.
+ * The initialization function returns:
+ * <0 - error
+ * 0 - use board->num_ports
+ * >0 - number of ports
+ */
+ if (quirk->init) {
+ rc = quirk->init(dev);
+ if (rc < 0) {
+ priv = ERR_PTR(rc);
+ goto err_out;
+ }
+ if (rc)
+ nr_ports = rc;
+ }
+
+ priv = xzalloc(sizeof(struct serial_private) +
+ sizeof(unsigned int) * nr_ports);
+
+ priv->dev = dev;
+ priv->quirk = quirk;
+
+ memset(&uart, 0, sizeof(uart));
+ uart.pdata = xzalloc(sizeof(*uart.pdata));
+ uart.pdata->clock = board->base_baud * 16;
+
+ if (rc < 0) {
+ kfree(priv);
+ priv = ERR_PTR(rc);
+ goto err_deinit;
+ }
+
+ for (i = 0; i < nr_ports; i++) {
+ struct device_d *ns16550_dev;
+ struct resource *res;
+
+ rc = quirk->setup(priv, board, &uart, i);
+ if (rc == -ENOSYS) {
+ priv = ERR_PTR(-ENOSYS);
+ goto err_deinit;
+ }
+
+ if (rc)
+ break;
+
+ res = &uart.resource;
+
+ dev_dbg(&dev->dev, "setup PCI %s console @ 0x%llx-0x%llx\n",
+ res->flags & IORESOURCE_MEM ? "MMIO" : "IO port",
+ res->start, res->end);
+
+ ns16550_dev = device_alloc("ns16550_serial", DEVICE_ID_DYNAMIC);
+ ns16550_dev->platform_data = uart.pdata;
+ ns16550_dev->parent = &dev->dev;
+ device_add_resource(ns16550_dev, NULL,
+ res->start, res->end - res->start + 1,
+ res->flags);
+
+ rc = platform_device_register(ns16550_dev);
+ if (rc < 0) {
+ dev_err(&dev->dev, "couldn't register PCI %s console @0x%llx: %s\n",
+ res->flags & IORESOURCE_MEM ? "MMIO" : "IO port",
+ res->start, strerror(-rc));
+
+ break;
+ }
+ }
+ priv->nr = i;
+ priv->board = board;
+ return priv;
+
+err_deinit:
+ if (quirk->exit)
+ quirk->exit(dev);
+err_out:
+ return priv;
+}
+
+/*
+ * Probe one serial board. Unfortunately, there is no rhyme nor reason
+ * to the arrangement of serial ports on a PCI card.
+ */
+static int
+pciserial_init_one(struct pci_dev *dev, const struct pci_device_id *ent)
+{
+ struct pci_serial_quirk *quirk;
+ struct serial_private *priv;
+ const struct pciserial_board *board;
+ const struct pci_device_id *exclude;
+ struct pciserial_board tmp;
+ int rc;
+
+ quirk = find_quirk(dev);
+ if (quirk->probe) {
+ rc = quirk->probe(dev);
+ if (rc)
+ return rc;
+ }
+
+ if (ent->driver_data >= ARRAY_SIZE(pci_boards)) {
+ dev_err(&dev->dev, "invalid driver_data: %ld\n",
+ ent->driver_data);
+ return -EINVAL;
+ }
+
+ board = &pci_boards[ent->driver_data];
+
+ exclude = pci_match_id(blacklist, dev);
+ if (exclude)
+ return -ENODEV;
+
+ rc = pci_enable_device(dev);
+ if (rc)
+ return rc;
+
+ if (ent->driver_data == pbn_default) {
+ /*
+ * Use a copy of the pci_board entry for this;
+ * avoid changing entries in the table.
+ */
+ memcpy(&tmp, board, sizeof(struct pciserial_board));
+ board = &tmp;
+
+ /*
+ * We matched one of our class entries. Try to
+ * determine the parameters of this board.
+ */
+ rc = serial_pci_guess_board(dev, &tmp);
+ if (rc)
+ return rc;
+ } else {
+ /*
+ * We matched an explicit entry. If we are able to
+ * detect this boards settings with our heuristic,
+ * then we no longer need this entry.
+ */
+ memcpy(&tmp, &pci_boards[pbn_default],
+ sizeof(struct pciserial_board));
+ rc = serial_pci_guess_board(dev, &tmp);
+ if (rc == 0 && serial_pci_matches(board, &tmp))
+ moan_device("Redundant entry in serial pci_table.",
+ dev);
+ }
+
+ priv = pciserial_init_ports(dev, board);
+ if (IS_ERR(priv)) {
+ if (PTR_ERR(priv) == -ENOSYS) {
+ dev_err(&dev->dev,
+ "serial port requires not-yet-supported quirky behavior.\n"
+ "Consider porting it over from the Linux 8250_pci driver\n");
+ }
+
+ return PTR_ERR(priv);
+ }
+
+ dev->dev.priv = priv;
+ return 0;
+}
+
+static const struct pci_device_id serial_pci_tbl[] = {
+ /* Advantech use PCI_DEVICE_ID_ADVANTECH_PCI3620 (0x3620) as 'PCI_SUBVENDOR_ID' */
+ { PCI_VENDOR_ID_ADVANTECH, PCI_DEVICE_ID_ADVANTECH_PCI3620,
+ PCI_DEVICE_ID_ADVANTECH_PCI3620, 0x0001, 0, 0,
+ pbn_b2_8_921600 },
+ /* Advantech also use 0x3618 and 0xf618 */
+ { PCI_VENDOR_ID_ADVANTECH, PCI_DEVICE_ID_ADVANTECH_PCI3618,
+ PCI_DEVICE_ID_ADVANTECH_PCI3618, PCI_ANY_ID, 0, 0,
+ pbn_b0_4_921600 },
+ { PCI_VENDOR_ID_ADVANTECH, PCI_DEVICE_ID_ADVANTECH_PCIf618,
+ PCI_DEVICE_ID_ADVANTECH_PCI3618, PCI_ANY_ID, 0, 0,
+ pbn_b0_4_921600 },
+ { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V960,
+ PCI_SUBVENDOR_ID_CONNECT_TECH,
+ PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_232, 0, 0,
+ pbn_b1_8_1382400 },
+ { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V960,
+ PCI_SUBVENDOR_ID_CONNECT_TECH,
+ PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_232, 0, 0,
+ pbn_b1_4_1382400 },
+ { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V960,
+ PCI_SUBVENDOR_ID_CONNECT_TECH,
+ PCI_SUBDEVICE_ID_CONNECT_TECH_BH2_232, 0, 0,
+ pbn_b1_2_1382400 },
+ { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
+ PCI_SUBVENDOR_ID_CONNECT_TECH,
+ PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_232, 0, 0,
+ pbn_b1_8_1382400 },
+ { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
+ PCI_SUBVENDOR_ID_CONNECT_TECH,
+ PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_232, 0, 0,
+ pbn_b1_4_1382400 },
+ { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
+ PCI_SUBVENDOR_ID_CONNECT_TECH,
+ PCI_SUBDEVICE_ID_CONNECT_TECH_BH2_232, 0, 0,
+ pbn_b1_2_1382400 },
+ { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
+ PCI_SUBVENDOR_ID_CONNECT_TECH,
+ PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_485, 0, 0,
+ pbn_b1_8_921600 },
+ { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
+ PCI_SUBVENDOR_ID_CONNECT_TECH,
+ PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_485_4_4, 0, 0,
+ pbn_b1_8_921600 },
+ { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
+ PCI_SUBVENDOR_ID_CONNECT_TECH,
+ PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_485, 0, 0,
+ pbn_b1_4_921600 },
+ { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
+ PCI_SUBVENDOR_ID_CONNECT_TECH,
+ PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_485_2_2, 0, 0,
+ pbn_b1_4_921600 },
+ { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
+ PCI_SUBVENDOR_ID_CONNECT_TECH,
+ PCI_SUBDEVICE_ID_CONNECT_TECH_BH2_485, 0, 0,
+ pbn_b1_2_921600 },
+ { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
+ PCI_SUBVENDOR_ID_CONNECT_TECH,
+ PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_485_2_6, 0, 0,
+ pbn_b1_8_921600 },
+ { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
+ PCI_SUBVENDOR_ID_CONNECT_TECH,
+ PCI_SUBDEVICE_ID_CONNECT_TECH_BH081101V1, 0, 0,
+ pbn_b1_8_921600 },
+ { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
+ PCI_SUBVENDOR_ID_CONNECT_TECH,
+ PCI_SUBDEVICE_ID_CONNECT_TECH_BH041101V1, 0, 0,
+ pbn_b1_4_921600 },
+ { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
+ PCI_SUBVENDOR_ID_CONNECT_TECH,
+ PCI_SUBDEVICE_ID_CONNECT_TECH_BH2_20MHZ, 0, 0,
+ pbn_b1_2_1250000 },
+ { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI954,
+ PCI_SUBVENDOR_ID_CONNECT_TECH,
+ PCI_SUBDEVICE_ID_CONNECT_TECH_TITAN_2, 0, 0,
+ pbn_b0_2_1843200 },
+ { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI954,
+ PCI_SUBVENDOR_ID_CONNECT_TECH,
+ PCI_SUBDEVICE_ID_CONNECT_TECH_TITAN_4, 0, 0,
+ pbn_b0_4_1843200 },
+ { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI954,
+ PCI_VENDOR_ID_AFAVLAB,
+ PCI_SUBDEVICE_ID_AFAVLAB_P061, 0, 0,
+ pbn_b0_4_1152000 },
+ { PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_U530,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b2_bt_1_115200 },
+ { PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_UCOMM2,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b2_bt_2_115200 },
+ { PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_UCOMM422,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b2_bt_4_115200 },
+ { PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_UCOMM232,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b2_bt_2_115200 },
+ { PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_COMM4,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b2_bt_4_115200 },
+ { PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_COMM8,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b2_8_115200 },
+ { PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_7803,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b2_8_460800 },
+ { PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_UCOMM8,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b2_8_115200 },
+
+ { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_GTEK_SERIAL2,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b2_bt_2_115200 },
+ { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_SPCOM200,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b2_bt_2_921600 },
+ /*
+ * VScom SPCOM800, from sl@s.pl
+ */
+ { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_SPCOM800,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b2_8_921600 },
+ { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_1077,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b2_4_921600 },
+ /* Unknown card - subdevice 0x1584 */
+ { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
+ PCI_VENDOR_ID_PLX,
+ PCI_SUBDEVICE_ID_UNKNOWN_0x1584, 0, 0,
+ pbn_b2_4_115200 },
+ /* Unknown card - subdevice 0x1588 */
+ { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
+ PCI_VENDOR_ID_PLX,
+ PCI_SUBDEVICE_ID_UNKNOWN_0x1588, 0, 0,
+ pbn_b2_8_115200 },
+ { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
+ PCI_SUBVENDOR_ID_KEYSPAN,
+ PCI_SUBDEVICE_ID_KEYSPAN_SX2, 0, 0,
+ pbn_panacom },
+ { PCI_VENDOR_ID_PANACOM, PCI_DEVICE_ID_PANACOM_QUADMODEM,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_panacom4 },
+ { PCI_VENDOR_ID_PANACOM, PCI_DEVICE_ID_PANACOM_DUALMODEM,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_panacom2 },
+ { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030,
+ PCI_VENDOR_ID_ESDGMBH,
+ PCI_DEVICE_ID_ESDGMBH_CPCIASIO4, 0, 0,
+ pbn_b2_4_115200 },
+ { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
+ PCI_SUBVENDOR_ID_CHASE_PCIFAST,
+ PCI_SUBDEVICE_ID_CHASE_PCIFAST4, 0, 0,
+ pbn_b2_4_460800 },
+ { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
+ PCI_SUBVENDOR_ID_CHASE_PCIFAST,
+ PCI_SUBDEVICE_ID_CHASE_PCIFAST8, 0, 0,
+ pbn_b2_8_460800 },
+ { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
+ PCI_SUBVENDOR_ID_CHASE_PCIFAST,
+ PCI_SUBDEVICE_ID_CHASE_PCIFAST16, 0, 0,
+ pbn_b2_16_460800 },
+ { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
+ PCI_SUBVENDOR_ID_CHASE_PCIFAST,
+ PCI_SUBDEVICE_ID_CHASE_PCIFAST16FMC, 0, 0,
+ pbn_b2_16_460800 },
+ { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
+ PCI_SUBVENDOR_ID_CHASE_PCIRAS,
+ PCI_SUBDEVICE_ID_CHASE_PCIRAS4, 0, 0,
+ pbn_b2_4_460800 },
+ { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
+ PCI_SUBVENDOR_ID_CHASE_PCIRAS,
+ PCI_SUBDEVICE_ID_CHASE_PCIRAS8, 0, 0,
+ pbn_b2_8_460800 },
+ { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
+ PCI_SUBVENDOR_ID_EXSYS,
+ PCI_SUBDEVICE_ID_EXSYS_4055, 0, 0,
+ pbn_b2_4_115200 },
+ /*
+ * Megawolf Romulus PCI Serial Card, from Mike Hudson
+ * (Exoray@isys.ca)
+ */
+ { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_ROMULUS,
+ 0x10b5, 0x106a, 0, 0,
+ pbn_plx_romulus },
+ /*
+ * EndRun Technologies. PCI express device range.
+ * EndRun PTP/1588 has 2 Native UARTs.
+ */
+ { PCI_VENDOR_ID_ENDRUN, PCI_DEVICE_ID_ENDRUN_1588,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_endrun_2_4000000 },
+ /*
+ * Quatech cards. These actually have configurable clocks but for
+ * now we just use the default.
+ *
+ * 100 series are RS232, 200 series RS422,
+ */
+ { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_QSC100,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b1_4_115200 },
+ { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSC100,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b1_2_115200 },
+ { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSC100E,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b2_2_115200 },
+ { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSC200,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b1_2_115200 },
+ { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSC200E,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b2_2_115200 },
+ { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_QSC200,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b1_4_115200 },
+ { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_ESC100D,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b1_8_115200 },
+ { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_ESC100M,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b1_8_115200 },
+ { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_QSCP100,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b1_4_115200 },
+ { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSCP100,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b1_2_115200 },
+ { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_QSCP200,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b1_4_115200 },
+ { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSCP200,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b1_2_115200 },
+ { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_QSCLP100,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b2_4_115200 },
+ { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSCLP100,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b2_2_115200 },
+ { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_SSCLP100,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b2_1_115200 },
+ { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_QSCLP200,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b2_4_115200 },
+ { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSCLP200,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b2_2_115200 },
+ { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_SSCLP200,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b2_1_115200 },
+ { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_ESCLP100,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b0_8_115200 },
+
+ { PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_OXSEMI_16PCI954,
+ PCI_VENDOR_ID_SPECIALIX, PCI_SUBDEVICE_ID_SPECIALIX_SPEED4,
+ 0, 0,
+ pbn_b0_4_921600 },
+ { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI954,
+ PCI_SUBVENDOR_ID_SIIG, PCI_SUBDEVICE_ID_SIIG_QUARTET_SERIAL,
+ 0, 0,
+ pbn_b0_4_1152000 },
+ { PCI_VENDOR_ID_OXSEMI, 0x9505,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b0_bt_2_921600 },
+
+ /*
+ * The below card is a little controversial since it is the
+ * subject of a PCI vendor/device ID clash. (See
+ * www.ussg.iu.edu/hypermail/linux/kernel/0303.1/0516.html).
+ * For now just used the hex ID 0x950a.
+ */
+ { PCI_VENDOR_ID_OXSEMI, 0x950a,
+ PCI_SUBVENDOR_ID_SIIG, PCI_SUBDEVICE_ID_SIIG_DUAL_00,
+ 0, 0, pbn_b0_2_115200 },
+ { PCI_VENDOR_ID_OXSEMI, 0x950a,
+ PCI_SUBVENDOR_ID_SIIG, PCI_SUBDEVICE_ID_SIIG_DUAL_30,
+ 0, 0, pbn_b0_2_115200 },
+ { PCI_VENDOR_ID_OXSEMI, 0x950a,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b0_2_1130000 },
+ { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_C950,
+ PCI_VENDOR_ID_OXSEMI, PCI_SUBDEVICE_ID_OXSEMI_C950, 0, 0,
+ pbn_b0_1_921600 },
+ { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI954,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b0_4_115200 },
+ { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI952,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b0_bt_2_921600 },
+ { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI958,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b2_8_1152000 },
+
+ /*
+ * Oxford Semiconductor Inc. Tornado PCI express device range.
+ */
+ { PCI_VENDOR_ID_OXSEMI, 0xc101, /* OXPCIe952 1 Legacy UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b0_1_4000000 },
+ { PCI_VENDOR_ID_OXSEMI, 0xc105, /* OXPCIe952 1 Legacy UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b0_1_4000000 },
+ { PCI_VENDOR_ID_OXSEMI, 0xc11b, /* OXPCIe952 1 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_oxsemi_1_4000000 },
+ { PCI_VENDOR_ID_OXSEMI, 0xc11f, /* OXPCIe952 1 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_oxsemi_1_4000000 },
+ { PCI_VENDOR_ID_OXSEMI, 0xc120, /* OXPCIe952 1 Legacy UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b0_1_4000000 },
+ { PCI_VENDOR_ID_OXSEMI, 0xc124, /* OXPCIe952 1 Legacy UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b0_1_4000000 },
+ { PCI_VENDOR_ID_OXSEMI, 0xc138, /* OXPCIe952 1 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_oxsemi_1_4000000 },
+ { PCI_VENDOR_ID_OXSEMI, 0xc13d, /* OXPCIe952 1 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_oxsemi_1_4000000 },
+ { PCI_VENDOR_ID_OXSEMI, 0xc140, /* OXPCIe952 1 Legacy UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b0_1_4000000 },
+ { PCI_VENDOR_ID_OXSEMI, 0xc141, /* OXPCIe952 1 Legacy UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b0_1_4000000 },
+ { PCI_VENDOR_ID_OXSEMI, 0xc144, /* OXPCIe952 1 Legacy UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b0_1_4000000 },
+ { PCI_VENDOR_ID_OXSEMI, 0xc145, /* OXPCIe952 1 Legacy UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b0_1_4000000 },
+ { PCI_VENDOR_ID_OXSEMI, 0xc158, /* OXPCIe952 2 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_oxsemi_2_4000000 },
+ { PCI_VENDOR_ID_OXSEMI, 0xc15d, /* OXPCIe952 2 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_oxsemi_2_4000000 },
+ { PCI_VENDOR_ID_OXSEMI, 0xc208, /* OXPCIe954 4 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_oxsemi_4_4000000 },
+ { PCI_VENDOR_ID_OXSEMI, 0xc20d, /* OXPCIe954 4 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_oxsemi_4_4000000 },
+ { PCI_VENDOR_ID_OXSEMI, 0xc308, /* OXPCIe958 8 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_oxsemi_8_4000000 },
+ { PCI_VENDOR_ID_OXSEMI, 0xc30d, /* OXPCIe958 8 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_oxsemi_8_4000000 },
+ { PCI_VENDOR_ID_OXSEMI, 0xc40b, /* OXPCIe200 1 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_oxsemi_1_4000000 },
+ { PCI_VENDOR_ID_OXSEMI, 0xc40f, /* OXPCIe200 1 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_oxsemi_1_4000000 },
+ { PCI_VENDOR_ID_OXSEMI, 0xc41b, /* OXPCIe200 1 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_oxsemi_1_4000000 },
+ { PCI_VENDOR_ID_OXSEMI, 0xc41f, /* OXPCIe200 1 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_oxsemi_1_4000000 },
+ { PCI_VENDOR_ID_OXSEMI, 0xc42b, /* OXPCIe200 1 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_oxsemi_1_4000000 },
+ { PCI_VENDOR_ID_OXSEMI, 0xc42f, /* OXPCIe200 1 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_oxsemi_1_4000000 },
+ { PCI_VENDOR_ID_OXSEMI, 0xc43b, /* OXPCIe200 1 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_oxsemi_1_4000000 },
+ { PCI_VENDOR_ID_OXSEMI, 0xc43f, /* OXPCIe200 1 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_oxsemi_1_4000000 },
+ { PCI_VENDOR_ID_OXSEMI, 0xc44b, /* OXPCIe200 1 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_oxsemi_1_4000000 },
+ { PCI_VENDOR_ID_OXSEMI, 0xc44f, /* OXPCIe200 1 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_oxsemi_1_4000000 },
+ { PCI_VENDOR_ID_OXSEMI, 0xc45b, /* OXPCIe200 1 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_oxsemi_1_4000000 },
+ { PCI_VENDOR_ID_OXSEMI, 0xc45f, /* OXPCIe200 1 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_oxsemi_1_4000000 },
+ { PCI_VENDOR_ID_OXSEMI, 0xc46b, /* OXPCIe200 1 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_oxsemi_1_4000000 },
+ { PCI_VENDOR_ID_OXSEMI, 0xc46f, /* OXPCIe200 1 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_oxsemi_1_4000000 },
+ { PCI_VENDOR_ID_OXSEMI, 0xc47b, /* OXPCIe200 1 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_oxsemi_1_4000000 },
+ { PCI_VENDOR_ID_OXSEMI, 0xc47f, /* OXPCIe200 1 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_oxsemi_1_4000000 },
+ { PCI_VENDOR_ID_OXSEMI, 0xc48b, /* OXPCIe200 1 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_oxsemi_1_4000000 },
+ { PCI_VENDOR_ID_OXSEMI, 0xc48f, /* OXPCIe200 1 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_oxsemi_1_4000000 },
+ { PCI_VENDOR_ID_OXSEMI, 0xc49b, /* OXPCIe200 1 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_oxsemi_1_4000000 },
+ { PCI_VENDOR_ID_OXSEMI, 0xc49f, /* OXPCIe200 1 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_oxsemi_1_4000000 },
+ { PCI_VENDOR_ID_OXSEMI, 0xc4ab, /* OXPCIe200 1 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_oxsemi_1_4000000 },
+ { PCI_VENDOR_ID_OXSEMI, 0xc4af, /* OXPCIe200 1 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_oxsemi_1_4000000 },
+ { PCI_VENDOR_ID_OXSEMI, 0xc4bb, /* OXPCIe200 1 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_oxsemi_1_4000000 },
+ { PCI_VENDOR_ID_OXSEMI, 0xc4bf, /* OXPCIe200 1 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_oxsemi_1_4000000 },
+ { PCI_VENDOR_ID_OXSEMI, 0xc4cb, /* OXPCIe200 1 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_oxsemi_1_4000000 },
+ { PCI_VENDOR_ID_OXSEMI, 0xc4cf, /* OXPCIe200 1 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_oxsemi_1_4000000 },
+ /*
+ * Mainpine Inc. IQ Express "Rev3" utilizing OxSemi Tornado
+ */
+ { PCI_VENDOR_ID_MAINPINE, 0x4000, /* IQ Express 1 Port V.34 Super-G3 Fax */
+ PCI_VENDOR_ID_MAINPINE, 0x4001, 0, 0,
+ pbn_oxsemi_1_4000000 },
+ { PCI_VENDOR_ID_MAINPINE, 0x4000, /* IQ Express 2 Port V.34 Super-G3 Fax */
+ PCI_VENDOR_ID_MAINPINE, 0x4002, 0, 0,
+ pbn_oxsemi_2_4000000 },
+ { PCI_VENDOR_ID_MAINPINE, 0x4000, /* IQ Express 4 Port V.34 Super-G3 Fax */
+ PCI_VENDOR_ID_MAINPINE, 0x4004, 0, 0,
+ pbn_oxsemi_4_4000000 },
+ { PCI_VENDOR_ID_MAINPINE, 0x4000, /* IQ Express 8 Port V.34 Super-G3 Fax */
+ PCI_VENDOR_ID_MAINPINE, 0x4008, 0, 0,
+ pbn_oxsemi_8_4000000 },
+
+ /*
+ * Digi/IBM PCIe 2-port Async EIA-232 Adapter utilizing OxSemi Tornado
+ */
+ { PCI_VENDOR_ID_DIGI, PCIE_DEVICE_ID_NEO_2_OX_IBM,
+ PCI_SUBVENDOR_ID_IBM, PCI_ANY_ID, 0, 0,
+ pbn_oxsemi_2_4000000 },
+
+ /*
+ * SBS Technologies, Inc. P-Octal and PMC-OCTPRO cards,
+ * from skokodyn@yahoo.com
+ */
+ { PCI_VENDOR_ID_SBSMODULARIO, PCI_DEVICE_ID_OCTPRO,
+ PCI_SUBVENDOR_ID_SBSMODULARIO, PCI_SUBDEVICE_ID_OCTPRO232, 0, 0,
+ pbn_sbsxrsio },
+ { PCI_VENDOR_ID_SBSMODULARIO, PCI_DEVICE_ID_OCTPRO,
+ PCI_SUBVENDOR_ID_SBSMODULARIO, PCI_SUBDEVICE_ID_OCTPRO422, 0, 0,
+ pbn_sbsxrsio },
+ { PCI_VENDOR_ID_SBSMODULARIO, PCI_DEVICE_ID_OCTPRO,
+ PCI_SUBVENDOR_ID_SBSMODULARIO, PCI_SUBDEVICE_ID_POCTAL232, 0, 0,
+ pbn_sbsxrsio },
+ { PCI_VENDOR_ID_SBSMODULARIO, PCI_DEVICE_ID_OCTPRO,
+ PCI_SUBVENDOR_ID_SBSMODULARIO, PCI_SUBDEVICE_ID_POCTAL422, 0, 0,
+ pbn_sbsxrsio },
+
+ /*
+ * Digitan DS560-558, from jimd@esoft.com
+ */
+ { PCI_VENDOR_ID_ATT, PCI_DEVICE_ID_ATT_VENUS_MODEM,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b1_1_115200 },
+
+ /*
+ * Titan Electronic cards
+ * The 400L and 800L have a custom setup quirk.
+ */
+ { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_100,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b0_1_921600 },
+ { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b0_2_921600 },
+ { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_400,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b0_4_921600 },
+ { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800B,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b0_4_921600 },
+ { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_100L,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b1_1_921600 },
+ { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200L,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b1_bt_2_921600 },
+ { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_400L,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b0_bt_4_921600 },
+ { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800L,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b0_bt_8_921600 },
+ { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200I,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b4_bt_2_921600 },
+ { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_400I,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b4_bt_4_921600 },
+ { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800I,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b4_bt_8_921600 },
+ { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_400EH,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b0_4_921600 },
+ { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800EH,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b0_4_921600 },
+ { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800EHB,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b0_4_921600 },
+ { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_100E,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_oxsemi_1_4000000 },
+ { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200E,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_oxsemi_2_4000000 },
+ { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_400E,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_oxsemi_4_4000000 },
+ { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800E,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_oxsemi_8_4000000 },
+ { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200EI,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_oxsemi_2_4000000 },
+ { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200EISI,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_oxsemi_2_4000000 },
+ { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200V3,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b0_bt_2_921600 },
+ { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_400V3,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b0_4_921600 },
+ { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_410V3,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b0_4_921600 },
+ { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800V3,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b0_4_921600 },
+ { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800V3B,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b0_4_921600 },
+
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_10x_550,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b2_1_460800 },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_10x_650,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b2_1_460800 },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_10x_850,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b2_1_460800 },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_10x_550,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b2_bt_2_921600 },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_10x_650,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b2_bt_2_921600 },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_10x_850,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b2_bt_2_921600 },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_10x_550,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b2_bt_4_921600 },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_10x_650,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b2_bt_4_921600 },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_10x_850,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b2_bt_4_921600 },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_20x_550,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b0_1_921600 },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_20x_650,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b0_1_921600 },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_20x_850,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b0_1_921600 },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_20x_550,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b0_bt_2_921600 },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_20x_650,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b0_bt_2_921600 },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_20x_850,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b0_bt_2_921600 },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_20x_550,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b0_bt_4_921600 },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_20x_650,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b0_bt_4_921600 },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_20x_850,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b0_bt_4_921600 },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_8S_20x_550,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b0_bt_8_921600 },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_8S_20x_650,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b0_bt_8_921600 },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_8S_20x_850,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b0_bt_8_921600 },
+
+ /*
+ * Computone devices submitted by Doug McNash dmcnash@computone.com
+ */
+ { PCI_VENDOR_ID_COMPUTONE, PCI_DEVICE_ID_COMPUTONE_PG,
+ PCI_SUBVENDOR_ID_COMPUTONE, PCI_SUBDEVICE_ID_COMPUTONE_PG4,
+ 0, 0, pbn_computone_4 },
+ { PCI_VENDOR_ID_COMPUTONE, PCI_DEVICE_ID_COMPUTONE_PG,
+ PCI_SUBVENDOR_ID_COMPUTONE, PCI_SUBDEVICE_ID_COMPUTONE_PG8,
+ 0, 0, pbn_computone_8 },
+ { PCI_VENDOR_ID_COMPUTONE, PCI_DEVICE_ID_COMPUTONE_PG,
+ PCI_SUBVENDOR_ID_COMPUTONE, PCI_SUBDEVICE_ID_COMPUTONE_PG6,
+ 0, 0, pbn_computone_6 },
+
+ { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI95N,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_oxsemi },
+ { PCI_VENDOR_ID_TIMEDIA, PCI_DEVICE_ID_TIMEDIA_1889,
+ PCI_VENDOR_ID_TIMEDIA, PCI_ANY_ID, 0, 0,
+ pbn_b0_bt_1_921600 },
+
+ /*
+ * Sunix PCI serial boards
+ */
+ { PCI_VENDOR_ID_SUNIX, PCI_DEVICE_ID_SUNIX_1999,
+ PCI_VENDOR_ID_SUNIX, 0x0001, 0, 0,
+ pbn_sunix_pci_1s },
+ { PCI_VENDOR_ID_SUNIX, PCI_DEVICE_ID_SUNIX_1999,
+ PCI_VENDOR_ID_SUNIX, 0x0002, 0, 0,
+ pbn_sunix_pci_2s },
+ { PCI_VENDOR_ID_SUNIX, PCI_DEVICE_ID_SUNIX_1999,
+ PCI_VENDOR_ID_SUNIX, 0x0004, 0, 0,
+ pbn_sunix_pci_4s },
+ { PCI_VENDOR_ID_SUNIX, PCI_DEVICE_ID_SUNIX_1999,
+ PCI_VENDOR_ID_SUNIX, 0x0084, 0, 0,
+ pbn_sunix_pci_4s },
+ { PCI_VENDOR_ID_SUNIX, PCI_DEVICE_ID_SUNIX_1999,
+ PCI_VENDOR_ID_SUNIX, 0x0008, 0, 0,
+ pbn_sunix_pci_8s },
+ { PCI_VENDOR_ID_SUNIX, PCI_DEVICE_ID_SUNIX_1999,
+ PCI_VENDOR_ID_SUNIX, 0x0088, 0, 0,
+ pbn_sunix_pci_8s },
+ { PCI_VENDOR_ID_SUNIX, PCI_DEVICE_ID_SUNIX_1999,
+ PCI_VENDOR_ID_SUNIX, 0x0010, 0, 0,
+ pbn_sunix_pci_16s },
+
+ /*
+ * AFAVLAB serial card, from Harald Welte <laforge@gnumonks.org>
+ */
+ { PCI_VENDOR_ID_AFAVLAB, PCI_DEVICE_ID_AFAVLAB_P028,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b0_bt_8_115200 },
+ { PCI_VENDOR_ID_AFAVLAB, PCI_DEVICE_ID_AFAVLAB_P030,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b0_bt_8_115200 },
+
+ { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_DSERIAL,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b0_bt_2_115200 },
+ { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUATRO_A,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b0_bt_2_115200 },
+ { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUATRO_B,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b0_bt_2_115200 },
+ { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUATTRO_A,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b0_bt_2_115200 },
+ { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUATTRO_B,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b0_bt_2_115200 },
+ { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_OCTO_A,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b0_bt_4_460800 },
+ { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_OCTO_B,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b0_bt_4_460800 },
+ { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_PORT_PLUS,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b0_bt_2_460800 },
+ { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUAD_A,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b0_bt_2_460800 },
+ { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUAD_B,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b0_bt_2_460800 },
+ { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_SSERIAL,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b0_bt_1_115200 },
+ { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_PORT_650,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b0_bt_1_460800 },
+
+ /*
+ * Korenix Jetcard F0/F1 cards (JC1204, JC1208, JC1404, JC1408).
+ * Cards are identified by their subsystem vendor IDs, which
+ * (in hex) match the model number.
+ *
+ * Note that JC140x are RS422/485 cards which require ox950
+ * ACR = 0x10, and as such are not currently fully supported.
+ */
+ { PCI_VENDOR_ID_KORENIX, PCI_DEVICE_ID_KORENIX_JETCARDF0,
+ 0x1204, 0x0004, 0, 0,
+ pbn_b0_4_921600 },
+ { PCI_VENDOR_ID_KORENIX, PCI_DEVICE_ID_KORENIX_JETCARDF0,
+ 0x1208, 0x0004, 0, 0,
+ pbn_b0_4_921600 },
+/* { PCI_VENDOR_ID_KORENIX, PCI_DEVICE_ID_KORENIX_JETCARDF0,
+ 0x1402, 0x0002, 0, 0,
+ pbn_b0_2_921600 }, */
+/* { PCI_VENDOR_ID_KORENIX, PCI_DEVICE_ID_KORENIX_JETCARDF0,
+ 0x1404, 0x0004, 0, 0,
+ pbn_b0_4_921600 }, */
+ { PCI_VENDOR_ID_KORENIX, PCI_DEVICE_ID_KORENIX_JETCARDF1,
+ 0x1208, 0x0004, 0, 0,
+ pbn_b0_4_921600 },
+
+ { PCI_VENDOR_ID_KORENIX, PCI_DEVICE_ID_KORENIX_JETCARDF2,
+ 0x1204, 0x0004, 0, 0,
+ pbn_b0_4_921600 },
+ { PCI_VENDOR_ID_KORENIX, PCI_DEVICE_ID_KORENIX_JETCARDF2,
+ 0x1208, 0x0004, 0, 0,
+ pbn_b0_4_921600 },
+ { PCI_VENDOR_ID_KORENIX, PCI_DEVICE_ID_KORENIX_JETCARDF3,
+ 0x1208, 0x0004, 0, 0,
+ pbn_b0_4_921600 },
+ /*
+ * Dell Remote Access Card 4 - Tim_T_Murphy@Dell.com
+ */
+ { PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_DELL_RAC4,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b1_1_1382400 },
+
+ /*
+ * Dell Remote Access Card III - Tim_T_Murphy@Dell.com
+ */
+ { PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_DELL_RACIII,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b1_1_1382400 },
+
+ /*
+ * RAStel 2 port modem, gerg@moreton.com.au
+ */
+ { PCI_VENDOR_ID_MORETON, PCI_DEVICE_ID_RASTEL_2PORT,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b2_bt_2_115200 },
+
+ /*
+ * EKF addition for i960 Boards form EKF with serial port
+ */
+ { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_80960_RP,
+ 0xE4BF, PCI_ANY_ID, 0, 0,
+ pbn_intel_i960 },
+
+ /*
+ * Xircom Cardbus/Ethernet combos
+ */
+ { PCI_VENDOR_ID_XIRCOM, PCI_DEVICE_ID_XIRCOM_X3201_MDM,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b0_1_115200 },
+ /*
+ * Xircom RBM56G cardbus modem - Dirk Arnold (temp entry)
+ */
+ { PCI_VENDOR_ID_XIRCOM, PCI_DEVICE_ID_XIRCOM_RBM56G,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b0_1_115200 },
+
+ /*
+ * Untested PCI modems, sent in from various folks...
+ */
+
+ /*
+ * Elsa Model 56K PCI Modem, from Andreas Rath <arh@01019freenet.de>
+ */
+ { PCI_VENDOR_ID_ROCKWELL, 0x1004,
+ 0x1048, 0x1500, 0, 0,
+ pbn_b1_1_115200 },
+
+ { PCI_VENDOR_ID_SGI, PCI_DEVICE_ID_SGI_IOC3,
+ 0xFF00, 0, 0, 0,
+ pbn_sgi_ioc3 },
+
+ /*
+ * HP Diva card
+ */
+ { PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_DIVA,
+ PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_DIVA_RMP3, 0, 0,
+ pbn_b1_1_115200 },
+ { PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_DIVA,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b0_5_115200 },
+ { PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_DIVA_AUX,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b2_1_115200 },
+
+ { PCI_VENDOR_ID_DCI, PCI_DEVICE_ID_DCI_PCCOM2,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b3_2_115200 },
+ { PCI_VENDOR_ID_DCI, PCI_DEVICE_ID_DCI_PCCOM4,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b3_4_115200 },
+ { PCI_VENDOR_ID_DCI, PCI_DEVICE_ID_DCI_PCCOM8,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b3_8_115200 },
+ /*
+ * Pericom PI7C9X795[1248] Uno/Dual/Quad/Octal UART
+ */
+ { PCI_VENDOR_ID_PERICOM, PCI_DEVICE_ID_PERICOM_PI7C9X7951,
+ PCI_ANY_ID, PCI_ANY_ID,
+ 0,
+ 0, pbn_pericom_PI7C9X7951 },
+ { PCI_VENDOR_ID_PERICOM, PCI_DEVICE_ID_PERICOM_PI7C9X7952,
+ PCI_ANY_ID, PCI_ANY_ID,
+ 0,
+ 0, pbn_pericom_PI7C9X7952 },
+ { PCI_VENDOR_ID_PERICOM, PCI_DEVICE_ID_PERICOM_PI7C9X7954,
+ PCI_ANY_ID, PCI_ANY_ID,
+ 0,
+ 0, pbn_pericom_PI7C9X7954 },
+ { PCI_VENDOR_ID_PERICOM, PCI_DEVICE_ID_PERICOM_PI7C9X7958,
+ PCI_ANY_ID, PCI_ANY_ID,
+ 0,
+ 0, pbn_pericom_PI7C9X7958 },
+ /*
+ * ACCES I/O Products quad
+ */
+ { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_COM_2SDB,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_pericom_PI7C9X7952 },
+ { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_MPCIE_COM_2S,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_pericom_PI7C9X7952 },
+ { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_COM_4SDB,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_pericom_PI7C9X7954 },
+ { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_MPCIE_COM_4S,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_pericom_PI7C9X7954 },
+ { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_COM232_2DB,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_pericom_PI7C9X7952 },
+ { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_MPCIE_COM232_2,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_pericom_PI7C9X7952 },
+ { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_COM232_4DB,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_pericom_PI7C9X7954 },
+ { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_MPCIE_COM232_4,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_pericom_PI7C9X7954 },
+ { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_COM_2SMDB,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_pericom_PI7C9X7952 },
+ { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_MPCIE_COM_2SM,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_pericom_PI7C9X7952 },
+ { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_COM_4SMDB,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_pericom_PI7C9X7954 },
+ { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_MPCIE_COM_4SM,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_pericom_PI7C9X7954 },
+ { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_MPCIE_ICM485_1,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_pericom_PI7C9X7951 },
+ { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_MPCIE_ICM422_2,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_pericom_PI7C9X7952 },
+ { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_MPCIE_ICM485_2,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_pericom_PI7C9X7952 },
+ { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_MPCIE_ICM422_4,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_pericom_PI7C9X7954 },
+ { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_MPCIE_ICM485_4,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_pericom_PI7C9X7954 },
+ { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_ICM_2S,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_pericom_PI7C9X7952 },
+ { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_ICM_4S,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_pericom_PI7C9X7954 },
+ { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_ICM232_2,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_pericom_PI7C9X7952 },
+ { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_MPCIE_ICM232_2,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_pericom_PI7C9X7952 },
+ { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_ICM232_4,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_pericom_PI7C9X7954 },
+ { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_MPCIE_ICM232_4,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_pericom_PI7C9X7954 },
+ { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_ICM_2SM,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_pericom_PI7C9X7952 },
+ { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_COM422_4,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_pericom_PI7C9X7954 },
+ { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_COM485_4,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_pericom_PI7C9X7954 },
+ { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_COM422_8,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_pericom_PI7C9X7958 },
+ { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_COM485_8,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_pericom_PI7C9X7958 },
+ { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_COM232_4,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_pericom_PI7C9X7954 },
+ { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_COM232_8,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_pericom_PI7C9X7958 },
+ { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_COM_4SM,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_pericom_PI7C9X7954 },
+ { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_COM_8SM,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_pericom_PI7C9X7958 },
+ { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_ICM_4SM,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_pericom_PI7C9X7954 },
+ /*
+ * Topic TP560 Data/Fax/Voice 56k modem (reported by Evan Clarke)
+ */
+ { PCI_VENDOR_ID_TOPIC, PCI_DEVICE_ID_TOPIC_TP560,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b0_1_115200 },
+ /*
+ * ITE
+ */
+ { PCI_VENDOR_ID_ITE, PCI_DEVICE_ID_ITE_8872,
+ PCI_ANY_ID, PCI_ANY_ID,
+ 0, 0,
+ pbn_b1_bt_1_115200 },
+
+ /*
+ * IntaShield IS-200
+ */
+ { PCI_VENDOR_ID_INTASHIELD, PCI_DEVICE_ID_INTASHIELD_IS200,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, /* 135a.0811 */
+ pbn_b2_2_115200 },
+ /*
+ * IntaShield IS-400
+ */
+ { PCI_VENDOR_ID_INTASHIELD, PCI_DEVICE_ID_INTASHIELD_IS400,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, /* 135a.0dc0 */
+ pbn_b2_4_115200 },
+ /*
+ * BrainBoxes UC-260
+ */
+ { PCI_VENDOR_ID_INTASHIELD, 0x0D21,
+ PCI_ANY_ID, PCI_ANY_ID,
+ PCI_CLASS_COMMUNICATION_MULTISERIAL << 8, 0xffff00,
+ pbn_b2_4_115200 },
+ { PCI_VENDOR_ID_INTASHIELD, 0x0E34,
+ PCI_ANY_ID, PCI_ANY_ID,
+ PCI_CLASS_COMMUNICATION_MULTISERIAL << 8, 0xffff00,
+ pbn_b2_4_115200 },
+ /*
+ * Perle PCI-RAS cards
+ */
+ { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030,
+ PCI_SUBVENDOR_ID_PERLE, PCI_SUBDEVICE_ID_PCI_RAS4,
+ 0, 0, pbn_b2_4_921600 },
+ { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030,
+ PCI_SUBVENDOR_ID_PERLE, PCI_SUBDEVICE_ID_PCI_RAS8,
+ 0, 0, pbn_b2_8_921600 },
+
+ /*
+ * Mainpine series cards: Fairly standard layout but fools
+ * parts of the autodetect in some cases and uses otherwise
+ * unmatched communications subclasses in the PCI Express case
+ */
+
+ { /* RockForceDUO */
+ PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+ PCI_VENDOR_ID_MAINPINE, 0x0200,
+ 0, 0, pbn_b0_2_115200 },
+ { /* RockForceQUATRO */
+ PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+ PCI_VENDOR_ID_MAINPINE, 0x0300,
+ 0, 0, pbn_b0_4_115200 },
+ { /* RockForceDUO+ */
+ PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+ PCI_VENDOR_ID_MAINPINE, 0x0400,
+ 0, 0, pbn_b0_2_115200 },
+ { /* RockForceQUATRO+ */
+ PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+ PCI_VENDOR_ID_MAINPINE, 0x0500,
+ 0, 0, pbn_b0_4_115200 },
+ { /* RockForce+ */
+ PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+ PCI_VENDOR_ID_MAINPINE, 0x0600,
+ 0, 0, pbn_b0_2_115200 },
+ { /* RockForce+ */
+ PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+ PCI_VENDOR_ID_MAINPINE, 0x0700,
+ 0, 0, pbn_b0_4_115200 },
+ { /* RockForceOCTO+ */
+ PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+ PCI_VENDOR_ID_MAINPINE, 0x0800,
+ 0, 0, pbn_b0_8_115200 },
+ { /* RockForceDUO+ */
+ PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+ PCI_VENDOR_ID_MAINPINE, 0x0C00,
+ 0, 0, pbn_b0_2_115200 },
+ { /* RockForceQUARTRO+ */
+ PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+ PCI_VENDOR_ID_MAINPINE, 0x0D00,
+ 0, 0, pbn_b0_4_115200 },
+ { /* RockForceOCTO+ */
+ PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+ PCI_VENDOR_ID_MAINPINE, 0x1D00,
+ 0, 0, pbn_b0_8_115200 },
+ { /* RockForceD1 */
+ PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+ PCI_VENDOR_ID_MAINPINE, 0x2000,
+ 0, 0, pbn_b0_1_115200 },
+ { /* RockForceF1 */
+ PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+ PCI_VENDOR_ID_MAINPINE, 0x2100,
+ 0, 0, pbn_b0_1_115200 },
+ { /* RockForceD2 */
+ PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+ PCI_VENDOR_ID_MAINPINE, 0x2200,
+ 0, 0, pbn_b0_2_115200 },
+ { /* RockForceF2 */
+ PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+ PCI_VENDOR_ID_MAINPINE, 0x2300,
+ 0, 0, pbn_b0_2_115200 },
+ { /* RockForceD4 */
+ PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+ PCI_VENDOR_ID_MAINPINE, 0x2400,
+ 0, 0, pbn_b0_4_115200 },
+ { /* RockForceF4 */
+ PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+ PCI_VENDOR_ID_MAINPINE, 0x2500,
+ 0, 0, pbn_b0_4_115200 },
+ { /* RockForceD8 */
+ PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+ PCI_VENDOR_ID_MAINPINE, 0x2600,
+ 0, 0, pbn_b0_8_115200 },
+ { /* RockForceF8 */
+ PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+ PCI_VENDOR_ID_MAINPINE, 0x2700,
+ 0, 0, pbn_b0_8_115200 },
+ { /* IQ Express D1 */
+ PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+ PCI_VENDOR_ID_MAINPINE, 0x3000,
+ 0, 0, pbn_b0_1_115200 },
+ { /* IQ Express F1 */
+ PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+ PCI_VENDOR_ID_MAINPINE, 0x3100,
+ 0, 0, pbn_b0_1_115200 },
+ { /* IQ Express D2 */
+ PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+ PCI_VENDOR_ID_MAINPINE, 0x3200,
+ 0, 0, pbn_b0_2_115200 },
+ { /* IQ Express F2 */
+ PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+ PCI_VENDOR_ID_MAINPINE, 0x3300,
+ 0, 0, pbn_b0_2_115200 },
+ { /* IQ Express D4 */
+ PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+ PCI_VENDOR_ID_MAINPINE, 0x3400,
+ 0, 0, pbn_b0_4_115200 },
+ { /* IQ Express F4 */
+ PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+ PCI_VENDOR_ID_MAINPINE, 0x3500,
+ 0, 0, pbn_b0_4_115200 },
+ { /* IQ Express D8 */
+ PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+ PCI_VENDOR_ID_MAINPINE, 0x3C00,
+ 0, 0, pbn_b0_8_115200 },
+ { /* IQ Express F8 */
+ PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+ PCI_VENDOR_ID_MAINPINE, 0x3D00,
+ 0, 0, pbn_b0_8_115200 },
+
+
+ /*
+ * PA Semi PA6T-1682M on-chip UART
+ */
+ { PCI_VENDOR_ID_PASEMI, 0xa004,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_pasemi_1682M },
+
+ /*
+ * National Instruments
+ */
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI23216,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b1_16_115200 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI2328,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b1_8_115200 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI2324,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b1_bt_4_115200 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI2322,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b1_bt_2_115200 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI2324I,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b1_bt_4_115200 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI2322I,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b1_bt_2_115200 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8420_23216,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b1_16_115200 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8420_2328,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b1_8_115200 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8420_2324,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b1_bt_4_115200 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8420_2322,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b1_bt_2_115200 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8422_2324,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b1_bt_4_115200 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8422_2322,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b1_bt_2_115200 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8430_2322,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_ni8430_2 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI8430_2322,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_ni8430_2 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8430_2324,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_ni8430_4 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI8430_2324,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_ni8430_4 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8430_2328,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_ni8430_8 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI8430_2328,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_ni8430_8 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8430_23216,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_ni8430_16 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI8430_23216,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_ni8430_16 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8432_2322,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_ni8430_2 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI8432_2322,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_ni8430_2 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8432_2324,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_ni8430_4 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI8432_2324,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_ni8430_4 },
+ { PCI_VENDOR_ID_NI, PCIE_DEVICE_ID_NI_PXIE8430_2328,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_ni8430_pxie_8 },
+ { PCI_VENDOR_ID_NI, PCIE_DEVICE_ID_NI_PXIE8430_23216,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_ni8430_pxie_16 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8431_4852,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_ni8431_2 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8431_4854,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_ni8431_4 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8431_4858,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_ni8431_8 },
+ { PCI_VENDOR_ID_NI, PCIE_DEVICE_ID_NI_PXIE8431_4858,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_ni8431_pxie_8 },
+ { PCI_VENDOR_ID_NI, PCIE_DEVICE_ID_NI_PXIE8431_48516,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_ni8431_pxie_16 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8433_4852,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_ni8431_2 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8433_4854,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_ni8431_4 },
+
+ /*
+ * MOXA
+ */
+ { PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP102E,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_moxa8250_2p },
+ { PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP102EL,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_moxa8250_2p },
+ { PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP104EL_A,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_moxa8250_4p },
+ { PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP114EL,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_moxa8250_4p },
+ { PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP116E_A_A,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_moxa8250_8p },
+ { PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP116E_A_B,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_moxa8250_8p },
+ { PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP118EL_A,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_moxa8250_8p },
+ { PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP118E_A_I,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_moxa8250_8p },
+ { PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP132EL,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_moxa8250_2p },
+ { PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP134EL_A,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_moxa8250_4p },
+ { PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP138E_A,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_moxa8250_8p },
+ { PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP168EL_A,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_moxa8250_8p },
+
+ /*
+ * ADDI-DATA GmbH communication cards <info@addi-data.com>
+ */
+ { PCI_VENDOR_ID_ADDIDATA,
+ PCI_DEVICE_ID_ADDIDATA_APCI7500,
+ PCI_ANY_ID,
+ PCI_ANY_ID,
+ 0,
+ 0,
+ pbn_b0_4_115200 },
+
+ { PCI_VENDOR_ID_ADDIDATA,
+ PCI_DEVICE_ID_ADDIDATA_APCI7420,
+ PCI_ANY_ID,
+ PCI_ANY_ID,
+ 0,
+ 0,
+ pbn_b0_2_115200 },
+
+ { PCI_VENDOR_ID_ADDIDATA,
+ PCI_DEVICE_ID_ADDIDATA_APCI7300,
+ PCI_ANY_ID,
+ PCI_ANY_ID,
+ 0,
+ 0,
+ pbn_b0_1_115200 },
+
+ { PCI_VENDOR_ID_AMCC,
+ PCI_DEVICE_ID_AMCC_ADDIDATA_APCI7800,
+ PCI_ANY_ID,
+ PCI_ANY_ID,
+ 0,
+ 0,
+ pbn_b1_8_115200 },
+
+ { PCI_VENDOR_ID_ADDIDATA,
+ PCI_DEVICE_ID_ADDIDATA_APCI7500_2,
+ PCI_ANY_ID,
+ PCI_ANY_ID,
+ 0,
+ 0,
+ pbn_b0_4_115200 },
+
+ { PCI_VENDOR_ID_ADDIDATA,
+ PCI_DEVICE_ID_ADDIDATA_APCI7420_2,
+ PCI_ANY_ID,
+ PCI_ANY_ID,
+ 0,
+ 0,
+ pbn_b0_2_115200 },
+
+ { PCI_VENDOR_ID_ADDIDATA,
+ PCI_DEVICE_ID_ADDIDATA_APCI7300_2,
+ PCI_ANY_ID,
+ PCI_ANY_ID,
+ 0,
+ 0,
+ pbn_b0_1_115200 },
+
+ { PCI_VENDOR_ID_ADDIDATA,
+ PCI_DEVICE_ID_ADDIDATA_APCI7500_3,
+ PCI_ANY_ID,
+ PCI_ANY_ID,
+ 0,
+ 0,
+ pbn_b0_4_115200 },
+
+ { PCI_VENDOR_ID_ADDIDATA,
+ PCI_DEVICE_ID_ADDIDATA_APCI7420_3,
+ PCI_ANY_ID,
+ PCI_ANY_ID,
+ 0,
+ 0,
+ pbn_b0_2_115200 },
+
+ { PCI_VENDOR_ID_ADDIDATA,
+ PCI_DEVICE_ID_ADDIDATA_APCI7300_3,
+ PCI_ANY_ID,
+ PCI_ANY_ID,
+ 0,
+ 0,
+ pbn_b0_1_115200 },
+
+ { PCI_VENDOR_ID_ADDIDATA,
+ PCI_DEVICE_ID_ADDIDATA_APCI7800_3,
+ PCI_ANY_ID,
+ PCI_ANY_ID,
+ 0,
+ 0,
+ pbn_b0_8_115200 },
+
+ { PCI_VENDOR_ID_ADDIDATA,
+ PCI_DEVICE_ID_ADDIDATA_APCIe7500,
+ PCI_ANY_ID,
+ PCI_ANY_ID,
+ 0,
+ 0,
+ pbn_ADDIDATA_PCIe_4_3906250 },
+
+ { PCI_VENDOR_ID_ADDIDATA,
+ PCI_DEVICE_ID_ADDIDATA_APCIe7420,
+ PCI_ANY_ID,
+ PCI_ANY_ID,
+ 0,
+ 0,
+ pbn_ADDIDATA_PCIe_2_3906250 },
+
+ { PCI_VENDOR_ID_ADDIDATA,
+ PCI_DEVICE_ID_ADDIDATA_APCIe7300,
+ PCI_ANY_ID,
+ PCI_ANY_ID,
+ 0,
+ 0,
+ pbn_ADDIDATA_PCIe_1_3906250 },
+
+ { PCI_VENDOR_ID_ADDIDATA,
+ PCI_DEVICE_ID_ADDIDATA_APCIe7800,
+ PCI_ANY_ID,
+ PCI_ANY_ID,
+ 0,
+ 0,
+ pbn_ADDIDATA_PCIe_8_3906250 },
+
+ { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9835,
+ PCI_VENDOR_ID_IBM, 0x0299,
+ 0, 0, pbn_b0_bt_2_115200 },
+
+ /*
+ * other NetMos 9835 devices are most likely handled by the
+ * parport_serial driver, check drivers/parport/parport_serial.c
+ * before adding them here.
+ */
+
+ { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9901,
+ 0xA000, 0x1000,
+ 0, 0, pbn_b0_1_115200 },
+
+ /* the 9901 is a rebranded 9912 */
+ { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9912,
+ 0xA000, 0x1000,
+ 0, 0, pbn_b0_1_115200 },
+
+ { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9922,
+ 0xA000, 0x1000,
+ 0, 0, pbn_b0_1_115200 },
+
+ { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9904,
+ 0xA000, 0x1000,
+ 0, 0, pbn_b0_1_115200 },
+
+ { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9900,
+ 0xA000, 0x1000,
+ 0, 0, pbn_b0_1_115200 },
+
+ { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9900,
+ 0xA000, 0x3002,
+ 0, 0, pbn_NETMOS9900_2s_115200 },
+
+ /*
+ * Best Connectivity and Rosewill PCI Multi I/O cards
+ */
+
+ { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9865,
+ 0xA000, 0x1000,
+ 0, 0, pbn_b0_1_115200 },
+
+ { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9865,
+ 0xA000, 0x3002,
+ 0, 0, pbn_b0_bt_2_115200 },
+
+ { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9865,
+ 0xA000, 0x3004,
+ 0, 0, pbn_b0_bt_4_115200 },
+ /* Intel CE4100 */
+ { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CE4100_UART,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_ce4100_1_115200 },
+
+ /*
+ * Cronyx Omega PCI
+ */
+ { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_CRONYX_OMEGA,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_omegapci },
+
+ /*
+ * Broadcom TruManage
+ */
+ { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_BROADCOM_TRUMANAGE,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_brcm_trumanage },
+
+ /*
+ * AgeStar as-prs2-009
+ */
+ { PCI_VENDOR_ID_AGESTAR, PCI_DEVICE_ID_AGESTAR_9375,
+ PCI_ANY_ID, PCI_ANY_ID,
+ 0, 0, pbn_b0_bt_2_115200 },
+
+ /*
+ * WCH CH353 series devices: The 2S1P is handled by parport_serial
+ * so not listed here.
+ */
+ { PCI_VENDOR_ID_WCH, PCI_DEVICE_ID_WCH_CH353_4S,
+ PCI_ANY_ID, PCI_ANY_ID,
+ 0, 0, pbn_b0_bt_4_115200 },
+
+ { PCI_VENDOR_ID_WCH, PCI_DEVICE_ID_WCH_CH353_2S1PF,
+ PCI_ANY_ID, PCI_ANY_ID,
+ 0, 0, pbn_b0_bt_2_115200 },
+
+ { PCI_VENDOR_ID_WCH, PCI_DEVICE_ID_WCH_CH355_4S,
+ PCI_ANY_ID, PCI_ANY_ID,
+ 0, 0, pbn_b0_bt_4_115200 },
+
+ { PCIE_VENDOR_ID_WCH, PCIE_DEVICE_ID_WCH_CH382_2S,
+ PCI_ANY_ID, PCI_ANY_ID,
+ 0, 0, pbn_wch382_2 },
+
+ { PCIE_VENDOR_ID_WCH, PCIE_DEVICE_ID_WCH_CH384_4S,
+ PCI_ANY_ID, PCI_ANY_ID,
+ 0, 0, pbn_wch384_4 },
+
+ /* Fintek PCI serial cards */
+ { PCI_DEVICE(0x1c29, 0x1104), .driver_data = pbn_fintek_4 },
+ { PCI_DEVICE(0x1c29, 0x1108), .driver_data = pbn_fintek_8 },
+ { PCI_DEVICE(0x1c29, 0x1112), .driver_data = pbn_fintek_12 },
+ { PCI_DEVICE(0x1c29, 0x1204), .driver_data = pbn_fintek_F81504A },
+ { PCI_DEVICE(0x1c29, 0x1208), .driver_data = pbn_fintek_F81508A },
+ { PCI_DEVICE(0x1c29, 0x1212), .driver_data = pbn_fintek_F81512A },
+
+ /* MKS Tenta SCOM-080x serial cards */
+ { PCI_DEVICE(0x1601, 0x0800), .driver_data = pbn_b0_4_1250000 },
+ { PCI_DEVICE(0x1601, 0xa801), .driver_data = pbn_b0_4_1250000 },
+
+ /* Amazon PCI serial device */
+ { PCI_DEVICE(0x1d0f, 0x8250), .driver_data = pbn_b0_1_115200 },
+
+ /*
+ * These entries match devices with class COMMUNICATION_SERIAL,
+ * COMMUNICATION_MODEM or COMMUNICATION_MULTISERIAL
+ */
+ { PCI_ANY_ID, PCI_ANY_ID,
+ PCI_ANY_ID, PCI_ANY_ID,
+ PCI_CLASS_COMMUNICATION_SERIAL << 8,
+ 0xffff00, pbn_default },
+ { PCI_ANY_ID, PCI_ANY_ID,
+ PCI_ANY_ID, PCI_ANY_ID,
+ PCI_CLASS_COMMUNICATION_MODEM << 8,
+ 0xffff00, pbn_default },
+ { PCI_ANY_ID, PCI_ANY_ID,
+ PCI_ANY_ID, PCI_ANY_ID,
+ PCI_CLASS_COMMUNICATION_MULTISERIAL << 8,
+ 0xffff00, pbn_default },
+ { 0, }
+};
+
+static struct pci_driver serial_pci_driver = {
+ .name = "ns16550_serial_pci",
+ .probe = pciserial_init_one,
+ .id_table = serial_pci_tbl,
+};
+
+static int __init serial_pci_register(void)
+{
+ return pci_driver_register(&serial_pci_driver);
+}
+console_initcall(serial_pci_register);
diff --git a/drivers/usb/gadget/f_fastboot.c b/drivers/usb/gadget/f_fastboot.c
index 82a202cc21..35c4b8cf4c 100644
--- a/drivers/usb/gadget/f_fastboot.c
+++ b/drivers/usb/gadget/f_fastboot.c
@@ -861,7 +861,7 @@ static int check_ubi(struct f_fastboot *f_fb, struct file_list_entry *fentry,
if (filetype == filetype_ubi) {
fastboot_tx_print(f_fb, FASTBOOT_MSG_INFO,
- "This is an UBI image...");
+ "This is a UBI image...");
return 1;
} else {
fastboot_tx_print(f_fb, FASTBOOT_MSG_FAIL,
diff --git a/dts/src/arm/imx6-logicpd-baseboard.dtsi b/dts/src/arm/imx6-logicpd-baseboard.dtsi
index 2a6ce87071..9e027b9a5f 100644
--- a/dts/src/arm/imx6-logicpd-baseboard.dtsi
+++ b/dts/src/arm/imx6-logicpd-baseboard.dtsi
@@ -328,6 +328,10 @@
pinctrl-0 = <&pinctrl_pwm3>;
};
+&snvs_pwrkey {
+ status = "okay";
+};
+
&ssi2 {
status = "okay";
};
diff --git a/dts/src/arm/imx6qdl-sabreauto.dtsi b/dts/src/arm/imx6qdl-sabreauto.dtsi
index f3404dd105..cf628465cd 100644
--- a/dts/src/arm/imx6qdl-sabreauto.dtsi
+++ b/dts/src/arm/imx6qdl-sabreauto.dtsi
@@ -230,6 +230,8 @@
accelerometer@1c {
compatible = "fsl,mma8451";
reg = <0x1c>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mma8451_int>;
interrupt-parent = <&gpio6>;
interrupts = <31 IRQ_TYPE_LEVEL_LOW>;
};
@@ -628,6 +630,12 @@
>;
};
+ pinctrl_mma8451_int: mma8451intgrp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_BCLK__GPIO6_IO31 0xb0b1
+ >;
+ };
+
pinctrl_pwm3: pwm1grp {
fsl,pins = <
MX6QDL_PAD_SD4_DAT1__PWM3_OUT 0x1b0b1
diff --git a/dts/src/arm/stm32mp157c-ev1.dts b/dts/src/arm/stm32mp157c-ev1.dts
index 89d29b50c3..91fc0a315c 100644
--- a/dts/src/arm/stm32mp157c-ev1.dts
+++ b/dts/src/arm/stm32mp157c-ev1.dts
@@ -183,14 +183,12 @@
ov5640: camera@3c {
compatible = "ovti,ov5640";
- pinctrl-names = "default";
- pinctrl-0 = <&ov5640_pins>;
reg = <0x3c>;
clocks = <&clk_ext_camera>;
clock-names = "xclk";
DOVDD-supply = <&v2v8>;
- powerdown-gpios = <&stmfx_pinctrl 18 GPIO_ACTIVE_HIGH>;
- reset-gpios = <&stmfx_pinctrl 19 GPIO_ACTIVE_LOW>;
+ powerdown-gpios = <&stmfx_pinctrl 18 (GPIO_ACTIVE_HIGH | GPIO_PUSH_PULL)>;
+ reset-gpios = <&stmfx_pinctrl 19 (GPIO_ACTIVE_LOW | GPIO_PUSH_PULL)>;
rotation = <180>;
status = "okay";
@@ -223,15 +221,8 @@
joystick_pins: joystick {
pins = "gpio0", "gpio1", "gpio2", "gpio3", "gpio4";
- drive-push-pull;
bias-pull-down;
};
-
- ov5640_pins: camera {
- pins = "agpio2", "agpio3"; /* stmfx pins 18 & 19 */
- drive-push-pull;
- output-low;
- };
};
};
};
diff --git a/dts/src/arm/stm32mp157c.dtsi b/dts/src/arm/stm32mp157c.dtsi
index 9b11654a0a..f98e0370c0 100644
--- a/dts/src/arm/stm32mp157c.dtsi
+++ b/dts/src/arm/stm32mp157c.dtsi
@@ -932,7 +932,7 @@
interrupt-names = "int0", "int1";
clocks = <&rcc CK_HSE>, <&rcc FDCAN_K>;
clock-names = "hclk", "cclk";
- bosch,mram-cfg = <0x1400 0 0 32 0 0 2 2>;
+ bosch,mram-cfg = <0x0 0 0 32 0 0 2 2>;
status = "disabled";
};
@@ -945,7 +945,7 @@
interrupt-names = "int0", "int1";
clocks = <&rcc CK_HSE>, <&rcc FDCAN_K>;
clock-names = "hclk", "cclk";
- bosch,mram-cfg = <0x0 0 0 32 0 0 2 2>;
+ bosch,mram-cfg = <0x1400 0 0 32 0 0 2 2>;
status = "disabled";
};
diff --git a/dts/src/arm/sun8i-a83t-tbs-a711.dts b/dts/src/arm/sun8i-a83t-tbs-a711.dts
index 568b90ece3..3bec3e0a81 100644
--- a/dts/src/arm/sun8i-a83t-tbs-a711.dts
+++ b/dts/src/arm/sun8i-a83t-tbs-a711.dts
@@ -192,6 +192,7 @@
vqmmc-supply = <&reg_dldo1>;
non-removable;
wakeup-source;
+ keep-power-in-suspend;
status = "okay";
brcmf: wifi@1 {
diff --git a/dts/src/arm64/freescale/fsl-ls1028a-qds.dts b/dts/src/arm64/freescale/fsl-ls1028a-qds.dts
index d98346da01..078a501022 100644
--- a/dts/src/arm64/freescale/fsl-ls1028a-qds.dts
+++ b/dts/src/arm64/freescale/fsl-ls1028a-qds.dts
@@ -127,7 +127,7 @@
status = "okay";
i2c-mux@77 {
- compatible = "nxp,pca9847";
+ compatible = "nxp,pca9547";
reg = <0x77>;
#address-cells = <1>;
#size-cells = <0>;
diff --git a/dts/src/arm64/freescale/imx8mm.dtsi b/dts/src/arm64/freescale/imx8mm.dtsi
index 58b8cd06ca..23c8fad793 100644
--- a/dts/src/arm64/freescale/imx8mm.dtsi
+++ b/dts/src/arm64/freescale/imx8mm.dtsi
@@ -394,7 +394,7 @@
};
sdma2: dma-controller@302c0000 {
- compatible = "fsl,imx8mm-sdma", "fsl,imx7d-sdma";
+ compatible = "fsl,imx8mm-sdma", "fsl,imx8mq-sdma";
reg = <0x302c0000 0x10000>;
interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clk IMX8MM_CLK_SDMA2_ROOT>,
@@ -405,7 +405,7 @@
};
sdma3: dma-controller@302b0000 {
- compatible = "fsl,imx8mm-sdma", "fsl,imx7d-sdma";
+ compatible = "fsl,imx8mm-sdma", "fsl,imx8mq-sdma";
reg = <0x302b0000 0x10000>;
interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clk IMX8MM_CLK_SDMA3_ROOT>,
@@ -737,7 +737,7 @@
};
sdma1: dma-controller@30bd0000 {
- compatible = "fsl,imx8mm-sdma", "fsl,imx7d-sdma";
+ compatible = "fsl,imx8mm-sdma", "fsl,imx8mq-sdma";
reg = <0x30bd0000 0x10000>;
interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clk IMX8MM_CLK_SDMA1_ROOT>,
diff --git a/dts/src/arm64/freescale/imx8mn.dtsi b/dts/src/arm64/freescale/imx8mn.dtsi
index 98496f5707..43c4db3121 100644
--- a/dts/src/arm64/freescale/imx8mn.dtsi
+++ b/dts/src/arm64/freescale/imx8mn.dtsi
@@ -288,7 +288,7 @@
};
sdma3: dma-controller@302b0000 {
- compatible = "fsl,imx8mn-sdma", "fsl,imx7d-sdma";
+ compatible = "fsl,imx8mn-sdma", "fsl,imx8mq-sdma";
reg = <0x302b0000 0x10000>;
interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clk IMX8MN_CLK_SDMA3_ROOT>,
@@ -299,7 +299,7 @@
};
sdma2: dma-controller@302c0000 {
- compatible = "fsl,imx8mn-sdma", "fsl,imx7d-sdma";
+ compatible = "fsl,imx8mn-sdma", "fsl,imx8mq-sdma";
reg = <0x302c0000 0x10000>;
interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clk IMX8MN_CLK_SDMA2_ROOT>,
@@ -612,7 +612,7 @@
};
sdma1: dma-controller@30bd0000 {
- compatible = "fsl,imx8mn-sdma", "fsl,imx7d-sdma";
+ compatible = "fsl,imx8mn-sdma", "fsl,imx8mq-sdma";
reg = <0x30bd0000 0x10000>;
interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clk IMX8MN_CLK_SDMA1_ROOT>,
diff --git a/dts/src/arm64/freescale/imx8mq-zii-ultra.dtsi b/dts/src/arm64/freescale/imx8mq-zii-ultra.dtsi
index 087b5b6ebe..32ce14936b 100644
--- a/dts/src/arm64/freescale/imx8mq-zii-ultra.dtsi
+++ b/dts/src/arm64/freescale/imx8mq-zii-ultra.dtsi
@@ -88,7 +88,7 @@
regulator-name = "0V9_ARM";
regulator-min-microvolt = <900000>;
regulator-max-microvolt = <1000000>;
- gpios = <&gpio3 19 GPIO_ACTIVE_HIGH>;
+ gpios = <&gpio3 16 GPIO_ACTIVE_HIGH>;
states = <1000000 0x1
900000 0x0>;
regulator-always-on;
diff --git a/images/Makefile.imx b/images/Makefile.imx
index a8f8a9b7d6..53d4ac8202 100644
--- a/images/Makefile.imx
+++ b/images/Makefile.imx
@@ -2,6 +2,24 @@
# barebox image generation Makefile for i.MX images
#
+# params: CONFIG symbol, entry point, flash header path string, board identifier string
+define build_imx_habv4img =
+$(eval
+ifeq ($($(strip $(1))), y)
+ pblb-y += $(strip $(2))
+ CFG_$(strip $(2)).pblb.imximg = $(board)/$(strip $(3)).imxcfg
+ FILE_barebox-$(strip $(4)).img = $(strip $(2)).pblb.imximg
+ FILE_barebox-$(strip $(4))-s.img = $(strip $(2)).pblb.simximg
+ FILE_barebox-$(strip $(4))-us.img = $(strip $(2)).pblb.usimximg
+ FILE_barebox-$(strip $(4))-es.img = $(strip $(2)).pblb.esimximg
+ image-y += barebox-$(strip $(4)).img
+ image-$(CONFIG_HABV4_IMAGE_SIGNED) += barebox-$(strip $(4))-s.img
+ image-$(CONFIG_HABV4_IMAGE_SIGNED_USB) += barebox-$(strip $(4))-us.img
+ image-$(CONFIG_HABV4_IMAGE_SIGNED_ENCRYPTED) += barebox-$(strip $(4))-es.img
+endif
+)
+endef
+
# %.imximg - convert into i.MX image
# ----------------------------------------------------------------
@@ -13,17 +31,20 @@ $(obj)/%.pimximg: $(obj)/% FORCE
-p $($(patsubst $(obj)/%.pblb,PBL_MEMORY_SIZE_%,$<)))
$(obj)/%.psimximg: $(obj)/% FORCE
- $(call if_changed,imx_image,$(CFG_$(patsubst %.psimximg,%.imximg,$(@F))),-s \
- -p $($(patsubst $(obj)/%.pblb,PBL_MEMORY_SIZE_%,$<)))
+ $(call if_changed,imx_image,$(CFG_$(patsubst %.psimximg,%.imximg,$(@F))),\
+ -p $($(patsubst $(obj)/%.pblb,PBL_MEMORY_SIZE_%,$<)) -s)
$(obj)/%.simximg: $(obj)/% FORCE
$(call if_changed,imx_image,$(CFG_$(patsubst %.simximg,%.imximg,$(@F))),-s)
$(obj)/%.usimximg: $(obj)/% FORCE
- $(call if_changed,imx_image,$(CFG_$(patsubst %.usimximg,%.imximg,$(@F))),-s -u)
+ $(call if_changed,imx_image,$(CFG_$(patsubst %.usimximg,%.imximg,$(@F))),-u -s)
+
+$(obj)/%.esimximg: $(obj)/% FORCE
+ $(call if_changed,imx_image,$(CFG_$(patsubst %.esimximg,%.imximg,$(@F))),-e -s)
-$(obj)/%.esimximg $(obj)/%.esimximg.dek: $(obj)/% FORCE
- $(call if_changed,imx_image,$(CFG_$(patsubst %.esimximg,%.imximg,$(@F))),-s -e)
+$(obj)/%.esimximg.dek: $(obj)/% FORCE
+ $(call if_changed,imx_image,$(CFG_$(patsubst %.esimximg,%.imximg,$(@F))),-e -s)
.SECONDEXPANSION:
$(obj)/%.img.dek: $(obj)/$$(FILE_$$(@F))
@@ -156,406 +177,166 @@ FILE_barebox-tx53-1011.img = start_imx53_tx53_1011.pblb.imximg
image-$(CONFIG_MACH_TX53) += barebox-tx53-1011.img
# ----------------------- i.MX6 based boards ---------------------------
-pblb-$(CONFIG_MACH_REALQ7) += start_imx6_realq7
-CFG_start_imx6_realq7.pblb.imximg = $(board)/datamodul-edm-qmx6/flash-header.imxcfg
-FILE_barebox-datamodul-edm-qmx6.img = start_imx6_realq7.pblb.imximg
-image-$(CONFIG_MACH_REALQ7) += barebox-datamodul-edm-qmx6.img
-
-pblb-$(CONFIG_MACH_GUF_SANTARO) += start_imx6q_guf_santaro
-CFG_start_imx6q_guf_santaro.pblb.imximg = $(board)/guf-santaro/flash-header.imxcfg
-FILE_barebox-guf-santaro.img = start_imx6q_guf_santaro.pblb.imximg
-image-$(CONFIG_MACH_GUF_SANTARO) += barebox-guf-santaro.img
-
-pblb-$(CONFIG_MACH_GK802) += start_imx6_gk802
-CFG_start_imx6_gk802.pblb.imximg = $(board)/gk802/flash-header.imxcfg
-FILE_barebox-gk802.img = start_imx6_gk802.pblb.imximg
-image-$(CONFIG_MACH_GK802) += barebox-gk802.img
-
-pblb-$(CONFIG_MACH_TQMA6X) += start_imx6dl_mba6x
-CFG_start_imx6dl_mba6x.pblb.imximg = $(board)/tqma6x/flash-header-tqma6dl.imxcfg
-FILE_barebox-tq-tqma6s-mba6x.img = start_imx6dl_mba6x.pblb.imximg
-image-$(CONFIG_MACH_TQMA6X) += barebox-tq-tqma6s-mba6x.img
-
-pblb-$(CONFIG_MACH_TQMA6X) += start_imx6q_mba6x
-CFG_start_imx6q_mba6x.pblb.imximg = $(board)/tqma6x/flash-header-tqma6q.imxcfg
-FILE_barebox-tq-tqma6q-mba6x.img = start_imx6q_mba6x.pblb.imximg
-image-$(CONFIG_MACH_TQMA6X) += barebox-tq-tqma6q-mba6x.img
-
-pblb-$(CONFIG_MACH_PHYTEC_SOM_IMX6) += start_phytec_pbab01_4gib
-CFG_start_phytec_pbab01_4gib.pblb.imximg = $(board)/phytec-som-imx6/flash-header-phytec-pfla02-4gib.imxcfg
-FILE_barebox-phytec-pbab01-4gib.img = start_phytec_pbab01_4gib.pblb.imximg
-image-$(CONFIG_MACH_PHYTEC_SOM_IMX6) += barebox-phytec-pbab01-4gib.img
-
-pblb-$(CONFIG_MACH_PHYTEC_SOM_IMX6) += start_phytec_pbab01_2gib
-CFG_start_phytec_pbab01_2gib.pblb.imximg = $(board)/phytec-som-imx6/flash-header-phytec-pfla02-2gib.imxcfg
-FILE_barebox-phytec-pbab01-2gib.img = start_phytec_pbab01_2gib.pblb.imximg
-image-$(CONFIG_MACH_PHYTEC_SOM_IMX6) += barebox-phytec-pbab01-2gib.img
-
-pblb-$(CONFIG_MACH_PHYTEC_SOM_IMX6) += start_phytec_pbab01_1gib
-CFG_start_phytec_pbab01_1gib.pblb.imximg = $(board)/phytec-som-imx6/flash-header-phytec-pfla02-1gib.imxcfg
-FILE_barebox-phytec-pbab01-1gib.img = start_phytec_pbab01_1gib.pblb.imximg
-image-$(CONFIG_MACH_PHYTEC_SOM_IMX6) += barebox-phytec-pbab01-1gib.img
-
-pblb-$(CONFIG_MACH_PHYTEC_SOM_IMX6) += start_phytec_pbab01_1gib_1bank
-CFG_start_phytec_pbab01_1gib_1bank.pblb.imximg = $(board)/phytec-som-imx6/flash-header-phytec-pfla02-1gib-1bank.imxcfg
-FILE_barebox-phytec-pbab01-1gib-1bank.img = start_phytec_pbab01_1gib_1bank.pblb.imximg
-image-$(CONFIG_MACH_PHYTEC_SOM_IMX6) += barebox-phytec-pbab01-1gib-1bank.img
-
-pblb-$(CONFIG_MACH_PHYTEC_SOM_IMX6) += start_phytec_pbab01_512mb_1bank
-CFG_start_phytec_pbab01_512mb_1bank.pblb.imximg = $(board)/phytec-som-imx6/flash-header-phytec-pfla02-512mb-1bank.imxcfg
-FILE_barebox-phytec-pbab01-512mb-1bank.img = start_phytec_pbab01_512mb_1bank.pblb.imximg
-image-$(CONFIG_MACH_PHYTEC_SOM_IMX6) += barebox-phytec-pbab01-512mb-1bank.img
-
-pblb-$(CONFIG_MACH_PHYTEC_SOM_IMX6) += start_phytec_pbab01dl_1gib
-CFG_start_phytec_pbab01dl_1gib.pblb.imximg = $(board)/phytec-som-imx6/flash-header-phytec-pfla02dl-1gib.imxcfg
-FILE_barebox-phytec-pbab01dl-1gib.img = start_phytec_pbab01dl_1gib.pblb.imximg
-image-$(CONFIG_MACH_PHYTEC_SOM_IMX6) += barebox-phytec-pbab01dl-1gib.img
-
-pblb-$(CONFIG_MACH_PHYTEC_SOM_IMX6) += start_phytec_pbab01dl_1gib_1bank
-CFG_start_phytec_pbab01dl_1gib_1bank.pblb.imximg = $(board)/phytec-som-imx6/flash-header-phytec-pfla02dl-1gib-1bank.imxcfg
-FILE_barebox-phytec-pbab01dl-1gib-1bank.img = start_phytec_pbab01dl_1gib_1bank.pblb.imximg
-image-$(CONFIG_MACH_PHYTEC_SOM_IMX6) += barebox-phytec-pbab01dl-1gib-1bank.img
-
-pblb-$(CONFIG_MACH_PHYTEC_SOM_IMX6) += start_phytec_pbab01s_512mb_1bank
-CFG_start_phytec_pbab01s_512mb_1bank.pblb.imximg = $(board)/phytec-som-imx6/flash-header-phytec-pfla02s-512mb-1bank.imxcfg
-FILE_barebox-phytec-pbab01s-512mb-1bank.img = start_phytec_pbab01s_512mb_1bank.pblb.imximg
-image-$(CONFIG_MACH_PHYTEC_SOM_IMX6) += barebox-phytec-pbab01s-512mb-1bank.img
-
-pblb-$(CONFIG_MACH_PHYTEC_SOM_IMX6) += start_phytec_pbab01s_256mb_1bank
-CFG_start_phytec_pbab01s_256mb_1bank.pblb.imximg = $(board)/phytec-som-imx6/flash-header-phytec-pfla02s-256mb-1bank.imxcfg
-FILE_barebox-phytec-pbab01s-256mb-1bank.img = start_phytec_pbab01s_256mb_1bank.pblb.imximg
-image-$(CONFIG_MACH_PHYTEC_SOM_IMX6) += barebox-phytec-pbab01s-256mb-1bank.img
-
-pblb-$(CONFIG_MACH_PHYTEC_SOM_IMX6) += start_phytec_pbab01s_128mb_1bank
-CFG_start_phytec_pbab01s_128mb_1bank.pblb.imximg = $(board)/phytec-som-imx6/flash-header-phytec-pfla02s-128mb-1bank.imxcfg
-FILE_barebox-phytec-pbab01s-128mb-1bank.img = start_phytec_pbab01s_128mb_1bank.pblb.imximg
-image-$(CONFIG_MACH_PHYTEC_SOM_IMX6) += barebox-phytec-pbab01s-128mb-1bank.img
-
-pblb-$(CONFIG_MACH_PHYTEC_SOM_IMX6) += start_phytec_phyboard_alcor_1gib
-CFG_start_phytec_phyboard_alcor_1gib.pblb.imximg = $(board)/phytec-som-imx6/flash-header-phytec-pfla02-1gib.imxcfg
-FILE_barebox-phytec-phyboard-alcor-1gib.img = start_phytec_phyboard_alcor_1gib.pblb.imximg
-image-$(CONFIG_MACH_PHYTEC_SOM_IMX6) += barebox-phytec-phyboard-alcor-1gib.img
-
-pblb-$(CONFIG_MACH_PHYTEC_SOM_IMX6) += start_phytec_phyboard_subra_512mb_1bank
-CFG_start_phytec_phyboard_subra_512mb_1bank.pblb.imximg = $(board)/phytec-som-imx6/flash-header-phytec-pfla02s-512mb-1bank.imxcfg
-FILE_barebox-phytec-phyboard-subra-512mb-1bank.img = start_phytec_phyboard_subra_512mb_1bank.pblb.imximg
-image-$(CONFIG_MACH_PHYTEC_SOM_IMX6) += barebox-phytec-phyboard-subra-512mb-1bank.img
-
-pblb-$(CONFIG_MACH_PHYTEC_SOM_IMX6) += start_phytec_phyboard_subra_1gib_1bank
-CFG_start_phytec_phyboard_subra_1gib_1bank.pblb.imximg = $(board)/phytec-som-imx6/flash-header-phytec-pfla02-1gib-1bank.imxcfg
-FILE_barebox-phytec-phyboard-subra-1gib-1bank.img = start_phytec_phyboard_subra_1gib_1bank.pblb.imximg
-image-$(CONFIG_MACH_PHYTEC_SOM_IMX6) += barebox-phytec-phyboard-subra-1gib-1bank.img
-
-pblb-$(CONFIG_MACH_DFI_FS700_M60) += start_imx6dl_dfi_fs700_m60_6s
-CFG_start_imx6dl_dfi_fs700_m60_6s.pblb.imximg = $(board)/dfi-fs700-m60/flash-header-fs700-m60-6s.imxcfg
-FILE_barebox-dfi-fs700-m60-6s.img = start_imx6dl_dfi_fs700_m60_6s.pblb.imximg
-image-$(CONFIG_MACH_DFI_FS700_M60) += barebox-dfi-fs700-m60-6s.img
-
-pblb-$(CONFIG_MACH_DFI_FS700_M60) += start_imx6q_dfi_fs700_m60_6q_micron
-CFG_start_imx6q_dfi_fs700_m60_6q_micron.pblb.imximg = $(board)/dfi-fs700-m60/flash-header-fs700-m60-6q-micron.imxcfg
-FILE_barebox-dfi-fs700-m60-6q-micron.img = start_imx6q_dfi_fs700_m60_6q_micron.pblb.imximg
-image-$(CONFIG_MACH_DFI_FS700_M60) += barebox-dfi-fs700-m60-6q-micron.img
-
-pblb-$(CONFIG_MACH_DFI_FS700_M60) += start_imx6q_dfi_fs700_m60_6q_nanya
-CFG_start_imx6q_dfi_fs700_m60_6q_nanya.pblb.imximg = $(board)/dfi-fs700-m60/flash-header-fs700-m60-6q-nanya.imxcfg
-FILE_barebox-dfi-fs700-m60-6q-nanya.img = start_imx6q_dfi_fs700_m60_6q_nanya.pblb.imximg
-image-$(CONFIG_MACH_DFI_FS700_M60) += barebox-dfi-fs700-m60-6q-nanya.img
-
-pblb-$(CONFIG_MACH_SABRELITE) += start_imx6q_sabrelite
-CFG_start_imx6q_sabrelite.pblb.imximg = $(board)/freescale-mx6-sabrelite/flash-header-mx6-sabrelite.imxcfg
-FILE_barebox-freescale-imx6q-sabrelite.img = start_imx6q_sabrelite.pblb.imximg
-image-$(CONFIG_MACH_SABRELITE) += barebox-freescale-imx6q-sabrelite.img
-
-pblb-$(CONFIG_MACH_SABRELITE) += start_imx6dl_sabrelite
-CFG_start_imx6dl_sabrelite.pblb.imximg = $(board)/freescale-mx6-sabrelite/flash-header-mx6-sabrelite.imxcfg
-FILE_barebox-freescale-imx6dl-sabrelite.img = start_imx6dl_sabrelite.pblb.imximg
-image-$(CONFIG_MACH_SABRELITE) += barebox-freescale-imx6dl-sabrelite.img
-
-pblb-$(CONFIG_MACH_SABRESD) += start_imx6q_sabresd
-CFG_start_imx6q_sabresd.pblb.imximg = $(board)/freescale-mx6-sabresd/flash-header-mx6-sabresd.imxcfg
-FILE_barebox-freescale-imx6q-sabresd.img = start_imx6q_sabresd.pblb.imximg
-image-$(CONFIG_MACH_SABRESD) += barebox-freescale-imx6q-sabresd.img
-
-pblb-$(CONFIG_MACH_UDOO_NEO) += start_imx6sx_udoo_neo
-CFG_start_imx6sx_udoo_neo.pblb.imximg = $(board)/udoo-neo/flash-header-mx6sx-udoo-neo_full.imxcfg
-FILE_barebox-udoo-neo.img = start_imx6sx_udoo_neo.pblb.imximg
-image-$(CONFIG_MACH_UDOO_NEO) += barebox-udoo-neo.img
-
-pblb-$(CONFIG_MACH_FREESCALE_IMX6SX_SABRESDB) += start_imx6sx_sabresdb
-CFG_start_imx6sx_sabresdb.pblb.imximg = $(board)/freescale-mx6sx-sabresdb/flash-header-mx6sx-sabresdb.imxcfg
-FILE_barebox-freescale-imx6sx-sabresdb.img = start_imx6sx_sabresdb.pblb.imximg
-image-$(CONFIG_MACH_FREESCALE_IMX6SX_SABRESDB) += barebox-freescale-imx6sx-sabresdb.img
-
-pblb-$(CONFIG_MACH_TECHNEXION_WANDBOARD) += start_imx6_wandboard
-CFG_start_imx6_wandboard.pblb.imximg = $(board)/technexion-wandboard/flash-header-technexion-wandboard.imxcfg
-FILE_barebox-imx6-wandboard.img = start_imx6_wandboard.pblb.imximg
-image-$(CONFIG_MACH_TECHNEXION_WANDBOARD) += barebox-imx6-wandboard.img
-
-pblb-$(CONFIG_MACH_SOLIDRUN_MICROSOM) += start_hummingboard_microsom_i1
-CFG_start_hummingboard_microsom_i1.pblb.imximg = $(board)/solidrun-microsom/flash-header-microsom-i1.imxcfg
-FILE_barebox-solidrun-hummingboard-microsom-i1.img = start_hummingboard_microsom_i1.pblb.imximg
-image-$(CONFIG_MACH_SOLIDRUN_MICROSOM) += barebox-solidrun-hummingboard-microsom-i1.img
-
-pblb-$(CONFIG_MACH_SOLIDRUN_MICROSOM) += start_hummingboard_microsom_i2
-CFG_start_hummingboard_microsom_i2.pblb.imximg = $(board)/solidrun-microsom/flash-header-microsom-i2.imxcfg
-FILE_barebox-solidrun-hummingboard-microsom-i2.img = start_hummingboard_microsom_i2.pblb.imximg
-image-$(CONFIG_MACH_SOLIDRUN_MICROSOM) += barebox-solidrun-hummingboard-microsom-i2.img
-
-pblb-$(CONFIG_MACH_SOLIDRUN_MICROSOM) += start_hummingboard_microsom_i2ex
-CFG_start_hummingboard_microsom_i2ex.pblb.imximg = $(board)/solidrun-microsom/flash-header-microsom-i2eX.imxcfg
-FILE_barebox-solidrun-hummingboard-microsom-i2eX.img = start_hummingboard_microsom_i2ex.pblb.imximg
-image-$(CONFIG_MACH_SOLIDRUN_MICROSOM) += barebox-solidrun-hummingboard-microsom-i2eX.img
-
-pblb-$(CONFIG_MACH_SOLIDRUN_MICROSOM) += start_hummingboard_microsom_i4
-CFG_start_hummingboard_microsom_i4.pblb.imximg = $(board)/solidrun-microsom/flash-header-microsom-i4.imxcfg
-FILE_barebox-solidrun-hummingboard-microsom-i4.img = start_hummingboard_microsom_i4.pblb.imximg
-image-$(CONFIG_MACH_SOLIDRUN_MICROSOM) += barebox-solidrun-hummingboard-microsom-i4.img
-
-pblb-$(CONFIG_MACH_SOLIDRUN_MICROSOM) += start_hummingboard2_microsom_i1
-CFG_start_hummingboard2_microsom_i1.pblb.imximg = $(board)/solidrun-microsom/flash-header-microsom-i1.imxcfg
-FILE_barebox-solidrun-hummingboard2-microsom-i1.img = start_hummingboard2_microsom_i1.pblb.imximg
-image-$(CONFIG_MACH_SOLIDRUN_MICROSOM) += barebox-solidrun-hummingboard2-microsom-i1.img
-
-pblb-$(CONFIG_MACH_SOLIDRUN_MICROSOM) += start_hummingboard2_microsom_i2
-CFG_start_hummingboard2_microsom_i2.pblb.imximg = $(board)/solidrun-microsom/flash-header-microsom-i2.imxcfg
-FILE_barebox-solidrun-hummingboard2-microsom-i2.img = start_hummingboard2_microsom_i2.pblb.imximg
-image-$(CONFIG_MACH_SOLIDRUN_MICROSOM) += barebox-solidrun-hummingboard2-microsom-i2.img
-
-pblb-$(CONFIG_MACH_SOLIDRUN_MICROSOM) += start_hummingboard2_microsom_i2ex
-CFG_start_hummingboard2_microsom_i2ex.pblb.imximg = $(board)/solidrun-microsom/flash-header-microsom-i2eX.imxcfg
-FILE_barebox-solidrun-hummingboard2-microsom-i2eX.img = start_hummingboard2_microsom_i2ex.pblb.imximg
-image-$(CONFIG_MACH_SOLIDRUN_MICROSOM) += barebox-solidrun-hummingboard2-microsom-i2eX.img
-
-pblb-$(CONFIG_MACH_SOLIDRUN_MICROSOM) += start_hummingboard2_microsom_i4
-CFG_start_hummingboard2_microsom_i4.pblb.imximg = $(board)/solidrun-microsom/flash-header-microsom-i4.imxcfg
-FILE_barebox-solidrun-hummingboard2-microsom-i4.img = start_hummingboard2_microsom_i4.pblb.imximg
-image-$(CONFIG_MACH_SOLIDRUN_MICROSOM) += barebox-solidrun-hummingboard2-microsom-i4.img
-
-pblb-$(CONFIG_MACH_SOLIDRUN_MICROSOM) += start_h100_microsom_i2ex
-CFG_start_h100_microsom_i2ex.pblb.imximg = $(board)/solidrun-microsom/flash-header-microsom-i2eX.imxcfg
-FILE_barebox-auvidea-h100-microsom-i2eX.img = start_h100_microsom_i2ex.pblb.imximg
-image-$(CONFIG_MACH_SOLIDRUN_MICROSOM) += barebox-auvidea-h100-microsom-i2eX.img
-
-pblb-$(CONFIG_MACH_NITROGEN6) += start_imx6q_nitrogen6x_1g
-CFG_start_imx6q_nitrogen6x_1g.pblb.imximg = $(board)/boundarydevices-nitrogen6/flash-header-nitrogen6q-1g.imxcfg
-FILE_barebox-boundarydevices-imx6q-nitrogen6x-1g.img = start_imx6q_nitrogen6x_1g.pblb.imximg
-image-$(CONFIG_MACH_NITROGEN6) += barebox-boundarydevices-imx6q-nitrogen6x-1g.img
-
-pblb-$(CONFIG_MACH_NITROGEN6) += start_imx6q_nitrogen6x_2g
-CFG_start_imx6q_nitrogen6x_2g.pblb.imximg = $(board)/boundarydevices-nitrogen6/flash-header-nitrogen6q-2g.imxcfg
-FILE_barebox-boundarydevices-imx6q-nitrogen6x-2g.img = start_imx6q_nitrogen6x_2g.pblb.imximg
-image-$(CONFIG_MACH_NITROGEN6) += barebox-boundarydevices-imx6q-nitrogen6x-2g.img
-
-pblb-$(CONFIG_MACH_NITROGEN6) += start_imx6dl_nitrogen6x_1g
-CFG_start_imx6dl_nitrogen6x_1g.pblb.imximg = $(board)/boundarydevices-nitrogen6/flash-header-nitrogen6dl-1g.imxcfg
-FILE_barebox-boundarydevices-imx6dl-nitrogen6x-1g.img = start_imx6dl_nitrogen6x_1g.pblb.imximg
-image-$(CONFIG_MACH_NITROGEN6) += barebox-boundarydevices-imx6dl-nitrogen6x-1g.img
-
-pblb-$(CONFIG_MACH_NITROGEN6) += start_imx6dl_nitrogen6x_2g
-CFG_start_imx6dl_nitrogen6x_2g.pblb.imximg = $(board)/boundarydevices-nitrogen6/flash-header-nitrogen6dl-2g.imxcfg
-FILE_barebox-boundarydevices-imx6dl-nitrogen6x-2g.img = start_imx6dl_nitrogen6x_2g.pblb.imximg
-image-$(CONFIG_MACH_NITROGEN6) += barebox-boundarydevices-imx6dl-nitrogen6x-2g.img
-
-pblb-$(CONFIG_MACH_NITROGEN6) += start_imx6qp_nitrogen6_max
-CFG_start_imx6qp_nitrogen6_max.pblb.imximg = $(board)/boundarydevices-nitrogen6/flash-header-nitrogen6qp-max.imxcfg
-FILE_barebox-boundarydevices-imx6qp-nitrogen6_max.img = start_imx6qp_nitrogen6_max.pblb.imximg
-image-$(CONFIG_MACH_NITROGEN6) += barebox-boundarydevices-imx6qp-nitrogen6_max.img
-
-pblb-$(CONFIG_MACH_TX6X) += start_imx6dl_tx6x_512m
-CFG_start_imx6dl_tx6x_512m.pblb.imximg = $(board)/karo-tx6x/flash-header-tx6dl-512m.imxcfg
-FILE_barebox-karo-imx6dl-tx6x-512m.img = start_imx6dl_tx6x_512m.pblb.imximg
-image-$(CONFIG_MACH_TX6X) += barebox-karo-imx6dl-tx6x-512m.img
-
-pblb-$(CONFIG_MACH_TX6X) += start_imx6dl_tx6x_1g
-CFG_start_imx6dl_tx6x_1g.pblb.imximg = $(board)/karo-tx6x/flash-header-tx6dl-1g.imxcfg
-FILE_barebox-karo-imx6dl-tx6x-1g.img = start_imx6dl_tx6x_1g.pblb.imximg
-image-$(CONFIG_MACH_TX6X) += barebox-karo-imx6dl-tx6x-1g.img
-
-pblb-$(CONFIG_MACH_TX6X) += start_imx6q_tx6x_1g
-CFG_start_imx6q_tx6x_1g.pblb.imximg = $(board)/karo-tx6x/flash-header-tx6q-1g.imxcfg
-FILE_barebox-karo-imx6q-tx6x-1g.img = start_imx6q_tx6x_1g.pblb.imximg
-image-$(CONFIG_MACH_TX6X) += barebox-karo-imx6q-tx6x-1g.img
-
-pblb-$(CONFIG_MACH_TX6X) += start_imx6q_tx6x_2g
-CFG_start_imx6q_tx6x_2g.pblb.imximg = $(board)/karo-tx6x/flash-header-tx6qp-2g.imxcfg
-FILE_barebox-karo-imx6qp-tx6x-2g.img = start_imx6q_tx6x_2g.pblb.imximg
-image-$(CONFIG_MACH_TX6X) += barebox-karo-imx6qp-tx6x-2g.img
-
-pblb-$(CONFIG_MACH_UDOO) += start_imx6_udoo
-CFG_start_imx6_udoo.pblb.imximg = $(board)/udoo/flash-header-mx6-udoo.imxcfg
-FILE_barebox-udoo-imx6q.img = start_imx6_udoo.pblb.imximg
-image-$(CONFIG_MACH_UDOO) += barebox-udoo-imx6q.img
-
-pblb-$(CONFIG_MACH_CM_FX6) += start_imx6_cm_fx6
-CFG_start_imx6_cm_fx6.pblb.imximg = $(board)/cm-fx6/flash-header-mx6-cm-fx6.imxcfg
-FILE_barebox-cm-fx6.img = start_imx6_cm_fx6.pblb.imximg
-image-$(CONFIG_MACH_CM_FX6) += barebox-cm-fx6.img
-
-pblb-$(CONFIG_MACH_CM_FX6) += start_imx6_utilite
-CFG_start_imx6_utilite.pblb.imximg = $(board)/cm-fx6/flash-header-mx6-cm-fx6.imxcfg
-FILE_barebox-utilite.img = start_imx6_utilite.pblb.imximg
-image-$(CONFIG_MACH_CM_FX6) += barebox-utilite.img
-
-pblb-$(CONFIG_MACH_VARISCITE_MX6) += start_variscite_custom
-CFG_start_variscite_custom.pblb.imximg = $(board)/variscite-mx6/flash-header-variscite.imxcfg
-FILE_barebox-variscite-custom.img = start_variscite_custom.pblb.imximg
-image-$(CONFIG_MACH_VARISCITE_MX6) += barebox-variscite-custom.img
-
-pblb-$(CONFIG_MACH_EMBEDSKY_E9) += start_imx6q_embedsky_e9
-CFG_start_imx6q_embedsky_e9.pblb.imximg = $(board)/embedsky-e9/flash-header-e9.imxcfg
-FILE_barebox-embedsky-imx6q-e9.img = start_imx6q_embedsky_e9.pblb.imximg
-image-$(CONFIG_MACH_EMBEDSKY_E9) += barebox-embedsky-imx6q-e9.img
-
-pblb-$(CONFIG_MACH_EMBEST_MARSBOARD) += start_imx6q_marsboard
-CFG_start_imx6q_marsboard.pblb.imximg = $(board)/embest-marsboard/flash-header-embest-marsboard.imxcfg
-FILE_barebox-embest-imx6q-marsboard.img = start_imx6q_marsboard.pblb.imximg
-image-$(CONFIG_MACH_EMBEST_MARSBOARD) += barebox-embest-imx6q-marsboard.img
-
-pblb-$(CONFIG_MACH_EMBEST_RIOTBOARD) += start_imx6s_riotboard
-CFG_start_imx6s_riotboard.pblb.imximg = $(board)/embest-riotboard/flash-header-embest-riotboard.imxcfg
-FILE_barebox-embest-imx6s-riotboard.img = start_imx6s_riotboard.pblb.imximg
-image-$(CONFIG_MACH_EMBEST_RIOTBOARD) += barebox-embest-imx6s-riotboard.img
-
-pblb-$(CONFIG_MACH_PHYTEC_SOM_IMX6) += start_phytec_pbaa03_1gib
-CFG_start_phytec_pbaa03_1gib.pblb.imximg = $(board)/phytec-som-imx6/flash-header-phytec-pcaaxl3-1gib.imxcfg
-FILE_barebox-phytec-pbaa03-1gib.img = start_phytec_pbaa03_1gib.pblb.imximg
-image-$(CONFIG_MACH_PHYTEC_SOM_IMX6) += barebox-phytec-pbaa03-1gib.img
-
-pblb-$(CONFIG_MACH_PHYTEC_SOM_IMX6) += start_phytec_pbaa03_1gib_1bank
-CFG_start_phytec_pbaa03_1gib_1bank.pblb.imximg = $(board)/phytec-som-imx6/flash-header-phytec-pcaaxl3-1gib-1bank.imxcfg
-FILE_barebox-phytec-pbaa03-1gib-1bank.img = start_phytec_pbaa03_1gib_1bank.pblb.imximg
-image-$(CONFIG_MACH_PHYTEC_SOM_IMX6) += barebox-phytec-pbaa03-1gib-1bank.img
-
-pblb-$(CONFIG_MACH_PHYTEC_SOM_IMX6) += start_phytec_pbaa03_2gib
-CFG_start_phytec_pbaa03_2gib.pblb.imximg = $(board)/phytec-som-imx6/flash-header-phytec-pcaaxl3-2gib.imxcfg
-FILE_barebox-phytec-pbaa03-2gib.img = start_phytec_pbaa03_2gib.pblb.imximg
-image-$(CONFIG_MACH_PHYTEC_SOM_IMX6) += barebox-phytec-pbaa03-2gib.img
-
-pblb-$(CONFIG_MACH_PHYTEC_SOM_IMX6) += start_phytec_phycore_imx6q_som_nand_1gib
-CFG_start_phytec_phycore_imx6q_som_nand_1gib.pblb.imximg = $(board)/phytec-som-imx6/flash-header-phytec-pcm058-1gib.imxcfg
-FILE_barebox-phytec-phycore-imx6q-som-nand-1gib.img = start_phytec_phycore_imx6q_som_nand_1gib.pblb.imximg
-image-$(CONFIG_MACH_PHYTEC_SOM_IMX6) += barebox-phytec-phycore-imx6q-som-nand-1gib.img
-
-pblb-$(CONFIG_MACH_PHYTEC_SOM_IMX6) += start_phytec_phycore_imx6qp_som_nand_1gib
-CFG_start_phytec_phycore_imx6qp_som_nand_1gib.pblb.imximg = $(board)/phytec-som-imx6/flash-header-phytec-pcm058qp-1gib.imxcfg
-FILE_barebox-phytec-phycore-imx6qp-som-nand-1gib.img = start_phytec_phycore_imx6qp_som_nand_1gib.pblb.imximg
-image-$(CONFIG_MACH_PHYTEC_SOM_IMX6) += barebox-phytec-phycore-imx6qp-som-nand-1gib.img
-
-pblb-$(CONFIG_MACH_PHYTEC_SOM_IMX6) += start_phytec_phycore_imx6q_som_emmc_1gib
-CFG_start_phytec_phycore_imx6q_som_emmc_1gib.pblb.imximg = $(board)/phytec-som-imx6/flash-header-phytec-pcm058-1gib.imxcfg
-FILE_barebox-phytec-phycore-imx6q-som-emmc-1gib.img = start_phytec_phycore_imx6q_som_emmc_1gib.pblb.imximg
-image-$(CONFIG_MACH_PHYTEC_SOM_IMX6) += barebox-phytec-phycore-imx6q-som-emmc-1gib.img
-
-pblb-$(CONFIG_MACH_PHYTEC_SOM_IMX6) += start_phytec_phycore_imx6q_som_emmc_2gib
-CFG_start_phytec_phycore_imx6q_som_emmc_2gib.pblb.imximg = $(board)/phytec-som-imx6/flash-header-phytec-pcm058-2gib.imxcfg
-FILE_barebox-phytec-phycore-imx6q-som-emmc-2gib.img = start_phytec_phycore_imx6q_som_emmc_2gib.pblb.imximg
-image-$(CONFIG_MACH_PHYTEC_SOM_IMX6) += barebox-phytec-phycore-imx6q-som-emmc-2gib.img
-
-pblb-$(CONFIG_MACH_PHYTEC_SOM_IMX6) += start_phytec_phycore_imx6dl_som_nand_256mb
-CFG_start_phytec_phycore_imx6dl_som_nand_256mb.pblb.imximg = $(board)/phytec-som-imx6/flash-header-phytec-pcm058dl-256mb.imxcfg
-FILE_barebox-phytec-phycore-imx6dl-som-nand-256mb.img = start_phytec_phycore_imx6dl_som_nand_256mb.pblb.imximg
-image-$(CONFIG_MACH_PHYTEC_SOM_IMX6) += barebox-phytec-phycore-imx6dl-som-nand-256mb.img
-
-pblb-$(CONFIG_MACH_PHYTEC_SOM_IMX6) += start_phytec_phycore_imx6dl_som_nand_1gib
-CFG_start_phytec_phycore_imx6dl_som_nand_1gib.pblb.imximg = $(board)/phytec-som-imx6/flash-header-phytec-pcm058dl-1gib-32bit.imxcfg
-FILE_barebox-phytec-phycore-imx6dl-som-nand-1gib.img = start_phytec_phycore_imx6dl_som_nand_1gib.pblb.imximg
-image-$(CONFIG_MACH_PHYTEC_SOM_IMX6) += barebox-phytec-phycore-imx6dl-som-nand-1gib.img
-
-pblb-$(CONFIG_MACH_PHYTEC_SOM_IMX6) += start_phytec_phycore_imx6dl_som_lc_nand_256mb
-CFG_start_phytec_phycore_imx6dl_som_lc_nand_256mb.pblb.imximg = $(board)/phytec-som-imx6/flash-header-phytec-pcm058dl-256mb.imxcfg
-FILE_barebox-phytec-phycore-imx6dl-som-lc-nand-256mb.img = start_phytec_phycore_imx6dl_som_lc_nand_256mb.pblb.imximg
-image-$(CONFIG_MACH_PHYTEC_SOM_IMX6) += barebox-phytec-phycore-imx6dl-som-lc-nand-256mb.img
-
-pblb-$(CONFIG_MACH_PHYTEC_SOM_IMX6) += start_phytec_phycore_imx6dl_som_emmc_1gib
-CFG_start_phytec_phycore_imx6dl_som_emmc_1gib.pblb.imximg = $(board)/phytec-som-imx6/flash-header-phytec-pcm058dl-1gib.imxcfg
-FILE_barebox-phytec-phycore-imx6dl-som-emmc-1gib.img = start_phytec_phycore_imx6dl_som_emmc_1gib.pblb.imximg
-image-$(CONFIG_MACH_PHYTEC_SOM_IMX6) += barebox-phytec-phycore-imx6dl-som-emmc-1gib.img
-
-pblb-$(CONFIG_MACH_PHYTEC_SOM_IMX6) += start_phytec_phycore_imx6dl_som_lc_emmc_1gib
-CFG_start_phytec_phycore_imx6dl_som_lc_emmc_1gib.pblb.imximg = $(board)/phytec-som-imx6/flash-header-phytec-pcm058dl-1gib.imxcfg
-FILE_barebox-phytec-phycore-imx6dl-som-lc-emmc-1gib.img = start_phytec_phycore_imx6dl_som_lc_emmc_1gib.pblb.imximg
-image-$(CONFIG_MACH_PHYTEC_SOM_IMX6) += barebox-phytec-phycore-imx6dl-som-lc-emmc-1gib.img
-
-pblb-$(CONFIG_MACH_KONTRON_SAMX6I) += start_imx6q_samx6i
-CFG_start_imx6q_samx6i.pblb.imximg = $(board)/kontron-samx6i/flash-header-samx6i-quad.imxcfg
-FILE_barebox-imx6q-samx6i.img = start_imx6q_samx6i.pblb.imximg
-image-$(CONFIG_MACH_KONTRON_SAMX6I) += barebox-imx6q-samx6i.img
-
-pblb-$(CONFIG_MACH_KONTRON_SAMX6I) += start_imx6dl_samx6i
-CFG_start_imx6dl_samx6i.pblb.imximg = $(board)/kontron-samx6i/flash-header-samx6i-duallite.imxcfg
-FILE_barebox-imx6dl-samx6i.img = start_imx6dl_samx6i.pblb.imximg
-image-$(CONFIG_MACH_KONTRON_SAMX6I) += barebox-imx6dl-samx6i.img
-
-pblb-$(CONFIG_MACH_GW_VENTANA) += start_imx6q_gw54xx_1gx64
-CFG_start_imx6q_gw54xx_1gx64.pblb.imximg = $(board)/gateworks-ventana/flash-header-ventana-quad-1gx64.imxcfg
-FILE_barebox-gateworks-imx6q-ventana-1gx64.img = start_imx6q_gw54xx_1gx64.pblb.imximg
-image-$(CONFIG_MACH_GW_VENTANA) += barebox-gateworks-imx6q-ventana-1gx64.img
-
-pblb-$(CONFIG_MACH_ELTEC_HIPERCAM) += start_imx6dl_eltec_hipercam
-CFG_start_imx6dl_eltec_hipercam.pblb.imximg = $(board)/eltec-hipercam/flash-header-eltec-hipercam.imxcfg
-FILE_barebox-eltec-hipercam.img = start_imx6dl_eltec_hipercam.pblb.imximg
-image-$(CONFIG_MACH_ELTEC_HIPERCAM) += barebox-eltec-hipercam.img
-
-pblb-$(CONFIG_MACH_ADVANTECH_ROM_742X) += start_advantech_imx6dl_rom_7421
-CFG_start_advantech_imx6dl_rom_7421.pblb.imximg = $(board)/advantech-mx6/flash-header-advantech-rom-7421.imxcfg
-FILE_barebox-advantech-imx6dl-rom-7421.img = start_advantech_imx6dl_rom_7421.pblb.imximg
-image-$(CONFIG_MACH_ADVANTECH_ROM_742X) += barebox-advantech-imx6dl-rom-7421.img
-
-pblb-$(CONFIG_MACH_ZII_RDU2) += start_imx6_zii_rdu2
-CFG_start_imx6_zii_rdu2.pblb.imximg = $(board)/zii-imx6q-rdu2/flash-header-rdu2.imxcfg
-FILE_barebox-zii-imx6-rdu2.img = start_imx6_zii_rdu2.pblb.imximg
-image-$(CONFIG_MACH_ZII_RDU2) += barebox-zii-imx6-rdu2.img
+$(call build_imx_habv4img, CONFIG_MACH_REALQ7, start_imx6_realq7, datamodul-edm-qmx6/flash-header, datamodul-edm-qmx6)
+
+$(call build_imx_habv4img, CONFIG_MACH_GUF_SANTARO, start_imx6q_guf_santaro, guf-santaro/flash-header, guf-santaro)
+
+$(call build_imx_habv4img, CONFIG_MACH_GK802, start_imx6_gk802, gk802/flash-header, gk802)
+
+$(call build_imx_habv4img, CONFIG_MACH_TQMA6X, start_imx6dl_mba6x, tqma6x/flash-header-tqma6dl, tq-tqma6s-mba6x)
+
+$(call build_imx_habv4img, CONFIG_MACH_TQMA6X, start_imx6q_mba6x, tqma6x/flash-header-tqma6q, tq-tqma6q-mba6x)
+
+$(call build_imx_habv4img, CONFIG_MACH_PHYTEC_SOM_IMX6, start_phytec_pbab01_4gib, phytec-som-imx6/flash-header-phytec-pfla02-4gib, phytec-pbab01-4gib)
+
+$(call build_imx_habv4img, CONFIG_MACH_PHYTEC_SOM_IMX6, start_phytec_pbab01_2gib, phytec-som-imx6/flash-header-phytec-pfla02-2gib, phytec-pbab01-2gib)
+
+$(call build_imx_habv4img, CONFIG_MACH_PHYTEC_SOM_IMX6, start_phytec_pbab01_1gib, phytec-som-imx6/flash-header-phytec-pfla02-1gib, phytec-pbab01-1gib)
+
+$(call build_imx_habv4img, CONFIG_MACH_PHYTEC_SOM_IMX6, start_phytec_pbab01_1gib_1bank, phytec-som-imx6/flash-header-phytec-pfla02-1gib-1bank, phytec-pbab01-1gib-1bank)
+
+$(call build_imx_habv4img, CONFIG_MACH_PHYTEC_SOM_IMX6, start_phytec_pbab01_512mb_1bank, phytec-som-imx6/flash-header-phytec-pfla02-512mb-1bank, phytec-pbab01-512mb-1bank)
+
+$(call build_imx_habv4img, CONFIG_MACH_PHYTEC_SOM_IMX6, start_phytec_pbab01dl_1gib, phytec-som-imx6/flash-header-phytec-pfla02dl-1gib, phytec-pbab01dl-1gib)
+
+$(call build_imx_habv4img, CONFIG_MACH_PHYTEC_SOM_IMX6, start_phytec_pbab01dl_1gib_1bank, phytec-som-imx6/flash-header-phytec-pfla02dl-1gib-1bank, phytec-pbab01dl-1gib-1bank)
+
+$(call build_imx_habv4img, CONFIG_MACH_PHYTEC_SOM_IMX6, start_phytec_pbab01s_512mb_1bank, phytec-som-imx6/flash-header-phytec-pfla02s-512mb-1bank, phytec-pbab01s-512mb-1bank)
+
+$(call build_imx_habv4img, CONFIG_MACH_PHYTEC_SOM_IMX6, start_phytec_pbab01s_256mb_1bank, phytec-som-imx6/flash-header-phytec-pfla02s-256mb-1bank, phytec-pbab01s-256mb-1bank)
+
+$(call build_imx_habv4img, CONFIG_MACH_PHYTEC_SOM_IMX6, start_phytec_pbab01s_128mb_1bank, phytec-som-imx6/flash-header-phytec-pfla02s-128mb-1bank, phytec-pbab01s-128mb-1bank)
+
+$(call build_imx_habv4img, CONFIG_MACH_PHYTEC_SOM_IMX6, start_phytec_phyboard_alcor_1gib, phytec-som-imx6/flash-header-phytec-pfla02-1gib, phytec-phyboard-alcor-1gib)
+
+$(call build_imx_habv4img, CONFIG_MACH_PHYTEC_SOM_IMX6, start_phytec_phyboard_subra_512mb_1bank, phytec-som-imx6/flash-header-phytec-pfla02s-512mb-1bank, phytec-phyboard-subra-512mb-1bank)
+
+$(call build_imx_habv4img, CONFIG_MACH_PHYTEC_SOM_IMX6, start_phytec_phyboard_subra_1gib_1bank, phytec-som-imx6/flash-header-phytec-pfla02-1gib-1bank, phytec-phyboard-subra-1gib-1bank)
+
+$(call build_imx_habv4img, CONFIG_MACH_DFI_FS700_M60, start_imx6dl_dfi_fs700_m60_6s, dfi-fs700-m60/flash-header-fs700-m60-6s, dfi-fs700-m60-6s)
+
+$(call build_imx_habv4img, CONFIG_MACH_DFI_FS700_M60, start_imx6q_dfi_fs700_m60_6q_micron, dfi-fs700-m60/flash-header-fs700-m60-6q-micron, dfi-fs700-m60-6q-micron)
+
+$(call build_imx_habv4img, CONFIG_MACH_DFI_FS700_M60, start_imx6q_dfi_fs700_m60_6q_nanya, dfi-fs700-m60/flash-header-fs700-m60-6q-nanya, dfi-fs700-m60-6q-nanya)
+
+$(call build_imx_habv4img, CONFIG_MACH_SABRELITE, start_imx6q_sabrelite, freescale-mx6-sabrelite/flash-header-mx6-sabrelite, freescale-imx6q-sabrelite)
+
+$(call build_imx_habv4img, CONFIG_MACH_SABRELITE, start_imx6dl_sabrelite, freescale-mx6-sabrelite/flash-header-mx6-sabrelite, freescale-imx6dl-sabrelite)
+
+$(call build_imx_habv4img, CONFIG_MACH_SABRESD, start_imx6q_sabresd, freescale-mx6-sabresd/flash-header-mx6-sabresd, freescale-imx6q-sabresd)
+
+$(call build_imx_habv4img, CONFIG_MACH_UDOO_NEO, start_imx6sx_udoo_neo, udoo-neo/flash-header-mx6sx-udoo-neo_full, udoo-neo)
+
+$(call build_imx_habv4img, CONFIG_MACH_FREESCALE_IMX6SX_SABRESDB, start_imx6sx_sabresdb, freescale-mx6sx-sabresdb/flash-header-mx6sx-sabresdb, freescale-imx6sx-sabresdb)
+
+$(call build_imx_habv4img, CONFIG_MACH_TECHNEXION_WANDBOARD, start_imx6_wandboard, technexion-wandboard/flash-header-technexion-wandboard, imx6-wandboard)
+
+$(call build_imx_habv4img, CONFIG_MACH_SOLIDRUN_MICROSOM, start_hummingboard_microsom_i1, solidrun-microsom/flash-header-microsom-i1, solidrun-hummingboard-microsom-i1)
+
+$(call build_imx_habv4img, CONFIG_MACH_SOLIDRUN_MICROSOM, start_hummingboard_microsom_i2, solidrun-microsom/flash-header-microsom-i2, solidrun-hummingboard-microsom-i2)
+
+$(call build_imx_habv4img, CONFIG_MACH_SOLIDRUN_MICROSOM, start_hummingboard_microsom_i2ex, solidrun-microsom/flash-header-microsom-i2eX, solidrun-hummingboard-microsom-i2eX)
+
+$(call build_imx_habv4img, CONFIG_MACH_SOLIDRUN_MICROSOM, start_hummingboard_microsom_i4, solidrun-microsom/flash-header-microsom-i4, solidrun-hummingboard-microsom-i4)
+
+$(call build_imx_habv4img, CONFIG_MACH_SOLIDRUN_MICROSOM, start_hummingboard2_microsom_i1, solidrun-microsom/flash-header-microsom-i1, solidrun-hummingboard2-microsom-i1)
+
+$(call build_imx_habv4img, CONFIG_MACH_SOLIDRUN_MICROSOM, start_hummingboard2_microsom_i2, solidrun-microsom/flash-header-microsom-i2, solidrun-hummingboard2-microsom-i2)
+
+$(call build_imx_habv4img, CONFIG_MACH_SOLIDRUN_MICROSOM, start_hummingboard2_microsom_i2ex, solidrun-microsom/flash-header-microsom-i2eX, solidrun-hummingboard2-microsom-i2eX)
+
+$(call build_imx_habv4img, CONFIG_MACH_SOLIDRUN_MICROSOM, start_hummingboard2_microsom_i4, solidrun-microsom/flash-header-microsom-i4, solidrun-hummingboard2-microsom-i4)
+
+$(call build_imx_habv4img, CONFIG_MACH_SOLIDRUN_MICROSOM, start_h100_microsom_i2ex, solidrun-microsom/flash-header-microsom-i2eX, auvidea-h100-microsom-i2eX)
+
+$(call build_imx_habv4img, CONFIG_MACH_NITROGEN6, start_imx6q_nitrogen6x_1g, boundarydevices-nitrogen6/flash-header-nitrogen6q-1g, boundarydevices-imx6q-nitrogen6x-1g)
+
+$(call build_imx_habv4img, CONFIG_MACH_NITROGEN6, start_imx6q_nitrogen6x_2g, boundarydevices-nitrogen6/flash-header-nitrogen6q-2g, boundarydevices-imx6q-nitrogen6x-2g)
+
+$(call build_imx_habv4img, CONFIG_MACH_NITROGEN6, start_imx6dl_nitrogen6x_1g, boundarydevices-nitrogen6/flash-header-nitrogen6dl-1g, boundarydevices-imx6dl-nitrogen6x-1g)
+
+$(call build_imx_habv4img, CONFIG_MACH_NITROGEN6, start_imx6dl_nitrogen6x_2g, boundarydevices-nitrogen6/flash-header-nitrogen6dl-2g, boundarydevices-imx6dl-nitrogen6x-2g)
+
+$(call build_imx_habv4img, CONFIG_MACH_NITROGEN6, start_imx6qp_nitrogen6_max, boundarydevices-nitrogen6/flash-header-nitrogen6qp-max, boundarydevices-imx6qp-nitrogen6_max)
+
+$(call build_imx_habv4img, CONFIG_MACH_TX6X, start_imx6dl_tx6x_512m, karo-tx6x/flash-header-tx6dl-512m, karo-imx6dl-tx6x-512m)
+
+$(call build_imx_habv4img, CONFIG_MACH_TX6X, start_imx6dl_tx6x_1g, karo-tx6x/flash-header-tx6dl-1g, karo-imx6dl-tx6x-1g)
+
+$(call build_imx_habv4img, CONFIG_MACH_TX6X, start_imx6q_tx6x_1g, karo-tx6x/flash-header-tx6q-1g, karo-imx6q-tx6x-1g)
+
+$(call build_imx_habv4img, CONFIG_MACH_TX6X, start_imx6q_tx6x_2g, karo-tx6x/flash-header-tx6qp-2g, karo-imx6qp-tx6x-2g)
+
+$(call build_imx_habv4img, CONFIG_MACH_UDOO, start_imx6_udoo, udoo/flash-header-mx6-udoo, udoo-imx6q)
+
+$(call build_imx_habv4img, CONFIG_MACH_CM_FX6, start_imx6_cm_fx6, cm-fx6/flash-header-mx6-cm-fx6, cm-fx6)
+
+$(call build_imx_habv4img, CONFIG_MACH_CM_FX6, start_imx6_utilite, cm-fx6/flash-header-mx6-cm-fx6, utilite)
+
+$(call build_imx_habv4img, CONFIG_MACH_VARISCITE_MX6, start_variscite_custom, variscite-mx6/flash-header-variscite, variscite-custom)
+
+$(call build_imx_habv4img, CONFIG_MACH_EMBEDSKY_E9, start_imx6q_embedsky_e9, embedsky-e9/flash-header-e9, embedsky-imx6q-e9)
+
+$(call build_imx_habv4img, CONFIG_MACH_EMBEST_MARSBOARD, start_imx6q_marsboard, embest-marsboard/flash-header-embest-marsboard, barebox-embest-imx6q-marsboard)
+
+$(call build_imx_habv4img, CONFIG_MACH_EMBEST_RIOTBOARD, start_imx6s_riotboard, embest-riotboard/flash-header-embest-riotboard, embest-imx6s-riotboard)
+
+$(call build_imx_habv4img, CONFIG_MACH_PHYTEC_SOM_IMX6, start_phytec_pbaa03_1gib, phytec-som-imx6/flash-header-phytec-pcaaxl3-1gib, phytec-pbaa03-1gib)
+
+$(call build_imx_habv4img, CONFIG_MACH_PHYTEC_SOM_IMX6, start_phytec_pbaa03_1gib_1bank, phytec-som-imx6/flash-header-phytec-pcaaxl3-1gib-1bank, phytec-pbaa03-1gib-1bank)
+
+$(call build_imx_habv4img, CONFIG_MACH_PHYTEC_SOM_IMX6, start_phytec_pbaa03_2gib, phytec-som-imx6/flash-header-phytec-pcaaxl3-2gib, phytec-pbaa03-2gib)
+
+$(call build_imx_habv4img, CONFIG_MACH_PHYTEC_SOM_IMX6, start_phytec_phycore_imx6q_som_nand_1gib, phytec-som-imx6/flash-header-phytec-pcm058-1gib, phytec-phycore-imx6q-som-nand-1gib)
+
+$(call build_imx_habv4img, CONFIG_MACH_PHYTEC_SOM_IMX6, start_phytec_phycore_imx6qp_som_nand_1gib, phytec-som-imx6/flash-header-phytec-pcm058qp-1gib, phytec-phycore-imx6qp-som-nand-1gib)
+
+$(call build_imx_habv4img, CONFIG_MACH_PHYTEC_SOM_IMX6, start_phytec_phycore_imx6q_som_emmc_1gib, phytec-som-imx6/flash-header-phytec-pcm058-1gib, phytec-phycore-imx6q-som-emmc-1gib)
+
+$(call build_imx_habv4img, CONFIG_MACH_PHYTEC_SOM_IMX6, start_phytec_phycore_imx6q_som_emmc_2gib, phytec-som-imx6/flash-header-phytec-pcm058-2gib, phytec-phycore-imx6q-som-emmc-2gib)
+
+$(call build_imx_habv4img, CONFIG_MACH_PHYTEC_SOM_IMX6, start_phytec_phycore_imx6dl_som_nand_256mb, phytec-som-imx6/flash-header-phytec-pcm058dl-256mb, phytec-phycore-imx6dl-som-nand-256mb)
+
+$(call build_imx_habv4img, CONFIG_MACH_PHYTEC_SOM_IMX6, start_phytec_phycore_imx6dl_som_nand_1gib, phytec-som-imx6/flash-header-phytec-pcm058dl-1gib-32bit, phytec-phycore-imx6dl-som-nand-1gib)
+
+$(call build_imx_habv4img, CONFIG_MACH_PHYTEC_SOM_IMX6, start_phytec_phycore_imx6dl_som_lc_nand_256mb, phytec-som-imx6/flash-header-phytec-pcm058dl-256mb, phytec-phycore-imx6dl-som-lc-nand-256mb)
+
+$(call build_imx_habv4img, CONFIG_MACH_PHYTEC_SOM_IMX6, start_phytec_phycore_imx6dl_som_emmc_1gib, phytec-som-imx6/flash-header-phytec-pcm058dl-1gib, phytec-phycore-imx6dl-som-emmc-1gib)
+
+$(call build_imx_habv4img, CONFIG_MACH_PHYTEC_SOM_IMX6, start_phytec_phycore_imx6dl_som_lc_emmc_1gib, phytec-som-imx6/flash-header-phytec-pcm058dl-1gib, phytec-phycore-imx6dl-som-lc-emmc-1gib)
+
+$(call build_imx_habv4img, CONFIG_MACH_KONTRON_SAMX6I, start_imx6q_samx6i, kontron-samx6i/flash-header-samx6i-quad, imx6q-samx6i)
+
+$(call build_imx_habv4img, CONFIG_MACH_KONTRON_SAMX6I, start_imx6dl_samx6i, kontron-samx6i/flash-header-samx6i-duallite, imx6dl-samx6i)
+
+$(call build_imx_habv4img, CONFIG_MACH_GW_VENTANA, start_imx6q_gw54xx_1gx64, gateworks-ventana/flash-header-ventana-quad-1gx64, gateworks-imx6q-ventana-1gx64)
+
+$(call build_imx_habv4img, CONFIG_MACH_ELTEC_HIPERCAM, start_imx6dl_eltec_hipercam, eltec-hipercam/flash-header-eltec-hipercam, eltec-hipercam)
+
+$(call build_imx_habv4img, CONFIG_MACH_ADVANTECH_ROM_742X, start_advantech_imx6dl_rom_7421, advantech-mx6/flash-header-advantech-rom-7421, advantech-imx6dl-rom-7421)
+
+$(call build_imx_habv4img, CONFIG_MACH_ZII_RDU2, start_imx6_zii_rdu2, zii-imx6q-rdu2/flash-header-rdu2, zii-imx6-rdu2)
# ----------------------- i.MX6ul / i.MX6ull based boards --------------
-pblb-$(CONFIG_MACH_GRINN_LITEBOARD) += start_imx6ul_liteboard_256mb
-CFG_start_imx6ul_liteboard_256mb.pblb.imximg = $(board)/grinn-liteboard/flash-header-liteboard-256mb.imxcfg
-FILE_barebox-grinn-liteboard-256mb.img = start_imx6ul_liteboard_256mb.pblb.imximg
-image-$(CONFIG_MACH_GRINN_LITEBOARD) += barebox-grinn-liteboard-256mb.img
-
-pblb-$(CONFIG_MACH_GRINN_LITEBOARD) += start_imx6ul_liteboard_512mb
-CFG_start_imx6ul_liteboard_512mb.pblb.imximg = $(board)/grinn-liteboard/flash-header-liteboard-512mb.imxcfg
-FILE_barebox-grinn-liteboard-512mb.img = start_imx6ul_liteboard_512mb.pblb.imximg
-image-$(CONFIG_MACH_GRINN_LITEBOARD) += barebox-grinn-liteboard-512mb.img
-
-pblb-$(CONFIG_MACH_NXP_IMX6ULL_EVK) += start_nxp_imx6ull_evk
-CFG_start_nxp_imx6ull_evk.pblb.imximg = $(board)/nxp-imx6ull-evk/flash-header-nxp-imx6ull-evk.imxcfg
-FILE_barebox-nxp-imx6ull-evk.img = start_nxp_imx6ull_evk.pblb.imximg
-image-$(CONFIG_MACH_NXP_IMX6ULL_EVK) += barebox-nxp-imx6ull-evk.img
-
-pblb-$(CONFIG_MACH_PHYTEC_SOM_IMX6) += start_phytec_phycore_imx6ul_som_nand_512mb
-CFG_start_phytec_phycore_imx6ul_som_nand_512mb.pblb.imximg = $(board)/phytec-som-imx6/flash-header-phytec-pcl063-512mb.imxcfg
-FILE_barebox-phytec-phycore-imx6ul-nand-512mb.img = start_phytec_phycore_imx6ul_som_nand_512mb.pblb.imximg
-image-$(CONFIG_MACH_PHYTEC_SOM_IMX6) += barebox-phytec-phycore-imx6ul-nand-512mb.img
-
-pblb-$(CONFIG_MACH_PHYTEC_SOM_IMX6) += start_phytec_phycore_imx6ull_som_lc_nand_256mb
-CFG_start_phytec_phycore_imx6ull_som_lc_nand_256mb.pblb.imximg = $(board)/phytec-som-imx6/flash-header-phytec-pcl063-256mb.imxcfg
-FILE_barebox-phytec-phycore-imx6ull-lc-nand-256mb.img = start_phytec_phycore_imx6ull_som_lc_nand_256mb.pblb.imximg
-image-$(CONFIG_MACH_PHYTEC_SOM_IMX6) += barebox-phytec-phycore-imx6ull-lc-nand-256mb.img
-
-pblb-$(CONFIG_MACH_PHYTEC_SOM_IMX6) += start_phytec_phycore_imx6ull_som_nand_512mb
-CFG_start_phytec_phycore_imx6ull_som_nand_512mb.pblb.imximg = $(board)/phytec-som-imx6/flash-header-phytec-pcl063-512mb.imxcfg
-FILE_barebox-phytec-phycore-imx6ull-nand-512mb.img = start_phytec_phycore_imx6ull_som_nand_512mb.pblb.imximg
-image-$(CONFIG_MACH_PHYTEC_SOM_IMX6) += barebox-phytec-phycore-imx6ull-nand-512mb.img
-
-pblb-$(CONFIG_MACH_PHYTEC_SOM_IMX6) += start_phytec_phycore_imx6ull_som_emmc_512mb
-CFG_start_phytec_phycore_imx6ull_som_emmc_512mb.pblb.imximg = $(board)/phytec-som-imx6/flash-header-phytec-pcl063-512mb.imxcfg
-FILE_barebox-phytec-phycore-imx6ull-emmc-512mb.img = start_phytec_phycore_imx6ull_som_emmc_512mb.pblb.imximg
-image-$(CONFIG_MACH_PHYTEC_SOM_IMX6) += barebox-phytec-phycore-imx6ull-emmc-512mb.img
-
-pblb-$(CONFIG_MACH_TECHNEXION_PICO_HOBBIT) += start_imx6ul_pico_hobbit_256mb
-CFG_start_imx6ul_pico_hobbit_256mb.pblb.imximg = $(board)/technexion-pico-hobbit/flash-header-imx6ul-pico-hobbit-256.imxcfg
-FILE_barebox-imx6ul-pico-hobbit-256mb.img = start_imx6ul_pico_hobbit_256mb.pblb.imximg
-image-$(CONFIG_MACH_TECHNEXION_PICO_HOBBIT) += barebox-imx6ul-pico-hobbit-256mb.img
-
-pblb-$(CONFIG_MACH_TECHNEXION_PICO_HOBBIT) += start_imx6ul_pico_hobbit_512mb
-CFG_start_imx6ul_pico_hobbit_512mb.pblb.imximg = $(board)/technexion-pico-hobbit/flash-header-imx6ul-pico-hobbit-512.imxcfg
-FILE_barebox-imx6ul-pico-hobbit-512mb.img = start_imx6ul_pico_hobbit_512mb.pblb.imximg
-image-$(CONFIG_MACH_TECHNEXION_PICO_HOBBIT) += barebox-imx6ul-pico-hobbit-512mb.img
-
-pblb-$(CONFIG_MACH_DIGI_CCIMX6ULSBCPRO) += start_imx6ul_ccimx6ulsbcpro
-CFG_start_imx6ul_ccimx6ulsbcpro.pblb.imximg = $(board)/digi-ccimx6ulsom/flash-header-imx6ul-ccimx6ulsbcpro.imxcfg
-FILE_barebox-imx6ul-ccimx6ulsbcpro.img = start_imx6ul_ccimx6ulsbcpro.pblb.imximg
-image-$(CONFIG_MACH_DIGI_CCIMX6ULSBCPRO) += barebox-imx6ul-ccimx6ulsbcpro.img
+$(call build_imx_habv4img, CONFIG_MACH_GRINN_LITEBOARD, start_imx6ul_liteboard_256mb, grinn-liteboard/flash-header-liteboard-256mb, grinn-liteboard-256mb)
+
+$(call build_imx_habv4img, CONFIG_MACH_GRINN_LITEBOARD, start_imx6ul_liteboard_512mb, grinn-liteboard/flash-header-liteboard-512mb, grinn-liteboard-512mb)
+
+$(call build_imx_habv4img, CONFIG_MACH_NXP_IMX6ULL_EVK, start_nxp_imx6ull_evk, nxp-imx6ull-evk/flash-header-nxp-imx6ull-evk, nxp-imx6ull-evk)
+
+$(call build_imx_habv4img, CONFIG_MACH_PHYTEC_SOM_IMX6, start_phytec_phycore_imx6ul_som_nand_512mb, phytec-som-imx6/flash-header-phytec-pcl063-512mb, phytec-phycore-imx6ul-nand-512mb)
+
+$(call build_imx_habv4img, CONFIG_MACH_PHYTEC_SOM_IMX6, start_phytec_phycore_imx6ull_som_lc_nand_256mb, phytec-som-imx6/flash-header-phytec-pcl063-256mb, phytec-phycore-imx6ull-lc-nand-256mb)
+
+$(call build_imx_habv4img, CONFIG_MACH_PHYTEC_SOM_IMX6, start_phytec_phycore_imx6ull_som_nand_512mb, phytec-som-imx6/flash-header-phytec-pcl063-512mb, phytec-phycore-imx6ull-nand-512mb)
+
+$(call build_imx_habv4img, CONFIG_MACH_PHYTEC_SOM_IMX6, start_phytec_phycore_imx6ull_som_emmc_512mb, phytec-som-imx6/flash-header-phytec-pcl063-512mb, phytec-phycore-imx6ull-emmc-512mb)
+
+$(call build_imx_habv4img, CONFIG_MACH_TECHNEXION_PICO_HOBBIT, start_imx6ul_pico_hobbit_256mb, technexion-pico-hobbit/flash-header-imx6ul-pico-hobbit-256, imx6ul-pico-hobbit-256mb)
+
+$(call build_imx_habv4img, CONFIG_MACH_TECHNEXION_PICO_HOBBIT, start_imx6ul_pico_hobbit_512mb, technexion-pico-hobbit/flash-header-imx6ul-pico-hobbit-512, imx6ul-pico-hobbit-512mb)
+
+$(call build_imx_habv4img, CONFIG_MACH_DIGI_CCIMX6ULSBCPRO, start_imx6ul_ccimx6ulsbcpro, digi-ccimx6ulsom/flash-header-imx6ul-ccimx6ulsbcpro, imx6ul-ccimx6ulsbcpro)
# ----------------------- vf6xx based boards ---------------------------
pblb-$(CONFIG_MACH_VF610_TWR) += start_vf610_twr
diff --git a/include/acpi.h b/include/acpi.h
new file mode 100644
index 0000000000..2d5fd3086a
--- /dev/null
+++ b/include/acpi.h
@@ -0,0 +1,73 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 Ahmad Fatoum
+ */
+
+#ifndef __ACPI_H_
+#define __ACPI_H_
+
+#include <linux/types.h>
+#include <driver.h>
+
+typedef char acpi_sig_t[4];
+
+struct __packed acpi_rsdp { /* root system description pointer */
+ char signature[8];
+ u8 checksum;
+ u8 oem_id[6];
+ u8 revision;
+ u32 rsdt_addr;
+};
+
+struct __packed acpi2_rsdp { /* root system description */
+ struct acpi_rsdp acpi1;
+ u32 length;
+ u64 xsdt_addr;
+ u8 extended_checksum;
+ u8 reserved[3];
+};
+
+struct __packed acpi_sdt { /* system description table header */
+ acpi_sig_t signature;
+ u32 len;
+ u8 revision;
+ u8 checksum;
+ char oem_id[6];
+ char oem_table_id[8];
+ u32 oem_revision;
+ u32 creator_id;
+ u32 creator_revision;
+};
+
+struct __packed acpi_rsdt { /* system description table header */
+ struct acpi_sdt sdt;
+ struct acpi_sdt * __aligned(8) entries[];
+};
+
+struct acpi_driver {
+ struct driver_d driver;
+ acpi_sig_t signature;
+};
+
+extern struct bus_type acpi_bus;
+
+static inline struct acpi_driver *to_acpi_driver(struct driver_d *drv)
+{
+ return container_of(drv, struct acpi_driver, driver);
+}
+
+#define device_acpi_driver(drv) \
+ register_driver_macro(device, acpi, drv)
+
+static inline int acpi_driver_register(struct acpi_driver *acpidrv)
+{
+ acpidrv->driver.bus = &acpi_bus;
+ return register_driver(&acpidrv->driver);
+}
+
+static inline int acpi_sigcmp(const acpi_sig_t sig_a, const acpi_sig_t sig_b)
+{
+ return memcmp(sig_a, sig_b, sizeof(acpi_sig_t));
+}
+
+#endif
diff --git a/include/driver.h b/include/driver.h
index 300603fa32..ad59ce90c3 100644
--- a/include/driver.h
+++ b/include/driver.h
@@ -155,12 +155,12 @@ int unregister_device(struct device_d *);
/* Iterate over a devices children
*/
#define device_for_each_child(dev, child) \
- list_for_each_entry(child, &dev->children, sibling)
+ list_for_each_entry(child, &(dev)->children, sibling)
/* Iterate over a devices children - Safe against removal version
*/
#define device_for_each_child_safe(dev, tmpdev, child) \
- list_for_each_entry_safe(child, tmpdev, &dev->children, sibling)
+ list_for_each_entry_safe(child, tmpdev, &(dev)->children, sibling)
/* Iterate through the devices of a given type. if last is NULL, the
* first device of this type is returned. Put this pointer in as
diff --git a/include/efi.h b/include/efi.h
index 166803a58f..43c0593951 100644
--- a/include/efi.h
+++ b/include/efi.h
@@ -91,21 +91,23 @@ typedef struct {
*/
/* Memory types: */
-#define EFI_RESERVED_TYPE 0
-#define EFI_LOADER_CODE 1
-#define EFI_LOADER_DATA 2
-#define EFI_BOOT_SERVICES_CODE 3
-#define EFI_BOOT_SERVICES_DATA 4
-#define EFI_RUNTIME_SERVICES_CODE 5
-#define EFI_RUNTIME_SERVICES_DATA 6
-#define EFI_CONVENTIONAL_MEMORY 7
-#define EFI_UNUSABLE_MEMORY 8
-#define EFI_ACPI_RECLAIM_MEMORY 9
-#define EFI_ACPI_MEMORY_NVS 10
-#define EFI_MEMORY_MAPPED_IO 11
-#define EFI_MEMORY_MAPPED_IO_PORT_SPACE 12
-#define EFI_PAL_CODE 13
-#define EFI_MAX_MEMORY_TYPE 14
+enum efi_memory_type {
+ EFI_RESERVED_TYPE,
+ EFI_LOADER_CODE,
+ EFI_LOADER_DATA,
+ EFI_BOOT_SERVICES_CODE,
+ EFI_BOOT_SERVICES_DATA,
+ EFI_RUNTIME_SERVICES_CODE,
+ EFI_RUNTIME_SERVICES_DATA,
+ EFI_CONVENTIONAL_MEMORY,
+ EFI_UNUSABLE_MEMORY,
+ EFI_ACPI_RECLAIM_MEMORY,
+ EFI_ACPI_MEMORY_NVS,
+ EFI_MEMORY_MAPPED_IO,
+ EFI_MEMORY_MAPPED_IO_PORT_SPACE,
+ EFI_PAL_CODE,
+ EFI_MAX_MEMORY_TYPE
+};
/* Attribute values: */
#define EFI_MEMORY_UC ((u64)0x0000000000000001ULL) /* uncached */
@@ -124,10 +126,12 @@ typedef struct {
/*
* Allocation types for calls to boottime->allocate_pages.
*/
-#define EFI_ALLOCATE_ANY_PAGES 0
-#define EFI_ALLOCATE_MAX_ADDRESS 1
-#define EFI_ALLOCATE_ADDRESS 2
-#define EFI_MAX_ALLOCATE_TYPE 3
+enum efi_allocate_type {
+ EFI_ALLOCATE_ANY_PAGES,
+ EFI_ALLOCATE_MAX_ADDRESS,
+ EFI_ALLOCATE_ADDRESS,
+ EFI_MAX_ALLOCATE_TYPE
+};
typedef int (*efi_freemem_callback_t) (u64 start, u64 end, void *arg);
diff --git a/include/efi/efi-device.h b/include/efi/efi-device.h
index 5eaf1f260d..5ec59a8a2d 100644
--- a/include/efi/efi-device.h
+++ b/include/efi/efi-device.h
@@ -45,4 +45,16 @@ int efi_connect_all(void);
void efi_register_devices(void);
struct efi_device *efi_get_bootsource(void);
+static inline bool efi_device_has_guid(struct efi_device *efidev, efi_guid_t guid)
+{
+ int i;
+
+ for (i = 0; i < efidev->num_guids; i++) {
+ if (!efi_guidcmp(efidev->guids[i], guid))
+ return true;
+ }
+
+ return false;
+}
+
#endif /* __EFI_EFI_DEVICE_H */
diff --git a/include/gpio.h b/include/gpio.h
index 4d5f2c25c7..0c0c0337e0 100644
--- a/include/gpio.h
+++ b/include/gpio.h
@@ -114,6 +114,11 @@ static inline int gpio_request(unsigned gpio, const char *label)
return 0;
}
+static inline int gpio_find_by_name(const char *name)
+{
+ return -ENOSYS;
+}
+
static inline int gpio_find_by_label(const char *label)
{
return -ENOSYS;
@@ -141,6 +146,7 @@ static inline void gpio_free_array(const struct gpio *array, size_t num)
}
#else
int gpio_request(unsigned gpio, const char *label);
+int gpio_find_by_name(const char *name);
int gpio_find_by_label(const char *label);
void gpio_free(unsigned gpio);
int gpio_request_one(unsigned gpio, unsigned long flags, const char *label);
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index d8125214a0..1fbb3dc5c1 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -15,6 +15,7 @@ struct pci_device_id {
__u32 vendor, device; /* Vendor and device ID or PCI_ANY_ID*/
__u32 subvendor, subdevice; /* Subsystem ID's or PCI_ANY_ID */
__u32 class, class_mask; /* (class,subclass,prog-if) triplet */
+ unsigned long driver_data; /* Data private to the driver */
};
#define SPI_NAME_SIZE 32
diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
index 105f381ada..1c6f442866 100644
--- a/include/linux/mtd/spi-nor.h
+++ b/include/linux/mtd/spi-nor.h
@@ -116,7 +116,7 @@
#define FSR_READY BIT(7)
/* Configuration Register bits. */
-#define CR_QUAD_EN_SPAN BIT(2) /* Spansion Quad I/O */
+#define CR_QUAD_EN_SPAN BIT(1) /* Spansion Quad I/O */
/* Supported SPI protocols */
#define SNOR_PROTO_INST_MASK GENMASK(23, 16)
diff --git a/include/linux/pci.h b/include/linux/pci.h
index d92d70b6bd..c742570e36 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -115,6 +115,17 @@ struct pci_dev {
};
#define to_pci_dev(d) container_of(d, struct pci_dev, dev)
+#define pci_resource_start(dev, bar) ((dev)->resource[(bar)].start)
+#define pci_resource_end(dev, bar) ((dev)->resource[(bar)].end)
+#define pci_resource_flags(dev, bar) ((dev)->resource[(bar)].flags)
+#define pci_resource_len(dev,bar) \
+ ((pci_resource_start((dev), (bar)) == 0 && \
+ pci_resource_end((dev), (bar)) == \
+ pci_resource_start((dev), (bar))) ? 0 : \
+ \
+ (pci_resource_end((dev), (bar)) - \
+ pci_resource_start((dev), (bar)) + 1))
+
enum {
PCI_BUS_RESOURCE_IO = 0,
PCI_BUS_RESOURCE_MEM = 1,
@@ -211,6 +222,20 @@ struct pci_driver {
.subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID
/**
+ * PCI_DEVICE_SUB - macro used to describe a specific PCI device with subsystem
+ * @vend: the 16 bit PCI Vendor ID
+ * @dev: the 16 bit PCI Device ID
+ * @subvend: the 16 bit PCI Subvendor ID
+ * @subdev: the 16 bit PCI Subdevice ID
+ *
+ * This macro is used to create a struct pci_device_id that matches a
+ * specific device with subsystem information.
+ */
+#define PCI_DEVICE_SUB(vend, dev, subvend, subdev) \
+ .vendor = (vend), .device = (dev), \
+ .subvendor = (subvend), .subdevice = (subdev)
+
+/**
* PCI_DEVICE_CLASS - macro used to describe a specific pci device class
* @dev_class: the class, subclass, prog-if triple for this device
* @dev_class_mask: the class mask for this device
@@ -350,4 +375,13 @@ enum pci_fixup_pass {
void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev);
+#ifdef CONFIG_PCI
+const struct pci_device_id *pci_match_id(const struct pci_device_id *ids,
+ struct pci_dev *dev);
+#else
+static inline const struct pci_device_id *pci_match_id(const struct pci_device_id *ids,
+ struct pci_dev *dev)
+{ return NULL; }
+#endif
+
#endif /* LINUX_PCI_H */
diff --git a/include/of.h b/include/of.h
index 98ddf795cb..f63a3efe13 100644
--- a/include/of.h
+++ b/include/of.h
@@ -197,14 +197,12 @@ extern int of_property_read_u64(const struct device_node *np,
extern int of_property_read_string(struct device_node *np,
const char *propname,
const char **out_string);
-extern int of_property_read_string_index(struct device_node *np,
- const char *propname,
- int index, const char **output);
extern int of_property_match_string(struct device_node *np,
const char *propname,
const char *string);
-extern int of_property_count_strings(struct device_node *np,
- const char *propname);
+extern int of_property_read_string_helper(const struct device_node *np,
+ const char *propname,
+ const char **out_strs, size_t sz, int index);
extern const __be32 *of_prop_next_u32(struct property *prop,
const __be32 *cur, u32 *pu);
@@ -444,20 +442,15 @@ static inline int of_property_read_string(struct device_node *np,
return -ENOSYS;
}
-static inline int of_property_read_string_index(struct device_node *np,
- const char *propname, int index, const char **output)
-{
- return -ENOSYS;
-}
-
static inline int of_property_match_string(struct device_node *np,
const char *propname, const char *string)
{
return -ENOSYS;
}
-static inline int of_property_count_strings(struct device_node *np,
- const char *propname)
+static inline int of_property_read_string_helper(const struct device_node *np,
+ const char *propname,
+ const char **out_strs, size_t sz, int index)
{
return -ENOSYS;
}
@@ -753,6 +746,70 @@ static inline struct device_node *of_find_matching_node(
child = of_get_next_available_child(parent, child))
/**
+ * of_property_read_string_array() - Read an array of strings from a multiple
+ * strings property.
+ * @np: device node from which the property value is to be read.
+ * @propname: name of the property to be searched.
+ * @out_strs: output array of string pointers.
+ * @sz: number of array elements to read.
+ *
+ * Search for a property in a device tree node and retrieve a list of
+ * terminated string values (pointer to data, not a copy) in that property.
+ *
+ * If @out_strs is NULL, the number of strings in the property is returned.
+ */
+static inline int of_property_read_string_array(const struct device_node *np,
+ const char *propname, const char **out_strs,
+ size_t sz)
+{
+ return of_property_read_string_helper(np, propname, out_strs, sz, 0);
+}
+
+/**
+ * of_property_count_strings() - Find and return the number of strings from a
+ * multiple strings property.
+ * @np: device node from which the property value is to be read.
+ * @propname: name of the property to be searched.
+ *
+ * Search for a property in a device tree node and retrieve the number of null
+ * terminated string contain in it. Returns the number of strings on
+ * success, -EINVAL if the property does not exist, -ENODATA if property
+ * does not have a value, and -EILSEQ if the string is not null-terminated
+ * within the length of the property data.
+ */
+static inline int of_property_count_strings(const struct device_node *np,
+ const char *propname)
+{
+ return of_property_read_string_helper(np, propname, NULL, 0, 0);
+}
+
+/**
+ * of_property_read_string_index() - Find and read a string from a multiple
+ * strings property.
+ * @np: device node from which the property value is to be read.
+ * @propname: name of the property to be searched.
+ * @index: index of the string in the list of strings
+ * @out_string: pointer to null terminated return string, modified only if
+ * return value is 0.
+ *
+ * Search for a property in a device tree node and retrieve a null
+ * terminated string value (pointer to data, not a copy) in the list of strings
+ * contained in that property.
+ * Returns 0 on success, -EINVAL if the property does not exist, -ENODATA if
+ * property does not have a value, and -EILSEQ if the string is not
+ * null-terminated within the length of the property data.
+ *
+ * The out_string pointer is modified only if a valid string can be decoded.
+ */
+static inline int of_property_read_string_index(const struct device_node *np,
+ const char *propname,
+ int index, const char **output)
+{
+ int rc = of_property_read_string_helper(np, propname, output, 1, index);
+ return rc < 0 ? rc : 0;
+}
+
+/**
* of_property_read_bool - Findfrom a property
* @np: device node from which the property value is to be read.
* @propname: name of the property to be searched.
diff --git a/include/soc/fsl/fsl_fman.h b/include/soc/fsl/fsl_fman.h
index 96d61298ef..fd69fded38 100644
--- a/include/soc/fsl/fsl_fman.h
+++ b/include/soc/fsl/fsl_fman.h
@@ -348,6 +348,9 @@ struct fm_fpm {
/* FPM Flush Control Register */
#define FMFP_FLC_DISP_LIM_NONE 0x00000000 /* no dispatch limitation */
+/* FMan Reset Command Register */
+#define FMFP_RSTC_RFM 0x80000000 /* FMan Soft Reset Command */
+
/* FMFP_EE - FPM event and enable register */
#define FMFPEE_DECC 0x80000000 /* double ECC err on FPM ram */
#define FMFPEE_STL 0x40000000 /* stall of task ... */
diff --git a/scripts/imx/imx.c b/scripts/imx/imx.c
index b3e8d62ba8..b8d939a431 100644
--- a/scripts/imx/imx.c
+++ b/scripts/imx/imx.c
@@ -673,13 +673,16 @@ static char *readcmd(struct config_data *data, FILE *f)
}
}
-int parse_config(struct config_data *data, const char *filename)
+int parse_config(struct config_data *data, const char *_filename)
{
FILE *f;
int lineno = 0;
char *line = NULL, *tmp;
char *argv[MAXARGS];
int nargs, i, ret = 0;
+ char *filename;
+
+ filename = strdup(_filename);
f = fopen(filename, "r");
if (!f) {
@@ -695,8 +698,17 @@ int parse_config(struct config_data *data, const char *filename)
lineno++;
tmp = strchr(line, '#');
- if (tmp)
- *tmp = 0;
+ if (tmp) {
+ char *endptr;
+ long linenum = strtol(tmp + 1, &endptr, 10);
+ if (strncmp(endptr, " \"", 2) == 0 && endptr[2]) {
+ free(filename);
+ lineno = linenum - 1;
+ filename = strdup(endptr + 2);
+ filename[strlen(filename) - 1] = '\0';
+ }
+ *tmp = '\0';
+ }
nargs = parse_line(line, argv);
if (!nargs)
@@ -708,8 +720,8 @@ int parse_config(struct config_data *data, const char *filename)
if (!strcmp(cmds[i].name, argv[0])) {
ret = cmds[i].parse(data, nargs, argv);
if (ret) {
- fprintf(stderr, "error in line %d: %s\n",
- lineno, strerror(-ret));
+ fprintf(stderr, "%s:%d: %s\n",
+ filename, lineno, strerror(-ret));
goto cleanup;
}
break;
@@ -724,5 +736,6 @@ int parse_config(struct config_data *data, const char *filename)
cleanup:
fclose(f);
+ free(filename);
return ret;
}