From e1f6c9ca6daef8e86b237e6bee09ee71ddace734 Mon Sep 17 00:00:00 2001 From: Gratian Crisan Date: Mon, 4 Nov 2013 14:51:20 -0600 Subject: [PATCH 01/83] scripts: Add pre-generated copy for arm-nilrt-linux-gnueabi-elfconfig.h In preparation for upgrading to gcc 4.7 we need a copy of the pre-generated header arm-nilrt-linux-gnueabi-elfconfig.h that matches the toolchain prefix. This file is identical to: arm-none-linux-gnueabi-elfconfig.h Signed-off-by: Gratian Crisan Acked-by: Brad Mouring --- scripts/mod/arm-nilrt-linux-gnueabi-elfconfig.h | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 scripts/mod/arm-nilrt-linux-gnueabi-elfconfig.h diff --git a/scripts/mod/arm-nilrt-linux-gnueabi-elfconfig.h b/scripts/mod/arm-nilrt-linux-gnueabi-elfconfig.h new file mode 100644 index 0000000000000..807d67db5eed8 --- /dev/null +++ b/scripts/mod/arm-nilrt-linux-gnueabi-elfconfig.h @@ -0,0 +1,4 @@ +#define KERNEL_ELFCLASS ELFCLASS32 +#define KERNEL_ELFDATA ELFDATA2LSB +#define HOST_ELFCLASS ELFCLASS32 +#define HOST_ELFDATA ELFDATA2LSB From ca1a7bc48138f6fc1f0b2d28d4ad38727bcccca8 Mon Sep 17 00:00:00 2001 From: Brad Mouring Date: Wed, 13 Nov 2013 15:00:01 -0600 Subject: [PATCH 02/83] scripts: Add pre-generated copy for x86_64 In order to support building the tools needed for on-target versioning for x86_64 targets (since HOSTCC continues to be x86), adding a pregenerated header for that toolchain. Signed-off-by: Brad Mouring Acked-by: Gratian Crisan --- scripts/mod/x86_64-nilrt-linux-elfconfig.h | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 scripts/mod/x86_64-nilrt-linux-elfconfig.h diff --git a/scripts/mod/x86_64-nilrt-linux-elfconfig.h b/scripts/mod/x86_64-nilrt-linux-elfconfig.h new file mode 100644 index 0000000000000..6dff0d9351a82 --- /dev/null +++ b/scripts/mod/x86_64-nilrt-linux-elfconfig.h @@ -0,0 +1,4 @@ +#define KERNEL_ELFCLASS ELFCLASS64 +#define KERNEL_ELFDATA ELFDATA2LSB +#define HOST_ELFCLASS ELFCLASS64 +#define HOST_ELFDATA ELFDATA2LSB From 2a6f40085264756f69765326e39719f3383201e3 Mon Sep 17 00:00:00 2001 From: Ben Shelton Date: Tue, 1 Apr 2014 11:31:31 -0500 Subject: [PATCH 03/83] shared: Adding mcopy syscall for Zynq Signed-off-by: Ben Shelton Acked-by: Scot Salmon Acked-by: Terry Wilcox Natinst-ReviewBoard-ID: 69848 [gratian: convert to new syscall table format for arm] Signed-off-by: Gratian Crisan [cvadrevu: Updated to just add missing Zynq code] Signed-off-by: Chaitanya Vadrevu --- arch/arm/tools/syscall.tbl | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/tools/syscall.tbl b/arch/arm/tools/syscall.tbl index b07e699aaa3c2..604c86e706260 100644 --- a/arch/arm/tools/syscall.tbl +++ b/arch/arm/tools/syscall.tbl @@ -484,3 +484,4 @@ 467 common open_tree_attr sys_open_tree_attr 468 common file_getattr sys_file_getattr 469 common file_setattr sys_file_setattr +470 common mcopy sys_mcopy From 15f532b628ad05f5c545f0eeb19833f4fabd6eb6 Mon Sep 17 00:00:00 2001 From: Francesca Ramadori Date: Thu, 26 Mar 2015 16:47:37 -0500 Subject: [PATCH 04/83] leds-ni793x: Add leds-ni793x driver to control the RT User 1 LED Add the leds-ni793x driver which controls the RT User 1 LED on the NI-793xR devices. The RT User 1 LED control is exposed through the Zynq FPGA logic. Signed-off-by: Francesca Ramadori Signed-off-by: Brad Mouring Acked-by: Josh Cartwright Acked-by: Ben Shelton [cvadrevu: Fixed trivial conflicts due to newer modules] [cvadrevu: Updated ni793x_leds_remove signature for newer kernel] [cvadrevu: Replaced ni793x_leds_ids with ni793x_led_ids] Signed-off-by: Chaitanya Vadrevu --- drivers/leds/Kconfig | 10 ++++ drivers/leds/Makefile | 1 + drivers/leds/leds-ni793x.c | 114 +++++++++++++++++++++++++++++++++++++ 3 files changed, 125 insertions(+) create mode 100644 drivers/leds/leds-ni793x.c diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index 06e6291be11b2..40a0a6116ffca 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig @@ -936,6 +936,16 @@ config LEDS_USER support in kernel. To compile this driver as a module, choose 'm' here: the module will be called uleds. +config LEDS_NI793X + tristate "LED support for NI 793xR devices" + depends on LEDS_CLASS + help + This option enables support for the User1 LED on the NI 793xR family + of devices. + + To compile this driver as a module, choose M here: the module will be + called leds-ni793x. + config LEDS_NIC78BX tristate "LED support for NI PXI NIC78bx devices" depends on LEDS_CLASS diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile index 9a0333ec1a861..db2dd3c511410 100644 --- a/drivers/leds/Makefile +++ b/drivers/leds/Makefile @@ -72,6 +72,7 @@ obj-$(CONFIG_LEDS_MLXREG) += leds-mlxreg.o obj-$(CONFIG_LEDS_MT6323) += leds-mt6323.o obj-$(CONFIG_LEDS_NET48XX) += leds-net48xx.o obj-$(CONFIG_LEDS_NETXBIG) += leds-netxbig.o +obj-$(CONFIG_LEDS_NI793X) += leds-ni793x.o obj-$(CONFIG_LEDS_NIC78BX) += leds-nic78bx.o obj-$(CONFIG_LEDS_NS2) += leds-ns2.o obj-$(CONFIG_LEDS_OT200) += leds-ot200.o diff --git a/drivers/leds/leds-ni793x.c b/drivers/leds/leds-ni793x.c new file mode 100644 index 0000000000000..b9edcc4bfb0ba --- /dev/null +++ b/drivers/leds/leds-ni793x.c @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2015 National Instruments Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include + +#define USER1_STATUS_BIT BIT(0) +#define USER1_OFF_CMD 0x1 +#define USER1_ON_CMD 0x2 + +struct ni793x_led { + void __iomem *user1; + struct led_classdev cdev; +}; + +static inline struct ni793x_led *to_ni793x_led(struct led_classdev *cdev) +{ + return container_of(cdev, struct ni793x_led, cdev); +} + +static void ni793x_led_set_brightness(struct led_classdev *cdev, + enum led_brightness brightness) +{ + struct ni793x_led *led = to_ni793x_led(cdev); + + if (brightness == LED_OFF) + writel_relaxed(USER1_OFF_CMD, led->user1); + else + writel_relaxed(USER1_ON_CMD, led->user1); +} + +static enum led_brightness +ni793x_led_get_brightness(struct led_classdev *cdev) +{ + struct ni793x_led *led = to_ni793x_led(cdev); + + return readl_relaxed(led->user1) & USER1_STATUS_BIT; +} + +static int ni793x_leds_probe(struct platform_device *pdev) +{ + struct device_node *node; + struct ni793x_led *led; + struct resource *res; + + led = devm_kzalloc(&pdev->dev, sizeof(*led), GFP_KERNEL); + if (!led) + return -ENOMEM; + + platform_set_drvdata(pdev, led); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + led->user1 = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(led->user1)) + return PTR_ERR(led->user1); + + node = of_get_child_by_name(pdev->dev.of_node, "user1"); + if (!node) { + dev_err(&pdev->dev, "user1 LED description not found\n"); + return -ENOENT; + } + + led->cdev.name = of_get_property(node, "label", NULL) ? : node->name; + led->cdev.default_trigger = of_get_property(node, + "linux,default-trigger", + NULL); + led->cdev.max_brightness = 1; + led->cdev.brightness_set = ni793x_led_set_brightness; + led->cdev.brightness_get = ni793x_led_get_brightness; + + return led_classdev_register(&pdev->dev, &led->cdev); +} + +static void ni793x_leds_remove(struct platform_device *pdev) +{ + struct ni793x_led *led = platform_get_drvdata(pdev); + + led_classdev_unregister(&led->cdev); +} + +static const struct of_device_id ni793x_led_ids[] = { + { .compatible = "ni,led-793x" }, + { }, +}; +MODULE_DEVICE_TABLE(of, ni793x_led_ids); + +static struct platform_driver ni793x_leds_driver = { + .driver = { + .name = "leds-ni793x", + .of_match_table = of_match_ptr(ni793x_led_ids), + }, + .probe = ni793x_leds_probe, + .remove = ni793x_leds_remove, +}; +module_platform_driver(ni793x_leds_driver); + +MODULE_DESCRIPTION("Driver for RT User1 LED on FlexRIO NI-793xR Products"); +MODULE_AUTHOR("National Instruments"); +MODULE_LICENSE("GPL"); From fa4877c4ff480bb211f3ae2a8aff2d3556c73ba4 Mon Sep 17 00:00:00 2001 From: Francesca Ramadori Date: Fri, 3 Apr 2015 16:37:13 -0500 Subject: [PATCH 05/83] leds-ni793x: Add documentation for leds-ni793x devicetree bindings Add documentation for leds-ni793x devicetree bindings. This driver controls the RT User1 LED on the FlexRIO NI-793xR devices. Signed-off-by: Francesca Ramadori Signed-off-by: Brad Mouring Acked-by: Josh Cartwright Acked-by: Ben Shelton --- .../devicetree/bindings/leds/leds-ni793x.txt | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 Documentation/devicetree/bindings/leds/leds-ni793x.txt diff --git a/Documentation/devicetree/bindings/leds/leds-ni793x.txt b/Documentation/devicetree/bindings/leds/leds-ni793x.txt new file mode 100644 index 0000000000000..5124e694cf88b --- /dev/null +++ b/Documentation/devicetree/bindings/leds/leds-ni793x.txt @@ -0,0 +1,21 @@ +LEDs connected to NI-793xR + +Required properties: +- compatible : should be : "ni,led-793x". +- reg: base address of LED control register space. + +The ni,led-793x device node only contains a single sub-node, 'user1'. + +LED sub-node properties: +- label : (optional) see leds/common.txt +- linux,default-trigger : (optional) see leds/common.txt + +Examples: + +leds-ni793x@4020F000 { + compatible = "ni,led-793x"; + reg = <0x4020F000 4>; + user1 { + label = "nilrt:user1:green"; + }; +}; From 1aa48caf568eac4983dacad405ff39ff87e74a24 Mon Sep 17 00:00:00 2001 From: Kyle Teske Date: Tue, 28 Aug 2012 12:48:18 -0500 Subject: [PATCH 06/83] fpgaperipheral: Add driver to notify clients on FPGA downloads Clients are drivers for peripherals with physical lines routed through the FPGA. Ethernet and serial will want to receive notifications so they can avoid accessing hardware while the FPGA is unprogrammed. Signed-off-by: Kyle Teske Natinst-ReviewBoard-ID: 26536 [cvadrevu: Fixed trivial conflicts due to newer modules] Signed-off-by: Chaitanya Vadrevu --- drivers/misc/Kconfig | 9 ++ drivers/misc/Makefile | 1 + drivers/misc/fpgaperipheral.c | 236 ++++++++++++++++++++++++++++++++++ include/misc/fpgaperipheral.h | 34 +++++ 4 files changed, 280 insertions(+) create mode 100644 drivers/misc/fpgaperipheral.c create mode 100644 include/misc/fpgaperipheral.h diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 2504de4c99b8e..62ca3814ce43e 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -57,6 +57,15 @@ config DUMMY_IRQ The sole purpose of this module is to help with debugging of systems on which spurious IRQs would happen on disabled IRQ vector. +config FPGA_PERIPHERAL + bool "FPGA Peripheral Driver" + help + FPGA Peripheral driver to notify peripheral devices of an + impending download. + + Used to make sure the devices routed through the FPGA are + powered off when an FPGA download occurs. + config IBM_ASM tristate "Device driver for IBM RSA service processor" depends on X86 && PCI && INPUT diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 2ce11031cd58f..67418457a63d9 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -77,3 +77,4 @@ obj-y += amd-sbi/ obj-$(CONFIG_MISC_RP1) += rp1/ obj-$(CONFIG_NI_RT_FEATURES) += nirtfeatures.o obj-$(CONFIG_NI_WATCHDOG) += niwatchdog.o +obj-$(CONFIG_FPGA_PERIPHERAL) += fpgaperipheral.o diff --git a/drivers/misc/fpgaperipheral.c b/drivers/misc/fpgaperipheral.c new file mode 100644 index 0000000000000..3432e4d580ce6 --- /dev/null +++ b/drivers/misc/fpgaperipheral.c @@ -0,0 +1,236 @@ +/* + * Copyright (C) 2012 National Instruments Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define FPGAPERIPHERAL_NAME "fpgaperipheral" +#define DEVCFG_INT_STS_OFFSET 0x0C +#define INT_STS_FPGA_DONE_MASK 0x04 + +BLOCKING_NOTIFIER_HEAD(fpgaperipheral_notifier_list); +EXPORT_SYMBOL_GPL(fpgaperipheral_notifier_list); + +/** + * struct fpgaperipheral_drvdata - fpgaperipheral driver structure + * @devcfg_addr: Pointer (from ioremap) to the devcfg memory region + */ +struct fpgaperipheral_drvdata { + void __iomem *devcfg_addr; +}; + +/* + * drvdata given filewide scope instead of dynamically + * allocated and passed around so it's easier to share between the + * platform driver (probe/remove) and misc device driver (open/release). + * This is okay since there is only ever 1 device. + */ +static struct fpgaperipheral_drvdata drvdata; + +/* Access control: Only allow one open at a time */ +static atomic_t fpgaperipheral_available = ATOMIC_INIT(1); + +/** + * is_fpga_programmed() - Checks if the FPGA is currently programmed + * Returns non-zero iff FPGA is programmed + */ +static int is_fpga_programmed(void) +{ + return ioread32(drvdata.devcfg_addr + DEVCFG_INT_STS_OFFSET) & + INT_STS_FPGA_DONE_MASK; +} + +/** + * notify_clients() - Depending on up_or_down, notifies clients FPGA is about + * to be unprogrammed, or is now programmed. + * @up_or_down: Whether FPGA is about to go down, or is now up. + */ +static void notify_clients(unsigned long up_or_down) +{ + blocking_notifier_call_chain(&fpgaperipheral_notifier_list, + up_or_down, NULL); +} + +/** + * fpgaperipheral_misc_open() - Notifies clients that FPGA is about to go down. + * Only allows 1 open() at a time. + * @inode: Pointer to the inode structure of this device. + * @file: Pointer to the file structure. + * Returns 0 on success, negative error otherwise + */ +static int fpgaperipheral_misc_open(struct inode *inode, struct file *file) +{ + if (!atomic_dec_and_test(&fpgaperipheral_available)) { + atomic_inc(&fpgaperipheral_available); + return -EBUSY; + } + + notify_clients(FPGA_PERIPHERAL_DOWN); + return 0; +} + +/** + * fpgaperipheral_misc_release() - Notifies clients that FPGA is back up. + * @inode: Pointer to the inode structure of this device. + * @file: Pointer to the file structure. + * Returns 0 on success, negative error otherwise + */ +static int fpgaperipheral_misc_release(struct inode *inode, struct file *file) +{ + if (is_fpga_programmed()) + notify_clients(FPGA_PERIPHERAL_UP); + + atomic_inc(&fpgaperipheral_available); + return 0; +} + +static const struct file_operations fpgaperipheral_misc_fops = { + .owner = THIS_MODULE, + .open = fpgaperipheral_misc_open, + .release = fpgaperipheral_misc_release +}; + +static struct miscdevice fpgaperipheral_misc_dev = { + .minor = MISC_DYNAMIC_MINOR, + .name = FPGAPERIPHERAL_NAME, + .fops = &fpgaperipheral_misc_fops, +}; + +/** + * fpgaperipheral_probe - Platform driver probe + * @pdev: Pointer to the platform device structure + * Returns 0 on success, negative error otherwise + */ +static int fpgaperipheral_probe(struct platform_device *pdev) +{ + int retval; + void __iomem *devcfg_addr; + struct resource *devcfg_res; + + /* Get devcfg resource */ + devcfg_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!devcfg_res) { + dev_err(&pdev->dev, "Couldn't get io resource\n"); + return -ENODEV; + } + + /* Get the mem region for devcfg */ + if (!request_mem_region(devcfg_res->start, + resource_size(devcfg_res), + FPGAPERIPHERAL_NAME)) { + dev_err(&pdev->dev, "Couldn't lock memory region at %Lx\n", + (unsigned long long) devcfg_res->start); + return -EBUSY; + } + + /* Map the devcfg mem region */ + devcfg_addr = ioremap(devcfg_res->start, resource_size(devcfg_res)); + if (!devcfg_addr) { + dev_err(&pdev->dev, "ioremap failed\n"); + retval = -EIO; + goto failed_after_request_mem_region; + } + + /* Set the drvdata where the misc device can find it */ + drvdata.devcfg_addr = devcfg_addr; + + /* Now register the misc device */ + retval = misc_register(&fpgaperipheral_misc_dev); + if (retval) { + dev_err(&pdev->dev, "Couldn't register misc device\n"); + goto failed_after_ioremap; + } + + return 0; + +failed_after_ioremap: + iounmap(drvdata.devcfg_addr); + +failed_after_request_mem_region: + release_mem_region(devcfg_res->start, resource_size(devcfg_res)); + + drvdata.devcfg_addr = NULL; + return retval; +} + +/** + * fpgaperipheral_remove - called when the platform driver is unregistered + * @pdev: Pointer to the platform device structure + * Returns 0 on success, negative error otherwise + */ +static int __exit fpgaperipheral_remove(struct platform_device *pdev) +{ + struct resource *devcfg_res; + + devcfg_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + + misc_deregister(&fpgaperipheral_misc_dev); + iounmap(drvdata.devcfg_addr); + release_mem_region(devcfg_res->start, resource_size(devcfg_res)); + + drvdata.devcfg_addr = NULL; + return 0; +} + +/* Match table for of_platform binding */ +#ifdef CONFIG_OF +static const struct of_device_id fpgaperipheral_of_match[] = { + { .compatible = FPGAPERIPHERAL_NAME, }, + {} +}; +MODULE_DEVICE_TABLE(of, fpgaperipheral_of_match); +#else +#define fpgaperipheral_of_match NULL +#endif + +static struct platform_driver fpgaperipheral_platform_driver = { + .probe = fpgaperipheral_probe, /* Probe method */ + .remove = __exit_p(fpgaperipheral_remove), /* Detach method */ + .driver = { + .owner = THIS_MODULE, + .name = FPGAPERIPHERAL_NAME, /* Driver name */ + .of_match_table = fpgaperipheral_of_match, + }, +}; + +/** + * fpgaperipheral_init - Initial driver registration call + * Returns 0 on success, negative error otherwise + */ +static int __init fpgaperipheral_init(void) +{ + return platform_driver_register(&fpgaperipheral_platform_driver); +} +module_init(fpgaperipheral_init); + +/** + * fpgaperipheral_exit - Driver unregistration call + * Returns 0 on success, negative error otherwise + */ +static void __exit fpgaperipheral_exit(void) +{ + platform_driver_unregister(&fpgaperipheral_platform_driver); +} +module_exit(fpgaperipheral_exit); + +MODULE_DESCRIPTION("Bus driver for FPGA peripherals on NI's Zynq-based controllers"); +MODULE_AUTHOR("Kyle Teske "); +MODULE_LICENSE("GPL"); diff --git a/include/misc/fpgaperipheral.h b/include/misc/fpgaperipheral.h new file mode 100644 index 0000000000000..aec44e06ae2d6 --- /dev/null +++ b/include/misc/fpgaperipheral.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2012 National Instruments Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _FPGA_PERIPHERAL_H_ +#define _FPGA_PERIPHERAL_H_ + +#include + +/* + * The value passed to notifier callbacks will be one of these. + * FPGA_PERIPHERAL_DOWN: The FPGA is about to be unprogrammed. + * FPGA_PERIPHERAL_UP: The FPGA is now programmed. + * This may be called even if not preceded by an FPGA_PERIPHERAL_DOWN. + * + * Client callbacks should always return notifier_from_errno(0) so the + * call chain continues to all clients. + */ +#define FPGA_PERIPHERAL_DOWN 0 +#define FPGA_PERIPHERAL_UP 1 + +extern struct blocking_notifier_head fpgaperipheral_notifier_list; + +#endif /* _FPGA_PERIPHERAL_H_ */ From 14bc4f0638dface168a8fab023bd36ba081cc60d Mon Sep 17 00:00:00 2001 From: Brad Mouring Date: Thu, 27 Oct 2016 17:18:54 -0500 Subject: [PATCH 07/83] fpgaperipheral: Add notification for failure We add a separate notification which will get called when FPGA programming fails. This is to enable client drivers to know when to stop waiting for FPGA to come up, if the re-programming fails. Signed-off-by: Karthik Manamcheri --- drivers/misc/fpgaperipheral.c | 2 ++ include/misc/fpgaperipheral.h | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/drivers/misc/fpgaperipheral.c b/drivers/misc/fpgaperipheral.c index 3432e4d580ce6..355f50f443dcc 100644 --- a/drivers/misc/fpgaperipheral.c +++ b/drivers/misc/fpgaperipheral.c @@ -97,6 +97,8 @@ static int fpgaperipheral_misc_release(struct inode *inode, struct file *file) { if (is_fpga_programmed()) notify_clients(FPGA_PERIPHERAL_UP); + else + notify_clients(FPGA_PERIPHERAL_FAILED); atomic_inc(&fpgaperipheral_available); return 0; diff --git a/include/misc/fpgaperipheral.h b/include/misc/fpgaperipheral.h index aec44e06ae2d6..37817cad66b64 100644 --- a/include/misc/fpgaperipheral.h +++ b/include/misc/fpgaperipheral.h @@ -22,12 +22,17 @@ * FPGA_PERIPHERAL_DOWN: The FPGA is about to be unprogrammed. * FPGA_PERIPHERAL_UP: The FPGA is now programmed. * This may be called even if not preceded by an FPGA_PERIPHERAL_DOWN. + * FPGA_PERIPHERAL_FAILED: The FPGA programming failed. + * If this is called, clients should not use the FPGA as it might be in + * a bad state. This is to notify the clients to abort any waiting for + * the FPGA to come back up. * * Client callbacks should always return notifier_from_errno(0) so the * call chain continues to all clients. */ #define FPGA_PERIPHERAL_DOWN 0 #define FPGA_PERIPHERAL_UP 1 +#define FPGA_PERIPHERAL_FAILED 2 extern struct blocking_notifier_head fpgaperipheral_notifier_list; From 11a785f018491256637e3e8e7c98c3ba3727601b Mon Sep 17 00:00:00 2001 From: Ben Shelton Date: Tue, 10 Jun 2014 11:47:28 -0500 Subject: [PATCH 08/83] fpgaperipheral: Add dev_info message if probe succeeded If fpgaperipheral_probe succeeds, it generates no debug output, even at the highest loglevel. Add a success message to make device tree debugging easier. Signed-off-by: Ben Shelton --- drivers/misc/fpgaperipheral.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/misc/fpgaperipheral.c b/drivers/misc/fpgaperipheral.c index 355f50f443dcc..e4015cb96bab7 100644 --- a/drivers/misc/fpgaperipheral.c +++ b/drivers/misc/fpgaperipheral.c @@ -161,6 +161,8 @@ static int fpgaperipheral_probe(struct platform_device *pdev) goto failed_after_ioremap; } + dev_info(&pdev->dev, "probe succeeded\n"); + return 0; failed_after_ioremap: From ab72950bbd84bd52cf38638bca5b4077ecf4eb1e Mon Sep 17 00:00:00 2001 From: Josh Cartwright Date: Mon, 5 Mar 2012 11:55:13 -0600 Subject: [PATCH 09/83] nizynqcpld: Add support for the NI Zynq CPLD The NI Zynq prototype board has a CPLD that provides various board-management capabilities. Signed-off-by: Josh Cartwright Signed-off-by: Jaeden Amero Acked-by: Jeff Westfahl Acked-by: Joe Hershberger [cvadrevu: Fixed trivial conflicts due to newer module] Signed-off-by: Chaitanya Vadrevu --- drivers/misc/Kconfig | 10 ++ drivers/misc/Makefile | 1 + drivers/misc/nizynqcpld.c | 222 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 233 insertions(+) create mode 100644 drivers/misc/nizynqcpld.c diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 62ca3814ce43e..64ae506071e5c 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -102,6 +102,16 @@ config IBMVMC To compile this driver as a module, choose M here: the module will be called ibmvmc. +config NIZYNQ_CPLD + tristate "National Instruments Zynq CPLD driver" + depends on I2C + help + If you say yes here, you get support for the CPLD features + on National Instruments Zynq-based targets. + + This driver can also be built as a module. If so, the module + will be called nizynqcpld.ko. + config PHANTOM tristate "Sensable PHANToM (PCI)" depends on PCI diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 67418457a63d9..0ca142eee19bf 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -29,6 +29,7 @@ obj-$(CONFIG_SMPRO_ERRMON) += smpro-errmon.o obj-$(CONFIG_SMPRO_MISC) += smpro-misc.o obj-$(CONFIG_CS5535_MFGPT) += cs5535-mfgpt.o obj-$(CONFIG_GEHC_ACHC) += gehc-achc.o +obj-$(CONFIG_NIZYNQ_CPLD) += nizynqcpld.o obj-$(CONFIG_HP_ILO) += hpilo.o obj-$(CONFIG_APDS9802ALS) += apds9802als.o obj-$(CONFIG_ISL29003) += isl29003.o diff --git a/drivers/misc/nizynqcpld.c b/drivers/misc/nizynqcpld.c new file mode 100644 index 0000000000000..ac8eebb4683c2 --- /dev/null +++ b/drivers/misc/nizynqcpld.c @@ -0,0 +1,222 @@ +/* + * Copyright (C) 2012 National Instruments Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include +#include +#include + + +#define NIZYNQCPLD_VERSION 0x00 +#define NIZYNQCPLD_PRODUCT 0x1D + +struct nizynqcpld_desc { + u8 supported_version; + u8 supported_product; +}; + +struct nizynqcpld { + struct device *dev; + struct nizynqcpld_desc *desc; + struct i2c_client *client; + struct mutex lock; +}; + +static int nizynqcpld_write(struct nizynqcpld *cpld, u8 reg, u8 data); +static int nizynqcpld_read(struct nizynqcpld *cpld, u8 reg, u8 *data); + +static inline void nizynqcpld_lock(struct nizynqcpld *cpld) +{ + mutex_lock(&cpld->lock); +} +static inline void nizynqcpld_unlock(struct nizynqcpld *cpld) +{ + mutex_unlock(&cpld->lock); +} + +static int nizynqcpld_write(struct nizynqcpld *cpld, u8 reg, u8 data) +{ + int err; + u8 tdata[2] = { reg, data }; + + /* write reg byte, then data */ + struct i2c_msg msg = { + .addr = cpld->client->addr, + .len = 2, + .buf = tdata, + }; + + err = i2c_transfer(cpld->client->adapter, &msg, 1); + + return err == 1 ? 0 : err; +} + +static int nizynqcpld_read(struct nizynqcpld *cpld, u8 reg, u8 *data) +{ + int err; + + /* First, write the CPLD register offset, then read the data. */ + struct i2c_msg msgs[] = { + { + .addr = cpld->client->addr, + .len = 1, + .buf = ®, + }, + { + .addr = cpld->client->addr, + .flags = I2C_M_RD, + .len = 1, + .buf = data, + }, + }; + + err = i2c_transfer(cpld->client->adapter, msgs, ARRAY_SIZE(msgs)); + + return err == ARRAY_SIZE(msgs) ? 0 : err; +} + +static struct nizynqcpld_desc nizynqcpld_descs[] = { + /* DosEquis and myRIO development CPLD */ + { + .supported_version = 3, + .supported_product = 0, + }, + /* DosEquis and myRIO development CPLD */ + { + .supported_version = 4, + .supported_product = 0, + }, + /* DosEquis and myRIO development CPLD */ + { + .supported_version = 5, + .supported_product = 0, + }, + /* DosEquis CPLD */ + { + .supported_version = 6, + .supported_product = 0, + }, + /* myRIO CPLD */ + { + .supported_version = 6, + .supported_product = 1, + }, +}; + +static int nizynqcpld_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct nizynqcpld_desc *desc; + struct nizynqcpld *cpld; + u8 version; + u8 product; + int err; + int i; + + cpld = kzalloc(sizeof(*cpld), GFP_KERNEL); + if (!cpld) { + err = -ENOMEM; + dev_err(&client->dev, "could not allocate private data.\n"); + goto err_cpld_alloc; + } + + cpld->dev = &client->dev; + cpld->client = client; + mutex_init(&cpld->lock); + + err = nizynqcpld_read(cpld, NIZYNQCPLD_VERSION, + &version); + if (err) { + dev_err(cpld->dev, "could not read version cpld version.\n"); + goto err_read_info; + } + + err = nizynqcpld_read(cpld, NIZYNQCPLD_PRODUCT, &product); + if (err) { + dev_err(cpld->dev, "could not read cpld product number.\n"); + goto err_read_info; + } + + for (i = 0, desc = NULL; i < ARRAY_SIZE(nizynqcpld_descs); i++) { + if (nizynqcpld_descs[i].supported_version == version && + nizynqcpld_descs[i].supported_product == product) { + desc = &nizynqcpld_descs[i]; + break; + } + } + + if (!desc) { + err = -ENODEV; + dev_err(cpld->dev, + "this driver does not support cpld with version %d and" + " product %d.\n", version, product); + goto err_no_version; + } + + cpld->desc = desc; + + i2c_set_clientdata(client, cpld); + + dev_info(&client->dev, + "%s NI Zynq-based target CPLD found.\n", + client->name); + + return 0; + +err_no_version: +err_read_info: + kfree(cpld); +err_cpld_alloc: + return err; +} + +static int nizynqcpld_remove(struct i2c_client *client) +{ + struct nizynqcpld *cpld = i2c_get_clientdata(client); + + kfree(cpld); + return 0; +} + +static const struct i2c_device_id nizynqcpld_ids[] = { + { .name = "nizynqcpld" }, + { }, +}; +MODULE_DEVICE_TABLE(i2c, nizynqcpld_ids); + +static struct i2c_driver nizynqcpld_driver = { + .driver = { + .name = "nizynqcpld", + .owner = THIS_MODULE, + }, + .probe = nizynqcpld_probe, + .remove = nizynqcpld_remove, + .id_table = nizynqcpld_ids, +}; + +static int __init nizynqcpld_init(void) +{ + return i2c_add_driver(&nizynqcpld_driver); +} +module_init(nizynqcpld_init); + +static void __exit nizynqcpld_exit(void) +{ + i2c_del_driver(&nizynqcpld_driver); +} +module_exit(nizynqcpld_exit); + +MODULE_DESCRIPTION("Driver for CPLD on NI's Zynq RIO products"); +MODULE_AUTHOR("National Instruments"); +MODULE_LICENSE("GPL"); From 283027c6f16f64c9b87a4185ca320ac732d6e855 Mon Sep 17 00:00:00 2001 From: Josh Cartwright Date: Mon, 5 Mar 2012 11:55:13 -0600 Subject: [PATCH 10/83] nizynqcpld: Add scratchpad read and write This provides a general purpose, raw interface to the CPLD's scratchpad. The scratchpad can be used to communicate between soft reboots of the target. Signed-off-by: Josh Cartwright --- drivers/misc/Kconfig | 2 +- drivers/misc/nizynqcpld.c | 135 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 136 insertions(+), 1 deletion(-) diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 64ae506071e5c..b1fb65d6b480d 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -104,7 +104,7 @@ config IBMVMC config NIZYNQ_CPLD tristate "National Instruments Zynq CPLD driver" - depends on I2C + depends on I2C && SYSFS help If you say yes here, you get support for the CPLD features on National Instruments Zynq-based targets. diff --git a/drivers/misc/nizynqcpld.c b/drivers/misc/nizynqcpld.c index ac8eebb4683c2..e2e6b072986e8 100644 --- a/drivers/misc/nizynqcpld.c +++ b/drivers/misc/nizynqcpld.c @@ -21,9 +21,18 @@ #define NIZYNQCPLD_VERSION 0x00 #define NIZYNQCPLD_PRODUCT 0x1D +#define PROTO_SCRATCHPADSR 0xFE +#define PROTO_SCRATCHPADHR 0xFF + +#define DOSX_SCRATCHPADSR 0x1E +#define DOSX_SCRATCHPADHR 0x1F + struct nizynqcpld_desc { + const struct attribute **attrs; u8 supported_version; u8 supported_product; + u8 scratch_hr_addr; + u8 scratch_sr_addr; }; struct nizynqcpld { @@ -86,31 +95,147 @@ static int nizynqcpld_read(struct nizynqcpld *cpld, u8 reg, u8 *data) return err == ARRAY_SIZE(msgs) ? 0 : err; } +static inline ssize_t nizynqcpld_scratch_show(struct nizynqcpld *cpld, + struct device_attribute *attr, + char *buf, u8 reg_addr) +{ + u8 data; + int err; + + nizynqcpld_lock(cpld); + err = nizynqcpld_read(cpld, reg_addr, &data); + nizynqcpld_unlock(cpld); + + if (err) { + dev_err(cpld->dev, "Error reading scratch register state.\n"); + return err; + } + + return sprintf(buf, "%02x\n", data); +} + +static ssize_t nizynqcpld_scratchsr_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct nizynqcpld *cpld = dev_get_drvdata(dev); + struct nizynqcpld_desc *desc = cpld->desc; + return nizynqcpld_scratch_show(cpld, attr, buf, desc->scratch_sr_addr); +} + +static ssize_t nizynqcpld_scratchhr_show( + struct device *dev, struct device_attribute *attr, char *buf) +{ + struct nizynqcpld *cpld = dev_get_drvdata(dev); + struct nizynqcpld_desc *desc = cpld->desc; + return nizynqcpld_scratch_show(cpld, attr, buf, desc->scratch_hr_addr); +} + +static inline ssize_t nizynqcpld_scratch_store(struct nizynqcpld *cpld, + struct device_attribute *attr, + const char *buf, size_t count, + u8 reg_addr) +{ + unsigned long tmp; + u8 data; + int err; + + err = kstrtoul(buf, 0, &tmp); + if (err) + return err; + + data = (u8) tmp; + + nizynqcpld_lock(cpld); + err = nizynqcpld_write(cpld, reg_addr, data); + nizynqcpld_unlock(cpld); + + if (err) { + dev_err(cpld->dev, + "Error writing to scratch register.\n"); + return err; + } + + return count; +} + +static ssize_t nizynqcpld_scratchsr_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct nizynqcpld *cpld = dev_get_drvdata(dev); + struct nizynqcpld_desc *desc = cpld->desc; + return nizynqcpld_scratch_store(cpld, attr, buf, count, + desc->scratch_sr_addr); +} + +static ssize_t nizynqcpld_scratchhr_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct nizynqcpld *cpld = dev_get_drvdata(dev); + struct nizynqcpld_desc *desc = cpld->desc; + return nizynqcpld_scratch_store(cpld, attr, buf, count, + desc->scratch_hr_addr); +} + +static DEVICE_ATTR(scratch_softreset, S_IRUSR|S_IWUSR, + nizynqcpld_scratchsr_show, nizynqcpld_scratchsr_store); +static DEVICE_ATTR(scratch_hardreset, S_IRUSR|S_IWUSR, + nizynqcpld_scratchhr_show, nizynqcpld_scratchhr_store); + +static const struct attribute *nizynqcpld_attrs[] = { + &dev_attr_scratch_softreset.attr, + &dev_attr_scratch_hardreset.attr, + NULL +}; + +static const struct attribute *dosequis6_attrs[] = { + &dev_attr_scratch_softreset.attr, + &dev_attr_scratch_hardreset.attr, + NULL +}; + static struct nizynqcpld_desc nizynqcpld_descs[] = { /* DosEquis and myRIO development CPLD */ { + .attrs = nizynqcpld_attrs, .supported_version = 3, .supported_product = 0, + .scratch_hr_addr = PROTO_SCRATCHPADHR, + .scratch_sr_addr = PROTO_SCRATCHPADSR, }, /* DosEquis and myRIO development CPLD */ { + .attrs = nizynqcpld_attrs, .supported_version = 4, .supported_product = 0, + .scratch_hr_addr = DOSX_SCRATCHPADHR, + .scratch_sr_addr = DOSX_SCRATCHPADSR, }, /* DosEquis and myRIO development CPLD */ { + .attrs = nizynqcpld_attrs, .supported_version = 5, .supported_product = 0, + .scratch_hr_addr = DOSX_SCRATCHPADHR, + .scratch_sr_addr = DOSX_SCRATCHPADSR, }, /* DosEquis CPLD */ { + .attrs = dosequis6_attrs, .supported_version = 6, .supported_product = 0, + .scratch_hr_addr = DOSX_SCRATCHPADHR, + .scratch_sr_addr = DOSX_SCRATCHPADSR, }, /* myRIO CPLD */ { + .attrs = dosequis6_attrs, .supported_version = 6, .supported_product = 1, + .scratch_hr_addr = DOSX_SCRATCHPADHR, + .scratch_sr_addr = DOSX_SCRATCHPADSR, }, }; @@ -166,6 +291,12 @@ static int nizynqcpld_probe(struct i2c_client *client, cpld->desc = desc; + err = sysfs_create_files(&cpld->dev->kobj, desc->attrs); + if (err) { + dev_err(cpld->dev, "could not register attrs for device.\n"); + goto err_sysfs_create_files; + } + i2c_set_clientdata(client, cpld); dev_info(&client->dev, @@ -174,6 +305,8 @@ static int nizynqcpld_probe(struct i2c_client *client, return 0; + sysfs_remove_files(&client->dev.kobj, desc->attrs); +err_sysfs_create_files: err_no_version: err_read_info: kfree(cpld); @@ -184,7 +317,9 @@ static int nizynqcpld_probe(struct i2c_client *client, static int nizynqcpld_remove(struct i2c_client *client) { struct nizynqcpld *cpld = i2c_get_clientdata(client); + struct nizynqcpld_desc *desc = cpld->desc; + sysfs_remove_files(&cpld->dev->kobj, desc->attrs); kfree(cpld); return 0; } From ef40de560d7bf67a9a2ce95d4e7c1241e3db18be Mon Sep 17 00:00:00 2001 From: Josh Cartwright Date: Mon, 20 Aug 2012 18:43:12 -0500 Subject: [PATCH 11/83] nizynqcpld: Add 'bootmode' attribute This is a read/write attribute that will set the necessary bits in the scratch registers used to determine which mode the board boots into. Currently, valid modes are 'runtime', 'safemode', and 'recovery'. Signed-off-by: Josh Cartwright --- drivers/misc/nizynqcpld.c | 68 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/drivers/misc/nizynqcpld.c b/drivers/misc/nizynqcpld.c index e2e6b072986e8..24781cbf19ada 100644 --- a/drivers/misc/nizynqcpld.c +++ b/drivers/misc/nizynqcpld.c @@ -184,13 +184,81 @@ static DEVICE_ATTR(scratch_softreset, S_IRUSR|S_IWUSR, static DEVICE_ATTR(scratch_hardreset, S_IRUSR|S_IWUSR, nizynqcpld_scratchhr_show, nizynqcpld_scratchhr_store); +static const char * const bootmode_strings[] = { + "runtime", "safemode", "recovery", +}; + +static ssize_t nizynqcpld_bootmode_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct nizynqcpld *cpld = dev_get_drvdata(dev); + struct nizynqcpld_desc *desc = cpld->desc; + int err; + u8 tmp; + + nizynqcpld_lock(cpld); + err = nizynqcpld_read(cpld, desc->scratch_hr_addr, &tmp); + nizynqcpld_unlock(cpld); + + if (err) + return err; + + tmp &= 0x3; + if (tmp >= ARRAY_SIZE(bootmode_strings)) + return -EINVAL; + + return sprintf(buf, "%s\n", bootmode_strings[tmp]); +} + +static int nizynqcpld_set_bootmode(struct nizynqcpld *cpld, u8 mode) +{ + struct nizynqcpld_desc *desc = cpld->desc; + int err; + u8 tmp; + + nizynqcpld_lock(cpld); + + err = nizynqcpld_read(cpld, desc->scratch_hr_addr, &tmp); + if (err) + goto unlock_out; + + tmp &= ~0x3; + tmp |= mode; + + err = nizynqcpld_write(cpld, desc->scratch_hr_addr, tmp); + +unlock_out: + nizynqcpld_unlock(cpld); + return err; +} + +static ssize_t nizynqcpld_bootmode_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct nizynqcpld *cpld = dev_get_drvdata(dev); + u8 i; + + for (i = 0; i < ARRAY_SIZE(bootmode_strings); i++) + if (!strcmp(buf, bootmode_strings[i])) + return nizynqcpld_set_bootmode(cpld, i) ?: count; + + return -EINVAL; +} + +static DEVICE_ATTR(bootmode, S_IRUSR|S_IWUSR, nizynqcpld_bootmode_show, + nizynqcpld_bootmode_store); + static const struct attribute *nizynqcpld_attrs[] = { + &dev_attr_bootmode.attr, &dev_attr_scratch_softreset.attr, &dev_attr_scratch_hardreset.attr, NULL }; static const struct attribute *dosequis6_attrs[] = { + &dev_attr_bootmode.attr, &dev_attr_scratch_softreset.attr, &dev_attr_scratch_hardreset.attr, NULL From 476bb39807fee4e3eaf40615ce3c1c445e3e97a0 Mon Sep 17 00:00:00 2001 From: Josh Cartwright Date: Mon, 5 Mar 2012 11:55:13 -0600 Subject: [PATCH 12/83] nizynqcpld: Add support for LEDs Signed-off-by: Josh Cartwright Signed-off-by: Scot Salmon Acked-by: Brad Mouring Acked-by: Josh Cartwright Natinst-ReviewBoard-ID: 36482 --- drivers/misc/Kconfig | 2 +- drivers/misc/nizynqcpld.c | 265 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 266 insertions(+), 1 deletion(-) diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index b1fb65d6b480d..7f369157c4609 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -104,7 +104,7 @@ config IBMVMC config NIZYNQ_CPLD tristate "National Instruments Zynq CPLD driver" - depends on I2C && SYSFS + depends on I2C && SYSFS && LEDS_CLASS help If you say yes here, you get support for the CPLD features on National Instruments Zynq-based targets. diff --git a/drivers/misc/nizynqcpld.c b/drivers/misc/nizynqcpld.c index 24781cbf19ada..4f5fce3cd72ab 100644 --- a/drivers/misc/nizynqcpld.c +++ b/drivers/misc/nizynqcpld.c @@ -12,6 +12,7 @@ * GNU General Public License for more details. */ #include +#include #include #include #include @@ -21,16 +22,48 @@ #define NIZYNQCPLD_VERSION 0x00 #define NIZYNQCPLD_PRODUCT 0x1D +#define PROTO_SWITCHANDLED 0x04 +#define PROTO_ETHERNETLED 0x05 #define PROTO_SCRATCHPADSR 0xFE #define PROTO_SCRATCHPADHR 0xFF +#define DOSX_STATUSLEDSHIFTBYTE1 0x05 +#define DOSX_STATUSLEDSHIFTBYTE0 0x06 +#define DOSX_LED 0x07 +#define DOSX_ETHERNETLED 0x08 #define DOSX_SCRATCHPADSR 0x1E #define DOSX_SCRATCHPADHR 0x1F +struct nizynqcpld_led_desc { + const char *name; + const char *default_trigger; + u8 addr; + u8 bit; + u8 pattern_lo_addr; + u8 pattern_hi_addr; + int max_brightness; +}; + +struct nizynqcpld; + +struct nizynqcpld_led { + struct nizynqcpld *cpld; + struct nizynqcpld_led_desc *desc; + unsigned on:1; + struct led_classdev cdev; + struct work_struct deferred_work; + u16 blink_pattern; +}; + +#define to_nizynqcpld_led(x) \ + container_of(x, struct nizynqcpld_led, cdev) + struct nizynqcpld_desc { const struct attribute **attrs; u8 supported_version; u8 supported_product; + struct nizynqcpld_led_desc *led_descs; + unsigned num_led_descs; u8 scratch_hr_addr; u8 scratch_sr_addr; }; @@ -38,6 +71,7 @@ struct nizynqcpld_desc { struct nizynqcpld { struct device *dev; struct nizynqcpld_desc *desc; + struct nizynqcpld_led *leds; struct i2c_client *client; struct mutex lock; }; @@ -54,6 +88,70 @@ static inline void nizynqcpld_unlock(struct nizynqcpld *cpld) mutex_unlock(&cpld->lock); } +/* Can't issue i2c transfers in set_brightness, because + * they can sleep */ +static void nizynqcpld_set_brightness_work(struct work_struct *work) +{ + struct nizynqcpld_led *led = container_of(work, struct nizynqcpld_led, + deferred_work); + struct nizynqcpld_led_desc *desc = led->desc; + struct nizynqcpld *cpld = led->cpld; + int err; + u8 tmp; + + nizynqcpld_lock(cpld); + + err = nizynqcpld_read(cpld, desc->addr, &tmp); + if (err) + goto unlock_out; + + tmp &= ~desc->bit; + if (led->on) + tmp |= desc->bit; + + nizynqcpld_write(cpld, desc->addr, tmp); + + if (desc->pattern_lo_addr && desc->pattern_hi_addr) { + /* spec says to write byte 1 first */ + nizynqcpld_write(cpld, desc->pattern_hi_addr, + led->blink_pattern >> 8); + nizynqcpld_write(cpld, desc->pattern_lo_addr, + led->blink_pattern & 0xff); + } + +unlock_out: + nizynqcpld_unlock(cpld); +} + +static void nizynqcpld_led_set_brightness(struct led_classdev *led_cdev, + enum led_brightness brightness) +{ + struct nizynqcpld_led *led = to_nizynqcpld_led(led_cdev); + led->on = !!brightness; + /* some LED's support a blink pattern instead of a variable brightness, + and blink_set isn't flexible enough for the supported patterns */ + led->blink_pattern = brightness; + schedule_work(&led->deferred_work); +} + +static enum led_brightness +nizynqcpld_led_get_brightness(struct led_classdev *led_cdev) +{ + struct nizynqcpld_led *led = to_nizynqcpld_led(led_cdev); + struct nizynqcpld_led_desc *desc = led->desc; + struct nizynqcpld *cpld = led->cpld; + u8 tmp; + + nizynqcpld_lock(cpld); + /* can't handle an error here, so, roll with it. */ + nizynqcpld_read(cpld, desc->addr, &tmp); + nizynqcpld_unlock(cpld); + + /* for the status LED, the blink pattern used for brightness on write + is write-only, so we just return on/off for all LED's */ + return tmp & desc->bit ? LED_FULL : 0; +} + static int nizynqcpld_write(struct nizynqcpld *cpld, u8 reg, u8 data) { int err; @@ -71,6 +169,49 @@ static int nizynqcpld_write(struct nizynqcpld *cpld, u8 reg, u8 data) return err == 1 ? 0 : err; } +static int nizynqcpld_led_register(struct nizynqcpld *cpld, + struct nizynqcpld_led_desc *desc, + struct nizynqcpld_led *led) +{ + int err; + u8 tmp; + + nizynqcpld_lock(cpld); + err = nizynqcpld_read(cpld, desc->addr, &tmp); + nizynqcpld_unlock(cpld); + + if (err) + goto err_out; + + led->cpld = cpld; + led->desc = desc; + led->on = !!(tmp & desc->bit); + INIT_WORK(&led->deferred_work, nizynqcpld_set_brightness_work); + + led->cdev.name = desc->name; + led->cdev.default_trigger = desc->default_trigger; + led->cdev.max_brightness = desc->max_brightness ? desc->max_brightness + : 1; + led->cdev.brightness_set = nizynqcpld_led_set_brightness; + led->cdev.brightness_get = nizynqcpld_led_get_brightness; + + err = led_classdev_register(cpld->dev, &led->cdev); + if (err) { + dev_err(cpld->dev, "error registering led.\n"); + goto err_led; + } + +err_led: +err_out: + return err; +} + +static void nizynqcpld_led_unregister(struct nizynqcpld_led *led) +{ + led_classdev_unregister(&led->cdev); +} + + static int nizynqcpld_read(struct nizynqcpld *cpld, u8 reg, u8 *data) { int err; @@ -264,12 +405,104 @@ static const struct attribute *dosequis6_attrs[] = { NULL }; +static struct nizynqcpld_led_desc proto_leds[] = { + { + .name = "nizynqcpld:user1:green", + .addr = PROTO_SWITCHANDLED, + .bit = 1 << 4, + }, + { + .name = "nizynqcpld:user1:yellow", + .addr = PROTO_SWITCHANDLED, + .bit = 1 << 3, + }, + { + .name = "nizynqcpld:status:yellow", + .addr = PROTO_SWITCHANDLED, + .bit = 1 << 2, + }, + { + .name = "nizynqcpld:eth1:green", + .addr = PROTO_ETHERNETLED, + .bit = 1 << 1, + .default_trigger = "e000b000:00:100Mb", + }, + { + .name = "nizynqcpld:eth1:yellow", + .addr = PROTO_ETHERNETLED, + .bit = 1 << 0, + .default_trigger = "e000b000:00:Gb", + }, +}; + +static struct nizynqcpld_led_desc dosx_leds[] = { + { + .name = "nizynqcpld:user1:green", + .addr = DOSX_LED, + .bit = 1 << 5, + }, + { + .name = "nizynqcpld:user1:yellow", + .addr = DOSX_LED, + .bit = 1 << 4, + }, + { + .name = "nizynqcpld:status:red", + .addr = DOSX_LED, + .bit = 1 << 3, + }, + { + .name = "nizynqcpld:status:yellow", + .addr = DOSX_LED, + .bit = 1 << 2, + .pattern_lo_addr = DOSX_STATUSLEDSHIFTBYTE0, + .pattern_hi_addr = DOSX_STATUSLEDSHIFTBYTE1, + .max_brightness = 0xffff, + }, + { + .name = "nizynqcpld:wifi:green", + .addr = DOSX_ETHERNETLED, + .bit = 1 << 5, + }, + { + .name = "nizynqcpld:wifi:yellow", + .addr = DOSX_ETHERNETLED, + .bit = 1 << 4, + }, + { + .name = "nizynqcpld:eth1:green", + .addr = DOSX_ETHERNETLED, + .bit = 1 << 3, + .default_trigger = "e000b000:01:100Mb", + }, + { + .name = "nizynqcpld:eth1:yellow", + .addr = DOSX_ETHERNETLED, + .bit = 1 << 2, + .default_trigger = "e000b000:01:Gb", + }, + { + .name = "nizynqcpld:eth0:green", + .addr = DOSX_ETHERNETLED, + .bit = 1 << 1, + .default_trigger = "e000b000:00:100Mb", + }, + { + .name = "nizynqcpld:eth0:yellow", + .addr = DOSX_ETHERNETLED, + .bit = 1 << 0, + .default_trigger = "e000b000:00:Gb", + }, +}; + static struct nizynqcpld_desc nizynqcpld_descs[] = { /* DosEquis and myRIO development CPLD */ { .attrs = nizynqcpld_attrs, .supported_version = 3, .supported_product = 0, + .led_descs = proto_leds, + .num_led_descs = ARRAY_SIZE(proto_leds), .scratch_hr_addr = PROTO_SCRATCHPADHR, .scratch_sr_addr = PROTO_SCRATCHPADSR, }, @@ -278,6 +511,8 @@ static struct nizynqcpld_desc nizynqcpld_descs[] = { .attrs = nizynqcpld_attrs, .supported_version = 4, .supported_product = 0, + .led_descs = dosx_leds, + .num_led_descs = ARRAY_SIZE(dosx_leds), .scratch_hr_addr = DOSX_SCRATCHPADHR, .scratch_sr_addr = DOSX_SCRATCHPADSR, }, @@ -286,6 +521,8 @@ static struct nizynqcpld_desc nizynqcpld_descs[] = { .attrs = nizynqcpld_attrs, .supported_version = 5, .supported_product = 0, + .led_descs = dosx_leds, + .num_led_descs = ARRAY_SIZE(dosx_leds), .scratch_hr_addr = DOSX_SCRATCHPADHR, .scratch_sr_addr = DOSX_SCRATCHPADSR, }, @@ -294,6 +531,8 @@ static struct nizynqcpld_desc nizynqcpld_descs[] = { .attrs = dosequis6_attrs, .supported_version = 6, .supported_product = 0, + .led_descs = dosx_leds, + .num_led_descs = ARRAY_SIZE(dosx_leds), .scratch_hr_addr = DOSX_SCRATCHPADHR, .scratch_sr_addr = DOSX_SCRATCHPADSR, }, @@ -302,6 +541,8 @@ static struct nizynqcpld_desc nizynqcpld_descs[] = { .attrs = dosequis6_attrs, .supported_version = 6, .supported_product = 1, + .led_descs = dosx_leds, + .num_led_descs = ARRAY_SIZE(dosx_leds), .scratch_hr_addr = DOSX_SCRATCHPADHR, .scratch_sr_addr = DOSX_SCRATCHPADSR, }, @@ -359,6 +600,21 @@ static int nizynqcpld_probe(struct i2c_client *client, cpld->desc = desc; + cpld->leds = kzalloc(sizeof(*cpld->leds) * desc->num_led_descs, + GFP_KERNEL); + if (!cpld->leds) { + err = -ENOMEM; + dev_err(cpld->dev, "could not allocate led state data\n"); + goto err_led_alloc; + } + + for (i = 0; i < desc->num_led_descs; i++) { + err = nizynqcpld_led_register(cpld, &desc->led_descs[i], + &cpld->leds[i]); + if (err) + goto err_led; + } + err = sysfs_create_files(&cpld->dev->kobj, desc->attrs); if (err) { dev_err(cpld->dev, "could not register attrs for device.\n"); @@ -375,6 +631,11 @@ static int nizynqcpld_probe(struct i2c_client *client, sysfs_remove_files(&client->dev.kobj, desc->attrs); err_sysfs_create_files: +err_led: + while (i--) + nizynqcpld_led_unregister(&cpld->leds[i]); + kfree(cpld->leds); +err_led_alloc: err_no_version: err_read_info: kfree(cpld); @@ -386,8 +647,12 @@ static int nizynqcpld_remove(struct i2c_client *client) { struct nizynqcpld *cpld = i2c_get_clientdata(client); struct nizynqcpld_desc *desc = cpld->desc; + int i; sysfs_remove_files(&cpld->dev->kobj, desc->attrs); + for (i = desc->num_led_descs - 1; i; --i) + nizynqcpld_led_unregister(&cpld->leds[i]); + kfree(cpld->leds); kfree(cpld); return 0; } From 3e1e13e2e8bb56cd32150c00a59d35f39e5ab6f2 Mon Sep 17 00:00:00 2001 From: Josh Cartwright Date: Mon, 5 Mar 2012 11:55:13 -0600 Subject: [PATCH 13/83] nizynqcpld: Add reboot support Use the SLCR to reboot the zynq if a reset function is not provided. Signed-off-by: Josh Cartwright Signed-off-by: Nathan Sullivan Acked-by: Jeff Westfahl Acked-by: Joe Hershberger Natinst-ReviewBoard-ID: 90458 --- drivers/misc/nizynqcpld.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/drivers/misc/nizynqcpld.c b/drivers/misc/nizynqcpld.c index 4f5fce3cd72ab..2f881f553b968 100644 --- a/drivers/misc/nizynqcpld.c +++ b/drivers/misc/nizynqcpld.c @@ -15,18 +15,20 @@ #include #include #include +#include #include #include - #define NIZYNQCPLD_VERSION 0x00 #define NIZYNQCPLD_PRODUCT 0x1D +#define PROTO_PROCESSORSTATE 0x01 #define PROTO_SWITCHANDLED 0x04 #define PROTO_ETHERNETLED 0x05 #define PROTO_SCRATCHPADSR 0xFE #define PROTO_SCRATCHPADHR 0xFF +#define DOSX_PROCESSORRESET 0x02 #define DOSX_STATUSLEDSHIFTBYTE1 0x05 #define DOSX_STATUSLEDSHIFTBYTE0 0x06 #define DOSX_LED 0x07 @@ -64,6 +66,7 @@ struct nizynqcpld_desc { u8 supported_product; struct nizynqcpld_led_desc *led_descs; unsigned num_led_descs; + u8 reboot_addr; u8 scratch_hr_addr; u8 scratch_sr_addr; }; @@ -74,6 +77,7 @@ struct nizynqcpld { struct nizynqcpld_led *leds; struct i2c_client *client; struct mutex lock; + struct ni_zynq_board_reset reset; }; static int nizynqcpld_write(struct nizynqcpld *cpld, u8 reg, u8 data); @@ -236,6 +240,14 @@ static int nizynqcpld_read(struct nizynqcpld *cpld, u8 reg, u8 *data) return err == ARRAY_SIZE(msgs) ? 0 : err; } +static void nizynqcpld_reset(struct ni_zynq_board_reset *reset) +{ + struct nizynqcpld *cpld = container_of(reset, struct nizynqcpld, reset); + struct nizynqcpld_desc *desc = cpld->desc; + + nizynqcpld_write(cpld, desc->reboot_addr, 0x80); +} + static inline ssize_t nizynqcpld_scratch_show(struct nizynqcpld *cpld, struct device_attribute *attr, char *buf, u8 reg_addr) @@ -503,6 +515,7 @@ static struct nizynqcpld_desc nizynqcpld_descs[] = { .supported_product = 0, .led_descs = proto_leds, .num_led_descs = ARRAY_SIZE(proto_leds), + .reboot_addr = PROTO_PROCESSORSTATE, .scratch_hr_addr = PROTO_SCRATCHPADHR, .scratch_sr_addr = PROTO_SCRATCHPADSR, }, @@ -513,6 +526,7 @@ static struct nizynqcpld_desc nizynqcpld_descs[] = { .supported_product = 0, .led_descs = dosx_leds, .num_led_descs = ARRAY_SIZE(dosx_leds), + .reboot_addr = DOSX_PROCESSORRESET, .scratch_hr_addr = DOSX_SCRATCHPADHR, .scratch_sr_addr = DOSX_SCRATCHPADSR, }, @@ -523,6 +537,7 @@ static struct nizynqcpld_desc nizynqcpld_descs[] = { .supported_product = 0, .led_descs = dosx_leds, .num_led_descs = ARRAY_SIZE(dosx_leds), + .reboot_addr = DOSX_PROCESSORRESET, .scratch_hr_addr = DOSX_SCRATCHPADHR, .scratch_sr_addr = DOSX_SCRATCHPADSR, }, @@ -533,6 +548,7 @@ static struct nizynqcpld_desc nizynqcpld_descs[] = { .supported_product = 0, .led_descs = dosx_leds, .num_led_descs = ARRAY_SIZE(dosx_leds), + .reboot_addr = DOSX_PROCESSORRESET, .scratch_hr_addr = DOSX_SCRATCHPADHR, .scratch_sr_addr = DOSX_SCRATCHPADSR, }, @@ -543,6 +559,7 @@ static struct nizynqcpld_desc nizynqcpld_descs[] = { .supported_product = 1, .led_descs = dosx_leds, .num_led_descs = ARRAY_SIZE(dosx_leds), + .reboot_addr = DOSX_PROCESSORRESET, .scratch_hr_addr = DOSX_SCRATCHPADHR, .scratch_sr_addr = DOSX_SCRATCHPADSR, }, @@ -621,6 +638,9 @@ static int nizynqcpld_probe(struct i2c_client *client, goto err_sysfs_create_files; } + cpld->reset.reset = nizynqcpld_reset; + ni_zynq_board_reset = &cpld->reset; + i2c_set_clientdata(client, cpld); dev_info(&client->dev, @@ -649,6 +669,8 @@ static int nizynqcpld_remove(struct i2c_client *client) struct nizynqcpld_desc *desc = cpld->desc; int i; + ni_zynq_board_reset = NULL; + sysfs_remove_files(&cpld->dev->kobj, desc->attrs); for (i = desc->num_led_descs - 1; i; --i) nizynqcpld_led_unregister(&cpld->leds[i]); From 277acceb6d56ba7dd468580465ae34de612bb85c Mon Sep 17 00:00:00 2001 From: Josh Cartwright Date: Mon, 20 Aug 2012 17:15:28 -0500 Subject: [PATCH 14/83] nizynqcpld: Add attributes to query switches This will expose the switches as sysfs attributes for consumption by the RT utilities VIs. Signed-off-by: Josh Cartwright --- drivers/misc/nizynqcpld.c | 52 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/drivers/misc/nizynqcpld.c b/drivers/misc/nizynqcpld.c index 2f881f553b968..73e8d08f36d61 100644 --- a/drivers/misc/nizynqcpld.c +++ b/drivers/misc/nizynqcpld.c @@ -33,6 +33,7 @@ #define DOSX_STATUSLEDSHIFTBYTE0 0x06 #define DOSX_LED 0x07 #define DOSX_ETHERNETLED 0x08 +#define DOSX_DEBUGSWITCH 0x09 #define DOSX_SCRATCHPADSR 0x1E #define DOSX_SCRATCHPADHR 0x1F @@ -69,6 +70,7 @@ struct nizynqcpld_desc { u8 reboot_addr; u8 scratch_hr_addr; u8 scratch_sr_addr; + u8 switch_addr; }; struct nizynqcpld { @@ -337,6 +339,45 @@ static DEVICE_ATTR(scratch_softreset, S_IRUSR|S_IWUSR, static DEVICE_ATTR(scratch_hardreset, S_IRUSR|S_IWUSR, nizynqcpld_scratchhr_show, nizynqcpld_scratchhr_store); +struct switch_attribute { + struct device_attribute dev_attr; + u8 bit; +}; + +static inline ssize_t nizynqcpld_switch_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct nizynqcpld *cpld = dev_get_drvdata(dev); + struct nizynqcpld_desc *desc = cpld->desc; + struct switch_attribute *sa = + container_of(attr, struct switch_attribute, dev_attr); + int err; + u8 data; + + nizynqcpld_lock(cpld); + err = nizynqcpld_read(cpld, desc->switch_addr, &data); + nizynqcpld_unlock(cpld); + + if (err) { + dev_err(dev, "Error reading switch state.\n"); + return err; + } + + return sprintf(buf, "%u\n", !!(data & sa->bit)); +} + +#define SWITCH_ATTR(_name, _bit) \ + struct switch_attribute dev_attr_##_name = { \ + .bit = _bit, \ + .dev_attr = \ + __ATTR(_name, 0444, nizynqcpld_switch_show, NULL), \ + } + +static SWITCH_ATTR(console_out, 1 << 7); +static SWITCH_ATTR(ip_reset, 1 << 6); +static SWITCH_ATTR(safe_mode, 1 << 5); + static const char * const bootmode_strings[] = { "runtime", "safemode", "recovery", }; @@ -407,6 +448,9 @@ static const struct attribute *nizynqcpld_attrs[] = { &dev_attr_bootmode.attr, &dev_attr_scratch_softreset.attr, &dev_attr_scratch_hardreset.attr, + &dev_attr_console_out.dev_attr.attr, + &dev_attr_ip_reset.dev_attr.attr, + &dev_attr_safe_mode.dev_attr.attr, NULL }; @@ -414,6 +458,9 @@ static const struct attribute *dosequis6_attrs[] = { &dev_attr_bootmode.attr, &dev_attr_scratch_softreset.attr, &dev_attr_scratch_hardreset.attr, + &dev_attr_console_out.dev_attr.attr, + &dev_attr_ip_reset.dev_attr.attr, + &dev_attr_safe_mode.dev_attr.attr, NULL }; @@ -518,6 +565,7 @@ static struct nizynqcpld_desc nizynqcpld_descs[] = { .reboot_addr = PROTO_PROCESSORSTATE, .scratch_hr_addr = PROTO_SCRATCHPADHR, .scratch_sr_addr = PROTO_SCRATCHPADSR, + .switch_addr = PROTO_SWITCHANDLED, }, /* DosEquis and myRIO development CPLD */ { @@ -529,6 +577,7 @@ static struct nizynqcpld_desc nizynqcpld_descs[] = { .reboot_addr = DOSX_PROCESSORRESET, .scratch_hr_addr = DOSX_SCRATCHPADHR, .scratch_sr_addr = DOSX_SCRATCHPADSR, + .switch_addr = DOSX_DEBUGSWITCH, }, /* DosEquis and myRIO development CPLD */ { @@ -540,6 +589,7 @@ static struct nizynqcpld_desc nizynqcpld_descs[] = { .reboot_addr = DOSX_PROCESSORRESET, .scratch_hr_addr = DOSX_SCRATCHPADHR, .scratch_sr_addr = DOSX_SCRATCHPADSR, + .switch_addr = DOSX_DEBUGSWITCH, }, /* DosEquis CPLD */ { @@ -551,6 +601,7 @@ static struct nizynqcpld_desc nizynqcpld_descs[] = { .reboot_addr = DOSX_PROCESSORRESET, .scratch_hr_addr = DOSX_SCRATCHPADHR, .scratch_sr_addr = DOSX_SCRATCHPADSR, + .switch_addr = DOSX_DEBUGSWITCH, }, /* myRIO CPLD */ { @@ -562,6 +613,7 @@ static struct nizynqcpld_desc nizynqcpld_descs[] = { .reboot_addr = DOSX_PROCESSORRESET, .scratch_hr_addr = DOSX_SCRATCHPADHR, .scratch_sr_addr = DOSX_SCRATCHPADSR, + .switch_addr = DOSX_DEBUGSWITCH, }, }; From ee5b34defeb851d198165c0a7886270b207b5564 Mon Sep 17 00:00:00 2001 From: Jeff Westfahl Date: Tue, 9 Oct 2012 11:42:15 -0500 Subject: [PATCH 15/83] nizynqcpld: Add NI Watchdog support Add support for the Dos Equis CPLD watchdog, implementing the NI Watchdog ioctl interface with a misc device. Signed-off-by: Jeff Westfahl Signed-off-by: Scot Salmon Acked-by: Brad Mouring Acked-by: Josh Cartwright Natinst-ReviewBoard-ID: 36482 --- drivers/misc/nizynqcpld.c | 499 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 499 insertions(+) diff --git a/drivers/misc/nizynqcpld.c b/drivers/misc/nizynqcpld.c index 73e8d08f36d61..9db44e76f9718 100644 --- a/drivers/misc/nizynqcpld.c +++ b/drivers/misc/nizynqcpld.c @@ -11,12 +11,18 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ +#include #include +#include #include +#include #include +#include #include #include +#include #include +#include #include #define NIZYNQCPLD_VERSION 0x00 @@ -34,9 +40,28 @@ #define DOSX_LED 0x07 #define DOSX_ETHERNETLED 0x08 #define DOSX_DEBUGSWITCH 0x09 +#define DOSX_WATCHDOGCONTROL 0x13 +#define DOSX_WATCHDOGCOUNTER2 0x14 +#define DOSX_WATCHDOGCOUNTER1 0x15 +#define DOSX_WATCHDOGCOUNTER0 0x16 +#define DOSX_WATCHDOGSEED2 0x17 +#define DOSX_WATCHDOGSEED1 0x18 +#define DOSX_WATCHDOGSEED0 0x19 #define DOSX_SCRATCHPADSR 0x1E #define DOSX_SCRATCHPADHR 0x1F +#define DOSX_WATCHDOGCONTROL_PROC_INTERRUPT 0x40 +#define DOSX_WATCHDOGCONTROL_PROC_RESET 0x20 +#define DOSX_WATCHDOGCONTROL_ENTER_USER_MODE 0x80 +#define DOSX_WATCHDOGCONTROL_PET 0x10 +#define DOSX_WATCHDOGCONTROL_RUNNING 0x08 +#define DOSX_WATCHDOGCONTROL_CAPTURECOUNTER 0x04 +#define DOSX_WATCHDOGCONTROL_RESET 0x02 +#define DOSX_WATCHDOGCONTROL_ALARM 0x01 + +#define DOSX_WATCHDOG_MAX_COUNTER 0x00FFFFFF +#define DOSX_WATCHDOG_COUNTER_BYTES 3 + struct nizynqcpld_led_desc { const char *name; const char *default_trigger; @@ -61,22 +86,37 @@ struct nizynqcpld_led { #define to_nizynqcpld_led(x) \ container_of(x, struct nizynqcpld_led, cdev) +struct nizynqcpld_watchdog_desc { + u32 watchdog_period_ns; +}; + +struct nizynqcpld_watchdog { + struct miscdevice misc_dev; + struct nizynqcpld_watchdog_desc *desc; + atomic_t available; + wait_queue_head_t irq_event; + bool expired; +}; + struct nizynqcpld_desc { const struct attribute **attrs; u8 supported_version; u8 supported_product; struct nizynqcpld_led_desc *led_descs; unsigned num_led_descs; + struct nizynqcpld_watchdog_desc *watchdog_desc; u8 reboot_addr; u8 scratch_hr_addr; u8 scratch_sr_addr; u8 switch_addr; + u8 watchdog_addr; }; struct nizynqcpld { struct device *dev; struct nizynqcpld_desc *desc; struct nizynqcpld_led *leds; + struct nizynqcpld_watchdog watchdog; struct i2c_client *client; struct mutex lock; struct ni_zynq_board_reset reset; @@ -454,6 +494,51 @@ static const struct attribute *nizynqcpld_attrs[] = { NULL }; +static ssize_t dosequiscpld_wdmode_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct nizynqcpld *cpld = dev_get_drvdata(dev); + struct nizynqcpld_desc *desc = cpld->desc; + int err; + u8 tmp; + + nizynqcpld_lock(cpld); + err = nizynqcpld_read(cpld, desc->watchdog_addr, &tmp); + nizynqcpld_unlock(cpld); + + if (err) + return err; + + /* you write a 1 to the bit to enter user mode, but it reads as a + 0 in user mode for backwards compatibility */ + tmp &= DOSX_WATCHDOGCONTROL_ENTER_USER_MODE; + return sprintf(buf, "%s\n", tmp ? "boot" : "user"); +} + +static ssize_t dosequiscpld_wdmode_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct nizynqcpld *cpld = dev_get_drvdata(dev); + struct nizynqcpld_desc *desc = cpld->desc; + int err; + + /* you can only switch boot->user */ + if (strcmp(buf, "user")) + return -EINVAL; + + nizynqcpld_lock(cpld); + err = nizynqcpld_write(cpld, desc->watchdog_addr, + DOSX_WATCHDOGCONTROL_ENTER_USER_MODE); + nizynqcpld_unlock(cpld); + + return err ?: count; +} + +static DEVICE_ATTR(watchdog_mode, S_IRUSR|S_IWUSR, dosequiscpld_wdmode_show, + dosequiscpld_wdmode_store); + static const struct attribute *dosequis6_attrs[] = { &dev_attr_bootmode.attr, &dev_attr_scratch_softreset.attr, @@ -461,9 +546,386 @@ static const struct attribute *dosequis6_attrs[] = { &dev_attr_console_out.dev_attr.attr, &dev_attr_ip_reset.dev_attr.attr, &dev_attr_safe_mode.dev_attr.attr, + &dev_attr_watchdog_mode.attr, NULL }; +/* + * CPLD Watchdog (only for dosequis) + */ +static int nizynqcpld_watchdog_counter_set(struct nizynqcpld *cpld, u32 counter) +{ + int err; + u8 data[DOSX_WATCHDOG_COUNTER_BYTES]; + + data[0] = ((0x00FF0000 & counter) >> 16); + data[1] = ((0x0000FF00 & counter) >> 8); + data[2] = (0x000000FF & counter); + + nizynqcpld_lock(cpld); + + err = i2c_smbus_write_i2c_block_data(cpld->client, + DOSX_WATCHDOGSEED2, + DOSX_WATCHDOG_COUNTER_BYTES, + data); + nizynqcpld_unlock(cpld); + if (err) + dev_err(cpld->dev, + "Error %d writing watchdog counter.\n", err); + return err; +} + +static int nizynqcpld_watchdog_check_action(u32 action) +{ + int err = 0; + + switch (action) { + case DOSX_WATCHDOGCONTROL_PROC_INTERRUPT: + case DOSX_WATCHDOGCONTROL_PROC_RESET: + break; + default: + err = -ENOTSUPP; + } + + return err; +} + +static int nizynqcpld_watchdog_add_action(struct nizynqcpld *cpld, u32 action) +{ + int err; + u8 action_mask; + u8 control; + + if (NIWATCHDOG_ACTION_INTERRUPT == action) + action_mask = DOSX_WATCHDOGCONTROL_PROC_INTERRUPT; + else if (NIWATCHDOG_ACTION_RESET == action) + action_mask = DOSX_WATCHDOGCONTROL_PROC_RESET; + else + return -ENOTSUPP; + + nizynqcpld_lock(cpld); + + err = nizynqcpld_read(cpld, DOSX_WATCHDOGCONTROL, &control); + + if (err) { + dev_err(cpld->dev, + "Error %d reading watchdog control.\n", err); + goto out_unlock; + } + control |= action_mask; + + err = nizynqcpld_write(cpld, DOSX_WATCHDOGCONTROL, control); + + if (err) { + dev_err(cpld->dev, + "Error %d writing watchdog control.\n", err); + goto out_unlock; + } +out_unlock: + nizynqcpld_unlock(cpld); + return err; +} + +static int nizynqcpld_watchdog_start(struct nizynqcpld *cpld) +{ + int err; + u8 control; + + nizynqcpld_lock(cpld); + + cpld->watchdog.expired = false; + + err = nizynqcpld_read(cpld, DOSX_WATCHDOGCONTROL, &control); + if (err) { + dev_err(cpld->dev, + "Error %d reading watchdog control.\n", err); + goto out_unlock; + } + + err = nizynqcpld_write(cpld, DOSX_WATCHDOGCONTROL, + control | DOSX_WATCHDOGCONTROL_RESET); + if (err) { + dev_err(cpld->dev, + "Error %d writing watchdog control.\n", err); + goto out_unlock; + } + + err = nizynqcpld_write(cpld, DOSX_WATCHDOGCONTROL, + control | DOSX_WATCHDOGCONTROL_PET); + if (err) { + dev_err(cpld->dev, + "Error %d writing watchdog control.\n", err); + goto out_unlock; + } +out_unlock: + nizynqcpld_unlock(cpld); + return err; +} + +static int nizynqcpld_watchdog_pet(struct nizynqcpld *cpld, u32 *state) +{ + int err; + u8 control; + + nizynqcpld_lock(cpld); + + if (cpld->watchdog.expired) { + err = 0; + *state = NIWATCHDOG_STATE_EXPIRED; + } else { + err = nizynqcpld_read(cpld, DOSX_WATCHDOGCONTROL, &control); + if (err) { + dev_err(cpld->dev, + "Error %d reading watchdog control.\n", err); + goto out_unlock; + } + + control |= DOSX_WATCHDOGCONTROL_PET; + + err = nizynqcpld_write(cpld, DOSX_WATCHDOGCONTROL, control); + if (err) { + dev_err(cpld->dev, + "Error %d writing watchdog control.\n", err); + goto out_unlock; + } + + *state = NIWATCHDOG_STATE_RUNNING; + } + +out_unlock: + nizynqcpld_unlock(cpld); + return err; +} + +static int nizynqcpld_watchdog_reset(struct nizynqcpld *cpld) +{ + int err; + + nizynqcpld_lock(cpld); + + cpld->watchdog.expired = false; + + err = nizynqcpld_write(cpld, DOSX_WATCHDOGCONTROL, + DOSX_WATCHDOGCONTROL_RESET); + + nizynqcpld_unlock(cpld); + + if (err) + dev_err(cpld->dev, + "Error %d writing watchdog control.\n", err); + return err; +} + +static int nizynqcpld_watchdog_counter_get(struct nizynqcpld *cpld, + u32 *counter) +{ + int err; + u8 control; + u8 data[DOSX_WATCHDOG_COUNTER_BYTES]; + + nizynqcpld_lock(cpld); + + err = nizynqcpld_read(cpld, DOSX_WATCHDOGCONTROL, &control); + + if (err) { + dev_err(cpld->dev, + "Error %d reading watchdog control.\n", err); + goto out_unlock; + } + + err = nizynqcpld_write(cpld, DOSX_WATCHDOGCONTROL, + control | DOSX_WATCHDOGCONTROL_CAPTURECOUNTER); + if (err) { + dev_err(cpld->dev, + "Error %d capturing watchdog counter.\n", err); + goto out_unlock; + } + + /* Returns the number of read bytes */ + err = i2c_smbus_read_i2c_block_data(cpld->client, + DOSX_WATCHDOGCOUNTER2, + DOSX_WATCHDOG_COUNTER_BYTES, + data); + if (DOSX_WATCHDOG_COUNTER_BYTES == err) + err = 0; + else { + dev_err(cpld->dev, + "Error %d reading watchdog counter.\n", err); + goto out_unlock; + } + + *counter = (data[0] << 16) | (data[1] << 8) | data[2]; + +out_unlock: + nizynqcpld_unlock(cpld); + return err; +} + +static irqreturn_t nizynqcpld_watchdog_irq(int irq, void *data) +{ + struct nizynqcpld *cpld = data; + irqreturn_t ret = IRQ_NONE; + u8 control; + int err; + + nizynqcpld_lock(cpld); + + err = nizynqcpld_read(cpld, DOSX_WATCHDOGCONTROL, &control); + + if (err) { + dev_err(cpld->dev, + "Error %d reading watchdog control.\n", err); + goto out_unlock; + } else if (!(DOSX_WATCHDOGCONTROL_ALARM & control)) { + dev_err(cpld->dev, + "Spurious watchdog interrupt, 0x%02X\n", control); + goto out_unlock; + } + + cpld->watchdog.expired = true; + + /* Acknowledge the interrupt. */ + control |= DOSX_WATCHDOGCONTROL_RESET; + err = nizynqcpld_write(cpld, DOSX_WATCHDOGCONTROL, control); + + /* Signal the watchdog event. */ + wake_up_all(&cpld->watchdog.irq_event); + + ret = IRQ_HANDLED; + +out_unlock: + nizynqcpld_unlock(cpld); + return ret; +} + +static int nizynqcpld_watchdog_misc_open(struct inode *inode, + struct file *file) +{ + struct miscdevice *misc_dev = file->private_data; + struct nizynqcpld *cpld = container_of(misc_dev, struct nizynqcpld, + watchdog.misc_dev); + file->private_data = cpld; + + if (!atomic_dec_and_test(&cpld->watchdog.available)) { + atomic_inc(&cpld->watchdog.available); + return -EBUSY; + } + + return request_threaded_irq(cpld->client->irq, + NULL, nizynqcpld_watchdog_irq, + 0, NIWATCHDOG_NAME, cpld); +} + +static int nizynqcpld_watchdog_misc_release(struct inode *inode, + struct file *file) +{ + struct nizynqcpld *cpld = file->private_data; + free_irq(cpld->client->irq, cpld); + atomic_inc(&cpld->watchdog.available); + return 0; +} + +long nizynqcpld_watchdog_misc_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + struct nizynqcpld *cpld = file->private_data; + struct nizynqcpld_watchdog_desc *desc; + int err; + + desc = cpld->watchdog.desc; + + switch (cmd) { + case NIWATCHDOG_IOCTL_PERIOD_NS: { + __u32 period = desc->watchdog_period_ns; + err = copy_to_user((__u32 *)arg, &period, + sizeof(__u32)); + break; + } + case NIWATCHDOG_IOCTL_MAX_COUNTER: { + __u32 counter = DOSX_WATCHDOG_MAX_COUNTER; + err = copy_to_user((__u32 *)arg, &counter, + sizeof(__u32)); + break; + } + case NIWATCHDOG_IOCTL_COUNTER_SET: { + __u32 counter; + err = copy_from_user(&counter, (__u32 *)arg, + sizeof(__u32)); + if (!err) + err = nizynqcpld_watchdog_counter_set(cpld, counter); + break; + } + case NIWATCHDOG_IOCTL_CHECK_ACTION: { + __u32 action; + err = copy_from_user(&action, (__u32 *)arg, + sizeof(__u32)); + if (!err) + err = nizynqcpld_watchdog_check_action(action); + break; + } + case NIWATCHDOG_IOCTL_ADD_ACTION: { + __u32 action; + err = copy_from_user(&action, (__u32 *)arg, + sizeof(__u32)); + if (!err) + err = nizynqcpld_watchdog_add_action(cpld, action); + break; + } + case NIWATCHDOG_IOCTL_START: { + err = nizynqcpld_watchdog_start(cpld); + break; + } + case NIWATCHDOG_IOCTL_PET: { + __u32 state; + err = nizynqcpld_watchdog_pet(cpld, &state); + if (!err) + err = copy_to_user((__u32 *)arg, &state, + sizeof(__u32)); + break; + } + case NIWATCHDOG_IOCTL_RESET: { + err = nizynqcpld_watchdog_reset(cpld); + break; + } + case NIWATCHDOG_IOCTL_COUNTER_GET: { + __u32 counter; + err = nizynqcpld_watchdog_counter_get(cpld, &counter); + if (!err) { + err = copy_to_user((__u32 *)arg, &counter, + sizeof(__u32)); + } + break; + } + default: + err = -EINVAL; + break; + }; + + return err; +} + +unsigned int nizynqcpld_watchdog_misc_poll(struct file *file, + struct poll_table_struct *wait) +{ + struct nizynqcpld *cpld = file->private_data; + unsigned int mask = 0; + + poll_wait(file, &cpld->watchdog.irq_event, wait); + nizynqcpld_lock(cpld); + if (cpld->watchdog.expired) + mask = POLLIN; + nizynqcpld_unlock(cpld); + return mask; +} + +static const struct file_operations nizynqcpld_watchdog_misc_fops = { + .owner = THIS_MODULE, + .open = nizynqcpld_watchdog_misc_open, + .release = nizynqcpld_watchdog_misc_release, + .unlocked_ioctl = nizynqcpld_watchdog_misc_ioctl, + .poll = nizynqcpld_watchdog_misc_poll, +}; + static struct nizynqcpld_led_desc proto_leds[] = { { .name = "nizynqcpld:user1:green", @@ -554,6 +1016,14 @@ static struct nizynqcpld_led_desc dosx_leds[] = { }, }; +static struct nizynqcpld_watchdog_desc dosxv4_watchdog_desc = { + .watchdog_period_ns = 24000, +}; + +static struct nizynqcpld_watchdog_desc dosxv5_watchdog_desc = { + .watchdog_period_ns = 30720, +}; + static struct nizynqcpld_desc nizynqcpld_descs[] = { /* DosEquis and myRIO development CPLD */ { @@ -572,6 +1042,7 @@ static struct nizynqcpld_desc nizynqcpld_descs[] = { .attrs = nizynqcpld_attrs, .supported_version = 4, .supported_product = 0, + .watchdog_desc = &dosxv4_watchdog_desc, .led_descs = dosx_leds, .num_led_descs = ARRAY_SIZE(dosx_leds), .reboot_addr = DOSX_PROCESSORRESET, @@ -584,6 +1055,7 @@ static struct nizynqcpld_desc nizynqcpld_descs[] = { .attrs = nizynqcpld_attrs, .supported_version = 5, .supported_product = 0, + .watchdog_desc = &dosxv5_watchdog_desc, .led_descs = dosx_leds, .num_led_descs = ARRAY_SIZE(dosx_leds), .reboot_addr = DOSX_PROCESSORRESET, @@ -596,24 +1068,28 @@ static struct nizynqcpld_desc nizynqcpld_descs[] = { .attrs = dosequis6_attrs, .supported_version = 6, .supported_product = 0, + .watchdog_desc = &dosxv5_watchdog_desc, .led_descs = dosx_leds, .num_led_descs = ARRAY_SIZE(dosx_leds), .reboot_addr = DOSX_PROCESSORRESET, .scratch_hr_addr = DOSX_SCRATCHPADHR, .scratch_sr_addr = DOSX_SCRATCHPADSR, .switch_addr = DOSX_DEBUGSWITCH, + .watchdog_addr = DOSX_WATCHDOGCONTROL, }, /* myRIO CPLD */ { .attrs = dosequis6_attrs, .supported_version = 6, .supported_product = 1, + .watchdog_desc = &dosxv5_watchdog_desc, .led_descs = dosx_leds, .num_led_descs = ARRAY_SIZE(dosx_leds), .reboot_addr = DOSX_PROCESSORRESET, .scratch_hr_addr = DOSX_SCRATCHPADHR, .scratch_sr_addr = DOSX_SCRATCHPADSR, .switch_addr = DOSX_DEBUGSWITCH, + .watchdog_addr = DOSX_WATCHDOGCONTROL, }, }; @@ -690,6 +1166,25 @@ static int nizynqcpld_probe(struct i2c_client *client, goto err_sysfs_create_files; } + if (desc->watchdog_desc) { + struct nizynqcpld_watchdog *watchdog = &cpld->watchdog; + + watchdog->desc = desc->watchdog_desc; + atomic_set(&watchdog->available, 1); + init_waitqueue_head(&watchdog->irq_event); + watchdog->expired = false; + + watchdog->misc_dev.minor = MISC_DYNAMIC_MINOR; + watchdog->misc_dev.name = NIWATCHDOG_NAME; + watchdog->misc_dev.fops = &nizynqcpld_watchdog_misc_fops; + err = misc_register(&watchdog->misc_dev); + if (err) { + dev_err(cpld->dev, + "Couldn't register misc device\n"); + goto err_watchdog_register; + } + } + cpld->reset.reset = nizynqcpld_reset; ni_zynq_board_reset = &cpld->reset; @@ -701,6 +1196,7 @@ static int nizynqcpld_probe(struct i2c_client *client, return 0; +err_watchdog_register: sysfs_remove_files(&client->dev.kobj, desc->attrs); err_sysfs_create_files: err_led: @@ -723,6 +1219,9 @@ static int nizynqcpld_remove(struct i2c_client *client) ni_zynq_board_reset = NULL; + if (desc->watchdog_desc) + misc_deregister(&cpld->watchdog.misc_dev); + sysfs_remove_files(&cpld->dev->kobj, desc->attrs); for (i = desc->num_led_descs - 1; i; --i) nizynqcpld_led_unregister(&cpld->leds[i]); From a92d65b7bb0d693bc2186d09337981fb93012957 Mon Sep 17 00:00:00 2001 From: Ioan Cornea Date: Thu, 17 Oct 2013 14:47:41 +0300 Subject: [PATCH 16/83] nizynqcpld: Add support for wifi button on myRIO Signed-off-by: Ioan Cornea --- drivers/misc/nizynqcpld.c | 174 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 174 insertions(+) diff --git a/drivers/misc/nizynqcpld.c b/drivers/misc/nizynqcpld.c index 9db44e76f9718..ba8186d6d0a1d 100644 --- a/drivers/misc/nizynqcpld.c +++ b/drivers/misc/nizynqcpld.c @@ -24,6 +24,8 @@ #include #include #include +#include +#include #define NIZYNQCPLD_VERSION 0x00 #define NIZYNQCPLD_PRODUCT 0x1D @@ -62,6 +64,13 @@ #define DOSX_WATCHDOG_MAX_COUNTER 0x00FFFFFF #define DOSX_WATCHDOG_COUNTER_BYTES 3 +#define MYRIO_WIFISWCTRL_ADDR 0x0A +#define MYRIO_WIFISWCTRL_STATE 0x01 +#define MYRIO_WIFISWCTRL_ENPUSHIRQ 0x08 +#define MYRIO_WIFISWCTRL_PUSHIRQ 0x80 +#define MYRIO_WIFISWCTRL_ENRELIRQ 0x04 +#define MYRIO_WIFISWCTRL_RELIRQ 0x40 + struct nizynqcpld_led_desc { const char *name; const char *default_trigger; @@ -98,6 +107,13 @@ struct nizynqcpld_watchdog { bool expired; }; +struct myrio_wifi_sw { + struct input_dev *idev; + struct work_struct deferred_work; + bool irq_registered; + int irq; +}; + struct nizynqcpld_desc { const struct attribute **attrs; u8 supported_version; @@ -110,6 +126,7 @@ struct nizynqcpld_desc { u8 scratch_sr_addr; u8 switch_addr; u8 watchdog_addr; + u8 wifi_sw_addr; }; struct nizynqcpld { @@ -120,6 +137,7 @@ struct nizynqcpld { struct i2c_client *client; struct mutex lock; struct ni_zynq_board_reset reset; + struct myrio_wifi_sw wifi_sw; }; static int nizynqcpld_write(struct nizynqcpld *cpld, u8 reg, u8 data); @@ -1090,9 +1108,158 @@ static struct nizynqcpld_desc nizynqcpld_descs[] = { .scratch_sr_addr = DOSX_SCRATCHPADSR, .switch_addr = DOSX_DEBUGSWITCH, .watchdog_addr = DOSX_WATCHDOGCONTROL, + .wifi_sw_addr = MYRIO_WIFISWCTRL_ADDR, }, }; +static void wifi_sw_work_func(struct work_struct *work) +{ + struct myrio_wifi_sw *wifi_sw = + container_of(work, struct myrio_wifi_sw, deferred_work); + struct nizynqcpld *cpld = + container_of(wifi_sw, struct nizynqcpld, wifi_sw); + u8 data; + int err; + + nizynqcpld_lock(cpld); + err = nizynqcpld_read(cpld, cpld->desc->wifi_sw_addr, &data); + nizynqcpld_unlock(cpld); + + if (err) { + dev_err(&cpld->client->dev, + "error %d reading wifi_sw control register\n", err); + return; + } + + /* check the interrupt flags and clear them */ + if (data & (MYRIO_WIFISWCTRL_PUSHIRQ | MYRIO_WIFISWCTRL_RELIRQ)) { + nizynqcpld_lock(cpld); + err = nizynqcpld_write(cpld, cpld->desc->wifi_sw_addr, data); + nizynqcpld_unlock(cpld); + + if (err) { + dev_err(&cpld->client->dev, + "err %d clearing wifi_sw irq flag\n", err); + return; + } + } + + input_event(wifi_sw->idev, + EV_KEY, BTN_0, !!(data & MYRIO_WIFISWCTRL_STATE)); + input_sync(wifi_sw->idev); +} + +static irqreturn_t wifi_sw_hnd(int irq, void *irq_data) +{ + struct myrio_wifi_sw *wifi_sw = (struct myrio_wifi_sw *)irq_data; + schedule_work(&wifi_sw->deferred_work); + + return IRQ_HANDLED; +} + +static int wifi_sw_open(struct input_dev *dev) +{ + int err; + struct myrio_wifi_sw *wifi_sw = input_get_drvdata(dev); + struct nizynqcpld *cpld = + container_of(wifi_sw, struct nizynqcpld, wifi_sw); + + err = request_threaded_irq(wifi_sw->irq, + NULL, wifi_sw_hnd, 0, "wifi_sw", wifi_sw); + if (err) { + dev_err(&cpld->client->dev, + "error %d registering irq handle for wifi_sw\n", err); + } + + wifi_sw->irq_registered = !err; + return err; +} + +static void wifi_sw_close(struct input_dev *dev) +{ + struct myrio_wifi_sw *wifi_sw = input_get_drvdata(dev); + + if (wifi_sw->irq_registered) + free_irq(wifi_sw->irq, wifi_sw_hnd); +} + +static int myrio_wifi_sw_init(struct nizynqcpld *cpld) +{ + u8 data; + int err = 0; + struct input_dev *input; + + if (!cpld->desc->wifi_sw_addr) + goto wifi_sw_init_exit; + + INIT_WORK(&cpld->wifi_sw.deferred_work, wifi_sw_work_func); + cpld->wifi_sw.irq = irq_of_parse_and_map(cpld->client->dev.of_node, 1); + + /* ensure that the interrupt was mapped */ + if (!cpld->wifi_sw.irq) + goto wifi_sw_init_exit; + + /* enable interrupts */ + nizynqcpld_lock(cpld); + err = nizynqcpld_read(cpld, cpld->desc->wifi_sw_addr, &data); + + if (!err) { + data |= (MYRIO_WIFISWCTRL_ENPUSHIRQ | + MYRIO_WIFISWCTRL_ENRELIRQ); + err = nizynqcpld_write(cpld, cpld->desc->wifi_sw_addr, data); + } + nizynqcpld_unlock(cpld); + + if (err) { + dev_err(&cpld->client->dev, + "error %d enabling wifi_sw irq\n", err); + goto wifi_sw_init_exit; + } + + input = input_allocate_device(); + cpld->wifi_sw.idev = input; + + if (!input) { + dev_err(&cpld->client->dev, + "error %d allocating input device for wifi_sw\n", err); + goto wifi_sw_init_exit; + } + + input->name = "wifi_btn"; + input->phys = "wifi_btn/wifibtn"; + input->open = wifi_sw_open; + input->close = wifi_sw_close; + input_set_capability(input, EV_KEY, BTN_0); + input_set_drvdata(input, &cpld->wifi_sw); + + err = input_register_device(cpld->wifi_sw.idev); + + /* report initial state */ + wifi_sw_work_func(&cpld->wifi_sw.deferred_work); + + if (err) { + dev_err(&cpld->client->dev, + "error %d registering input device for wifi_sw\n", err); + goto wifi_sw_init_exit_register; + } + + return err; + +wifi_sw_init_exit_register: + input_free_device(cpld->wifi_sw.idev); + +wifi_sw_init_exit: + return err; +} + +static void myrio_wifi_sw_uninit(struct nizynqcpld *cpld) +{ + if (cpld->desc->wifi_sw_addr) { + input_unregister_device(cpld->wifi_sw.idev); + input_free_device(cpld->wifi_sw.idev); + } +} + static int nizynqcpld_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -1160,6 +1327,9 @@ static int nizynqcpld_probe(struct i2c_client *client, goto err_led; } + /* don't care about errors */ + myrio_wifi_sw_init(cpld); + err = sysfs_create_files(&cpld->dev->kobj, desc->attrs); if (err) { dev_err(cpld->dev, "could not register attrs for device.\n"); @@ -1199,6 +1369,7 @@ static int nizynqcpld_probe(struct i2c_client *client, err_watchdog_register: sysfs_remove_files(&client->dev.kobj, desc->attrs); err_sysfs_create_files: + myrio_wifi_sw_uninit(cpld); err_led: while (i--) nizynqcpld_led_unregister(&cpld->leds[i]); @@ -1226,6 +1397,9 @@ static int nizynqcpld_remove(struct i2c_client *client) for (i = desc->num_led_descs - 1; i; --i) nizynqcpld_led_unregister(&cpld->leds[i]); kfree(cpld->leds); + + myrio_wifi_sw_uninit(cpld); + kfree(cpld); return 0; } From e85181e5a440b60adb74861804899cab0ed78a43 Mon Sep 17 00:00:00 2001 From: Keng Soon Cheah Date: Wed, 28 Aug 2013 12:20:20 +0800 Subject: [PATCH 17/83] nizynqcpld: Add cRIO-906[6,7] CPLD support cRIO-906[6,7] (Sol) CPLD requires new driver support since it has a new version number. Also, the red and yellow LEDs and wifi LEDs are not supported. Signed-off-by: Keng Soon Cheah --- drivers/misc/nizynqcpld.c | 55 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/drivers/misc/nizynqcpld.c b/drivers/misc/nizynqcpld.c index ba8186d6d0a1d..824cb638ed527 100644 --- a/drivers/misc/nizynqcpld.c +++ b/drivers/misc/nizynqcpld.c @@ -1034,6 +1034,47 @@ static struct nizynqcpld_led_desc dosx_leds[] = { }, }; +static struct nizynqcpld_led_desc sol_leds[] = { + { + .name = "nizynqcpld:user1:green", + .addr = DOSX_LED, + .bit = 1 << 5, + }, + { + .name = "nizynqcpld:status:yellow", + .addr = DOSX_LED, + .bit = 1 << 2, + .pattern_lo_addr = DOSX_STATUSLEDSHIFTBYTE0, + /* write byte 1 first */ + .pattern_hi_addr = DOSX_STATUSLEDSHIFTBYTE1, + .max_brightness = 0xffff, + }, + { + .name = "nizynqcpld:eth1:green", + .addr = DOSX_ETHERNETLED, + .bit = 1 << 3, + .default_trigger = "e000b000:01:100Mb", + }, + { + .name = "nizynqcpld:eth1:yellow", + .addr = DOSX_ETHERNETLED, + .bit = 1 << 2, + .default_trigger = "e000b000:01:Gb", + }, + { + .name = "nizynqcpld:eth0:green", + .addr = DOSX_ETHERNETLED, + .bit = 1 << 1, + .default_trigger = "e000b000:00:100Mb", + }, + { + .name = "nizynqcpld:eth0:yellow", + .addr = DOSX_ETHERNETLED, + .bit = 1 << 0, + .default_trigger = "e000b000:00:Gb", + }, +}; + static struct nizynqcpld_watchdog_desc dosxv4_watchdog_desc = { .watchdog_period_ns = 24000, }; @@ -1110,6 +1151,20 @@ static struct nizynqcpld_desc nizynqcpld_descs[] = { .watchdog_addr = DOSX_WATCHDOGCONTROL, .wifi_sw_addr = MYRIO_WIFISWCTRL_ADDR, }, + /* Sol CPLD */ + { + .attrs = dosequis6_attrs, + .supported_version = 1, + .supported_product = 3, + .watchdog_desc = &dosxv5_watchdog_desc, + .led_descs = sol_leds, + .num_led_descs = ARRAY_SIZE(sol_leds), + .reboot_addr = DOSX_PROCESSORRESET, + .scratch_hr_addr = DOSX_SCRATCHPADHR, + .scratch_sr_addr = DOSX_SCRATCHPADSR, + .switch_addr = DOSX_DEBUGSWITCH, + .watchdog_addr = DOSX_WATCHDOGCONTROL, + }, }; static void wifi_sw_work_func(struct work_struct *work) From b8f7df0dba9cb1e84309bab717789c6dff7b4004 Mon Sep 17 00:00:00 2001 From: Jaeden Amero Date: Thu, 17 Oct 2013 14:55:57 -0500 Subject: [PATCH 18/83] nizynqcpld: Add Tecate CPLD support Add support for Tecate sbRIO to the CPLD by adding it to the list of CPLDs. It uses Sol-style LEDs. Signed-off-by: Jaeden Amero --- drivers/misc/nizynqcpld.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/misc/nizynqcpld.c b/drivers/misc/nizynqcpld.c index 824cb638ed527..70f3a1ca0f8cc 100644 --- a/drivers/misc/nizynqcpld.c +++ b/drivers/misc/nizynqcpld.c @@ -1151,6 +1151,20 @@ static struct nizynqcpld_desc nizynqcpld_descs[] = { .watchdog_addr = DOSX_WATCHDOGCONTROL, .wifi_sw_addr = MYRIO_WIFISWCTRL_ADDR, }, + /* Tecate */ + { + .attrs = dosequis6_attrs, + .supported_version = 1, + .supported_product = 2, + .watchdog_desc = &dosxv5_watchdog_desc, + .led_descs = sol_leds, + .num_led_descs = ARRAY_SIZE(sol_leds), + .reboot_addr = DOSX_PROCESSORRESET, + .scratch_hr_addr = DOSX_SCRATCHPADHR, + .scratch_sr_addr = DOSX_SCRATCHPADSR, + .switch_addr = DOSX_DEBUGSWITCH, + .watchdog_addr = DOSX_WATCHDOGCONTROL, + }, /* Sol CPLD */ { .attrs = dosequis6_attrs, From f64f8a4cf7b1412655f679fd2920474bf2aa1883 Mon Sep 17 00:00:00 2001 From: Jeff Westfahl Date: Fri, 24 Jan 2014 17:11:54 -0600 Subject: [PATCH 19/83] nizynqcpld: clean up tecate LEDs The CPLD driver is not used to control link speed LEDs for eth1 on Tecate. Signed-off-by: Jeff Westfahl Acked-by: Jaeden Amero --- drivers/misc/nizynqcpld.c | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/drivers/misc/nizynqcpld.c b/drivers/misc/nizynqcpld.c index 70f3a1ca0f8cc..c22264f7f8027 100644 --- a/drivers/misc/nizynqcpld.c +++ b/drivers/misc/nizynqcpld.c @@ -1075,6 +1075,35 @@ static struct nizynqcpld_led_desc sol_leds[] = { }, }; +static struct nizynqcpld_led_desc tecate_leds[] = { + { + .name = "nizynqcpld:user1:green", + .addr = DOSX_LED, + .bit = 1 << 5, + }, + { + .name = "nizynqcpld:status:yellow", + .addr = DOSX_LED, + .bit = 1 << 2, + .pattern_lo_addr = DOSX_STATUSLEDSHIFTBYTE0, + /* write byte 1 first */ + .pattern_hi_addr = DOSX_STATUSLEDSHIFTBYTE1, + .max_brightness = 0xffff, + }, + { + .name = "nizynqcpld:eth0:green", + .addr = DOSX_ETHERNETLED, + .bit = 1 << 1, + .default_trigger = "e000b000:00:100Mb", + }, + { + .name = "nizynqcpld:eth0:yellow", + .addr = DOSX_ETHERNETLED, + .bit = 1 << 0, + .default_trigger = "e000b000:00:Gb", + }, +}; + static struct nizynqcpld_watchdog_desc dosxv4_watchdog_desc = { .watchdog_period_ns = 24000, }; @@ -1157,8 +1186,8 @@ static struct nizynqcpld_desc nizynqcpld_descs[] = { .supported_version = 1, .supported_product = 2, .watchdog_desc = &dosxv5_watchdog_desc, - .led_descs = sol_leds, - .num_led_descs = ARRAY_SIZE(sol_leds), + .led_descs = tecate_leds, + .num_led_descs = ARRAY_SIZE(tecate_leds), .reboot_addr = DOSX_PROCESSORRESET, .scratch_hr_addr = DOSX_SCRATCHPADHR, .scratch_sr_addr = DOSX_SCRATCHPADSR, From 84d3c975fe9016650ffb530e109bfc103c27fa3a Mon Sep 17 00:00:00 2001 From: Joe Hershberger Date: Thu, 20 Feb 2014 16:30:46 -0600 Subject: [PATCH 20/83] nizynqcpld: Use correct register to detect switches The safemode, ipreset, and consoleout switches were being read from the DebugSwitchReg, which only represents the jumpers and not the reset button. Also, on targets like myRIO and Sol, the bitfields in that register changed from 0xE0 to 0x07. The bitfields in the ProcessorMode register have never changed and represent the actual state used by the bootloader. Use it here too. Signed-off-by: Joe Hershberger --- drivers/misc/nizynqcpld.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/misc/nizynqcpld.c b/drivers/misc/nizynqcpld.c index c22264f7f8027..88405beda978a 100644 --- a/drivers/misc/nizynqcpld.c +++ b/drivers/misc/nizynqcpld.c @@ -30,7 +30,7 @@ #define NIZYNQCPLD_VERSION 0x00 #define NIZYNQCPLD_PRODUCT 0x1D -#define PROTO_PROCESSORSTATE 0x01 +#define PROTO_PROCESSORMODE 0x01 #define PROTO_SWITCHANDLED 0x04 #define PROTO_ETHERNETLED 0x05 #define PROTO_SCRATCHPADSR 0xFE @@ -432,9 +432,9 @@ static inline ssize_t nizynqcpld_switch_show(struct device *dev, __ATTR(_name, 0444, nizynqcpld_switch_show, NULL), \ } -static SWITCH_ATTR(console_out, 1 << 7); -static SWITCH_ATTR(ip_reset, 1 << 6); -static SWITCH_ATTR(safe_mode, 1 << 5); +static SWITCH_ATTR(console_out, 1 << 2); +static SWITCH_ATTR(ip_reset, 1 << 1); +static SWITCH_ATTR(safe_mode, 1 << 0); static const char * const bootmode_strings[] = { "runtime", "safemode", "recovery", @@ -1120,10 +1120,10 @@ static struct nizynqcpld_desc nizynqcpld_descs[] = { .supported_product = 0, .led_descs = proto_leds, .num_led_descs = ARRAY_SIZE(proto_leds), - .reboot_addr = PROTO_PROCESSORSTATE, + .reboot_addr = PROTO_PROCESSORMODE, .scratch_hr_addr = PROTO_SCRATCHPADHR, .scratch_sr_addr = PROTO_SCRATCHPADSR, - .switch_addr = PROTO_SWITCHANDLED, + .switch_addr = PROTO_PROCESSORMODE, }, /* DosEquis and myRIO development CPLD */ { @@ -1136,7 +1136,7 @@ static struct nizynqcpld_desc nizynqcpld_descs[] = { .reboot_addr = DOSX_PROCESSORRESET, .scratch_hr_addr = DOSX_SCRATCHPADHR, .scratch_sr_addr = DOSX_SCRATCHPADSR, - .switch_addr = DOSX_DEBUGSWITCH, + .switch_addr = PROTO_PROCESSORMODE, }, /* DosEquis and myRIO development CPLD */ { @@ -1149,7 +1149,7 @@ static struct nizynqcpld_desc nizynqcpld_descs[] = { .reboot_addr = DOSX_PROCESSORRESET, .scratch_hr_addr = DOSX_SCRATCHPADHR, .scratch_sr_addr = DOSX_SCRATCHPADSR, - .switch_addr = DOSX_DEBUGSWITCH, + .switch_addr = PROTO_PROCESSORMODE, }, /* DosEquis CPLD */ { @@ -1162,7 +1162,7 @@ static struct nizynqcpld_desc nizynqcpld_descs[] = { .reboot_addr = DOSX_PROCESSORRESET, .scratch_hr_addr = DOSX_SCRATCHPADHR, .scratch_sr_addr = DOSX_SCRATCHPADSR, - .switch_addr = DOSX_DEBUGSWITCH, + .switch_addr = PROTO_PROCESSORMODE, .watchdog_addr = DOSX_WATCHDOGCONTROL, }, /* myRIO CPLD */ @@ -1176,7 +1176,7 @@ static struct nizynqcpld_desc nizynqcpld_descs[] = { .reboot_addr = DOSX_PROCESSORRESET, .scratch_hr_addr = DOSX_SCRATCHPADHR, .scratch_sr_addr = DOSX_SCRATCHPADSR, - .switch_addr = DOSX_DEBUGSWITCH, + .switch_addr = PROTO_PROCESSORMODE, .watchdog_addr = DOSX_WATCHDOGCONTROL, .wifi_sw_addr = MYRIO_WIFISWCTRL_ADDR, }, @@ -1191,7 +1191,7 @@ static struct nizynqcpld_desc nizynqcpld_descs[] = { .reboot_addr = DOSX_PROCESSORRESET, .scratch_hr_addr = DOSX_SCRATCHPADHR, .scratch_sr_addr = DOSX_SCRATCHPADSR, - .switch_addr = DOSX_DEBUGSWITCH, + .switch_addr = PROTO_PROCESSORMODE, .watchdog_addr = DOSX_WATCHDOGCONTROL, }, /* Sol CPLD */ @@ -1205,7 +1205,7 @@ static struct nizynqcpld_desc nizynqcpld_descs[] = { .reboot_addr = DOSX_PROCESSORRESET, .scratch_hr_addr = DOSX_SCRATCHPADHR, .scratch_sr_addr = DOSX_SCRATCHPADSR, - .switch_addr = DOSX_DEBUGSWITCH, + .switch_addr = PROTO_PROCESSORMODE, .watchdog_addr = DOSX_WATCHDOGCONTROL, }, }; From 56383ac0de986f8b90ba441860ba898cd02216da Mon Sep 17 00:00:00 2001 From: Joe Hershberger Date: Thu, 20 Feb 2014 16:35:05 -0600 Subject: [PATCH 21/83] nizynqcpld: Add support for reading soft-reset state Expose this information to the scripts in Linux. Signed-off-by: Joe Hershberger --- drivers/misc/nizynqcpld.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/misc/nizynqcpld.c b/drivers/misc/nizynqcpld.c index 88405beda978a..416500d6e1110 100644 --- a/drivers/misc/nizynqcpld.c +++ b/drivers/misc/nizynqcpld.c @@ -432,6 +432,7 @@ static inline ssize_t nizynqcpld_switch_show(struct device *dev, __ATTR(_name, 0444, nizynqcpld_switch_show, NULL), \ } +static SWITCH_ATTR(soft_reset, 1 << 5); static SWITCH_ATTR(console_out, 1 << 2); static SWITCH_ATTR(ip_reset, 1 << 1); static SWITCH_ATTR(safe_mode, 1 << 0); @@ -506,6 +507,7 @@ static const struct attribute *nizynqcpld_attrs[] = { &dev_attr_bootmode.attr, &dev_attr_scratch_softreset.attr, &dev_attr_scratch_hardreset.attr, + &dev_attr_soft_reset.dev_attr.attr, &dev_attr_console_out.dev_attr.attr, &dev_attr_ip_reset.dev_attr.attr, &dev_attr_safe_mode.dev_attr.attr, @@ -561,6 +563,7 @@ static const struct attribute *dosequis6_attrs[] = { &dev_attr_bootmode.attr, &dev_attr_scratch_softreset.attr, &dev_attr_scratch_hardreset.attr, + &dev_attr_soft_reset.dev_attr.attr, &dev_attr_console_out.dev_attr.attr, &dev_attr_ip_reset.dev_attr.attr, &dev_attr_safe_mode.dev_attr.attr, From 374739f80e1caeb02b5a345ffe62b015e7e97a50 Mon Sep 17 00:00:00 2001 From: Joe Hershberger Date: Thu, 20 Feb 2014 17:18:33 -0600 Subject: [PATCH 22/83] nizynqcpld: Expose power status to user-mode Some customers care about the status of the backup power source on the chassis that support it (so far only Dos Equis). Signed-off-by: Joe Hershberger --- drivers/misc/nizynqcpld.c | 72 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 69 insertions(+), 3 deletions(-) diff --git a/drivers/misc/nizynqcpld.c b/drivers/misc/nizynqcpld.c index 416500d6e1110..6e1569dddfc63 100644 --- a/drivers/misc/nizynqcpld.c +++ b/drivers/misc/nizynqcpld.c @@ -42,6 +42,7 @@ #define DOSX_LED 0x07 #define DOSX_ETHERNETLED 0x08 #define DOSX_DEBUGSWITCH 0x09 +#define DOSX_POWERSTATUS 0x0C #define DOSX_WATCHDOGCONTROL 0x13 #define DOSX_WATCHDOGCOUNTER2 0x14 #define DOSX_WATCHDOGCOUNTER1 0x15 @@ -503,6 +504,57 @@ static ssize_t nizynqcpld_bootmode_store(struct device *dev, static DEVICE_ATTR(bootmode, S_IRUSR|S_IWUSR, nizynqcpld_bootmode_show, nizynqcpld_bootmode_store); + +struct powerstatus_attribute { + struct device_attribute dev_attr; + u8 bit; +}; + +static inline ssize_t nizynqcpld_powerstatus_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct nizynqcpld *cpld = dev_get_drvdata(dev); + struct powerstatus_attribute *pa = + container_of(attr, struct powerstatus_attribute, dev_attr); + int err; + u8 data; + + nizynqcpld_lock(cpld); + err = nizynqcpld_read(cpld, DOSX_POWERSTATUS, &data); + nizynqcpld_unlock(cpld); + + if (err) { + dev_err(dev, "Error reading power status.\n"); + return err; + } + + return sprintf(buf, "%u\n", !!(data & pa->bit)); +} + +#define POWERSTATUS_ATTR(_name,_bit) \ + struct powerstatus_attribute dev_attr_##_name = { \ + .bit = _bit, \ + .dev_attr = \ + __ATTR(_name, 0444, nizynqcpld_powerstatus_show, NULL), \ + } + +static POWERSTATUS_ATTR(pwr_aux_valid, 1 << 4); +static POWERSTATUS_ATTR(pwr_primary_in_use, 1 << 0); + +static const struct attribute *nizynqcpld_pwr_attrs[] = { + &dev_attr_bootmode.attr, + &dev_attr_scratch_softreset.attr, + &dev_attr_scratch_hardreset.attr, + &dev_attr_soft_reset.dev_attr.attr, + &dev_attr_console_out.dev_attr.attr, + &dev_attr_ip_reset.dev_attr.attr, + &dev_attr_safe_mode.dev_attr.attr, + &dev_attr_pwr_aux_valid.dev_attr.attr, + &dev_attr_pwr_primary_in_use.dev_attr.attr, + NULL +}; + static const struct attribute *nizynqcpld_attrs[] = { &dev_attr_bootmode.attr, &dev_attr_scratch_softreset.attr, @@ -559,6 +611,20 @@ static ssize_t dosequiscpld_wdmode_store(struct device *dev, static DEVICE_ATTR(watchdog_mode, S_IRUSR|S_IWUSR, dosequiscpld_wdmode_show, dosequiscpld_wdmode_store); +static const struct attribute *dosequis6_pwr_attrs[] = { + &dev_attr_bootmode.attr, + &dev_attr_scratch_softreset.attr, + &dev_attr_scratch_hardreset.attr, + &dev_attr_soft_reset.dev_attr.attr, + &dev_attr_console_out.dev_attr.attr, + &dev_attr_ip_reset.dev_attr.attr, + &dev_attr_safe_mode.dev_attr.attr, + &dev_attr_watchdog_mode.attr, + &dev_attr_pwr_aux_valid.dev_attr.attr, + &dev_attr_pwr_primary_in_use.dev_attr.attr, + NULL +}; + static const struct attribute *dosequis6_attrs[] = { &dev_attr_bootmode.attr, &dev_attr_scratch_softreset.attr, @@ -1130,7 +1196,7 @@ static struct nizynqcpld_desc nizynqcpld_descs[] = { }, /* DosEquis and myRIO development CPLD */ { - .attrs = nizynqcpld_attrs, + .attrs = nizynqcpld_pwr_attrs, .supported_version = 4, .supported_product = 0, .watchdog_desc = &dosxv4_watchdog_desc, @@ -1143,7 +1209,7 @@ static struct nizynqcpld_desc nizynqcpld_descs[] = { }, /* DosEquis and myRIO development CPLD */ { - .attrs = nizynqcpld_attrs, + .attrs = nizynqcpld_pwr_attrs, .supported_version = 5, .supported_product = 0, .watchdog_desc = &dosxv5_watchdog_desc, @@ -1156,7 +1222,7 @@ static struct nizynqcpld_desc nizynqcpld_descs[] = { }, /* DosEquis CPLD */ { - .attrs = dosequis6_attrs, + .attrs = dosequis6_pwr_attrs, .supported_version = 6, .supported_product = 0, .watchdog_desc = &dosxv5_watchdog_desc, From 04cfa97cfe52023a4d0774b1661443ed06b16e22 Mon Sep 17 00:00:00 2001 From: Joe Hershberger Date: Thu, 20 Feb 2014 18:02:43 -0600 Subject: [PATCH 23/83] nizynqcpld: Replace recovery boot mode with install We do not actually support recovery-mode, so replace that bit with install-mode The boot loader only checks that the first 2 bits == 0x1 for safe-mode. Otherwise it boots to runmode. Signed-off-by: Joe Hershberger --- drivers/misc/nizynqcpld.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/misc/nizynqcpld.c b/drivers/misc/nizynqcpld.c index 6e1569dddfc63..ed33ecfb8f19a 100644 --- a/drivers/misc/nizynqcpld.c +++ b/drivers/misc/nizynqcpld.c @@ -439,7 +439,7 @@ static SWITCH_ATTR(ip_reset, 1 << 1); static SWITCH_ATTR(safe_mode, 1 << 0); static const char * const bootmode_strings[] = { - "runtime", "safemode", "recovery", + "runtime", "safemode", "install", }; static ssize_t nizynqcpld_bootmode_show(struct device *dev, From 5eeaeccae1af6cb494958002fce69c99fcf1d219 Mon Sep 17 00:00:00 2001 From: Joe Hershberger Date: Fri, 21 Feb 2014 00:57:36 -0600 Subject: [PATCH 24/83] nizynqcpld: Add attribute for reset source Safe-mode will need to know the reset source Signed-off-by: Joe Hershberger --- drivers/misc/nizynqcpld.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/drivers/misc/nizynqcpld.c b/drivers/misc/nizynqcpld.c index ed33ecfb8f19a..9797814bcb2c7 100644 --- a/drivers/misc/nizynqcpld.c +++ b/drivers/misc/nizynqcpld.c @@ -37,6 +37,7 @@ #define PROTO_SCRATCHPADHR 0xFF #define DOSX_PROCESSORRESET 0x02 +#define DOSX_PROCRESETSOURCE 0x04 #define DOSX_STATUSLEDSHIFTBYTE1 0x05 #define DOSX_STATUSLEDSHIFTBYTE0 0x06 #define DOSX_LED 0x07 @@ -611,6 +612,38 @@ static ssize_t dosequiscpld_wdmode_store(struct device *dev, static DEVICE_ATTR(watchdog_mode, S_IRUSR|S_IWUSR, dosequiscpld_wdmode_show, dosequiscpld_wdmode_store); + +static const char * const resetsource_strings[] = { + "button", "processor", "fpga", "watchdog", "software", "softoff", +}; + +static ssize_t nizynqcpld_resetsource_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct nizynqcpld *cpld = dev_get_drvdata(dev); + int err; + u8 tmp; + int i; + + nizynqcpld_lock(cpld); + err = nizynqcpld_read(cpld, DOSX_PROCRESETSOURCE, &tmp); + nizynqcpld_unlock(cpld); + + if (err) + return err; + + for (i = 0; i < ARRAY_SIZE(resetsource_strings); i++) { + if ((1 << i) & tmp) + return sprintf(buf, "%s\n", resetsource_strings[i]); + } + + return sprintf(buf, "poweron\n"); +} + +static DEVICE_ATTR(reset_source, S_IRUSR, nizynqcpld_resetsource_show, NULL); + + static const struct attribute *dosequis6_pwr_attrs[] = { &dev_attr_bootmode.attr, &dev_attr_scratch_softreset.attr, @@ -620,6 +653,7 @@ static const struct attribute *dosequis6_pwr_attrs[] = { &dev_attr_ip_reset.dev_attr.attr, &dev_attr_safe_mode.dev_attr.attr, &dev_attr_watchdog_mode.attr, + &dev_attr_reset_source.attr, &dev_attr_pwr_aux_valid.dev_attr.attr, &dev_attr_pwr_primary_in_use.dev_attr.attr, NULL @@ -634,6 +668,7 @@ static const struct attribute *dosequis6_attrs[] = { &dev_attr_ip_reset.dev_attr.attr, &dev_attr_safe_mode.dev_attr.attr, &dev_attr_watchdog_mode.attr, + &dev_attr_reset_source.attr, NULL }; From 28cfab3fcbe246bb8faead17e340777269843dba Mon Sep 17 00:00:00 2001 From: Jeff Westfahl Date: Mon, 24 Feb 2014 08:45:49 -0600 Subject: [PATCH 25/83] nizynqcpld: Change LED prefix to "nilrt" Signed-off-by: Jeff Westfahl Natinst-CAR-ID: 452296 --- drivers/misc/nizynqcpld.c | 50 +++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/drivers/misc/nizynqcpld.c b/drivers/misc/nizynqcpld.c index 9797814bcb2c7..7463addd80fd5 100644 --- a/drivers/misc/nizynqcpld.c +++ b/drivers/misc/nizynqcpld.c @@ -1050,28 +1050,28 @@ static const struct file_operations nizynqcpld_watchdog_misc_fops = { static struct nizynqcpld_led_desc proto_leds[] = { { - .name = "nizynqcpld:user1:green", + .name = "nilrt:user1:green", .addr = PROTO_SWITCHANDLED, .bit = 1 << 4, }, { - .name = "nizynqcpld:user1:yellow", + .name = "nilrt:user1:yellow", .addr = PROTO_SWITCHANDLED, .bit = 1 << 3, }, { - .name = "nizynqcpld:status:yellow", + .name = "nilrt:status:yellow", .addr = PROTO_SWITCHANDLED, .bit = 1 << 2, }, { - .name = "nizynqcpld:eth1:green", + .name = "nilrt:eth1:green", .addr = PROTO_ETHERNETLED, .bit = 1 << 1, .default_trigger = "e000b000:00:100Mb", }, { - .name = "nizynqcpld:eth1:yellow", + .name = "nilrt:eth1:yellow", .addr = PROTO_ETHERNETLED, .bit = 1 << 0, .default_trigger = "e000b000:00:Gb", @@ -1080,22 +1080,22 @@ static struct nizynqcpld_led_desc proto_leds[] = { static struct nizynqcpld_led_desc dosx_leds[] = { { - .name = "nizynqcpld:user1:green", + .name = "nilrt:user1:green", .addr = DOSX_LED, .bit = 1 << 5, }, { - .name = "nizynqcpld:user1:yellow", + .name = "nilrt:user1:yellow", .addr = DOSX_LED, .bit = 1 << 4, }, { - .name = "nizynqcpld:status:red", + .name = "nilrt:status:red", .addr = DOSX_LED, .bit = 1 << 3, }, { - .name = "nizynqcpld:status:yellow", + .name = "nilrt:status:yellow", .addr = DOSX_LED, .bit = 1 << 2, .pattern_lo_addr = DOSX_STATUSLEDSHIFTBYTE0, @@ -1103,35 +1103,35 @@ static struct nizynqcpld_led_desc dosx_leds[] = { .max_brightness = 0xffff, }, { - .name = "nizynqcpld:wifi:green", + .name = "nilrt:wifi:green", .addr = DOSX_ETHERNETLED, .bit = 1 << 5, }, { - .name = "nizynqcpld:wifi:yellow", + .name = "nilrt:wifi:yellow", .addr = DOSX_ETHERNETLED, .bit = 1 << 4, }, { - .name = "nizynqcpld:eth1:green", + .name = "nilrt:eth1:green", .addr = DOSX_ETHERNETLED, .bit = 1 << 3, .default_trigger = "e000b000:01:100Mb", }, { - .name = "nizynqcpld:eth1:yellow", + .name = "nilrt:eth1:yellow", .addr = DOSX_ETHERNETLED, .bit = 1 << 2, .default_trigger = "e000b000:01:Gb", }, { - .name = "nizynqcpld:eth0:green", + .name = "nilrt:eth0:green", .addr = DOSX_ETHERNETLED, .bit = 1 << 1, .default_trigger = "e000b000:00:100Mb", }, { - .name = "nizynqcpld:eth0:yellow", + .name = "nilrt:eth0:yellow", .addr = DOSX_ETHERNETLED, .bit = 1 << 0, .default_trigger = "e000b000:00:Gb", @@ -1140,12 +1140,12 @@ static struct nizynqcpld_led_desc dosx_leds[] = { static struct nizynqcpld_led_desc sol_leds[] = { { - .name = "nizynqcpld:user1:green", + .name = "nilrt:user1:green", .addr = DOSX_LED, .bit = 1 << 5, }, { - .name = "nizynqcpld:status:yellow", + .name = "nilrt:status:yellow", .addr = DOSX_LED, .bit = 1 << 2, .pattern_lo_addr = DOSX_STATUSLEDSHIFTBYTE0, @@ -1154,25 +1154,25 @@ static struct nizynqcpld_led_desc sol_leds[] = { .max_brightness = 0xffff, }, { - .name = "nizynqcpld:eth1:green", + .name = "nilrt:eth1:green", .addr = DOSX_ETHERNETLED, .bit = 1 << 3, .default_trigger = "e000b000:01:100Mb", }, { - .name = "nizynqcpld:eth1:yellow", + .name = "nilrt:eth1:yellow", .addr = DOSX_ETHERNETLED, .bit = 1 << 2, .default_trigger = "e000b000:01:Gb", }, { - .name = "nizynqcpld:eth0:green", + .name = "nilrt:eth0:green", .addr = DOSX_ETHERNETLED, .bit = 1 << 1, .default_trigger = "e000b000:00:100Mb", }, { - .name = "nizynqcpld:eth0:yellow", + .name = "nilrt:eth0:yellow", .addr = DOSX_ETHERNETLED, .bit = 1 << 0, .default_trigger = "e000b000:00:Gb", @@ -1181,12 +1181,12 @@ static struct nizynqcpld_led_desc sol_leds[] = { static struct nizynqcpld_led_desc tecate_leds[] = { { - .name = "nizynqcpld:user1:green", + .name = "nilrt:user1:green", .addr = DOSX_LED, .bit = 1 << 5, }, { - .name = "nizynqcpld:status:yellow", + .name = "nilrt:status:yellow", .addr = DOSX_LED, .bit = 1 << 2, .pattern_lo_addr = DOSX_STATUSLEDSHIFTBYTE0, @@ -1195,13 +1195,13 @@ static struct nizynqcpld_led_desc tecate_leds[] = { .max_brightness = 0xffff, }, { - .name = "nizynqcpld:eth0:green", + .name = "nilrt:eth0:green", .addr = DOSX_ETHERNETLED, .bit = 1 << 1, .default_trigger = "e000b000:00:100Mb", }, { - .name = "nizynqcpld:eth0:yellow", + .name = "nilrt:eth0:yellow", .addr = DOSX_ETHERNETLED, .bit = 1 << 0, .default_trigger = "e000b000:00:Gb", From bcbd188e17ed62189e26c2f0802b9ff1bad220c6 Mon Sep 17 00:00:00 2001 From: Jeff Westfahl Date: Tue, 25 Feb 2014 15:45:32 -0600 Subject: [PATCH 26/83] nizynqcpld: myRIO WiFi LEDs are poorly named The myRIO WiFi LEDs are poorly named. The names "green" and "yellow" don't correspond to the actual colors of the LEDs (blue and red), but color names don't really relate to how the LEDs are used. Functional names "primary" and "secondary" are most appropriate; rename them as such. Signed-off-by: Jeff Westfahl Natinst-CAR-ID: 454237 --- drivers/misc/nizynqcpld.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/misc/nizynqcpld.c b/drivers/misc/nizynqcpld.c index 7463addd80fd5..a74c746b6639d 100644 --- a/drivers/misc/nizynqcpld.c +++ b/drivers/misc/nizynqcpld.c @@ -1103,12 +1103,12 @@ static struct nizynqcpld_led_desc dosx_leds[] = { .max_brightness = 0xffff, }, { - .name = "nilrt:wifi:green", + .name = "nilrt:wifi:primary", .addr = DOSX_ETHERNETLED, .bit = 1 << 5, }, { - .name = "nilrt:wifi:yellow", + .name = "nilrt:wifi:secondary", .addr = DOSX_ETHERNETLED, .bit = 1 << 4, }, From 5182afe8d2676abb970a4714975f3e216ec1c1e4 Mon Sep 17 00:00:00 2001 From: Chen Yee Chew Date: Tue, 25 Nov 2014 15:50:33 +0800 Subject: [PATCH 27/83] sbZynq: Add sbZynq to nizynq CPLD driver Signed-off-by: Chen Yee Chew Acked-by: Keng Soon Cheah Acked-by: Jaeden Amero Natinst-ReviewBoard-ID: 83857 --- drivers/misc/nizynqcpld.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/misc/nizynqcpld.c b/drivers/misc/nizynqcpld.c index a74c746b6639d..dcfdff8331445 100644 --- a/drivers/misc/nizynqcpld.c +++ b/drivers/misc/nizynqcpld.c @@ -1312,6 +1312,20 @@ static struct nizynqcpld_desc nizynqcpld_descs[] = { .switch_addr = PROTO_PROCESSORMODE, .watchdog_addr = DOSX_WATCHDOGCONTROL, }, + /* sbZynq CPLD */ + { + .attrs = dosequis6_attrs, + .supported_version = 1, + .supported_product = 4, + .watchdog_desc = &dosxv5_watchdog_desc, + .led_descs = sol_leds, + .num_led_descs = ARRAY_SIZE(sol_leds), + .reboot_addr = DOSX_PROCESSORRESET, + .scratch_hr_addr = DOSX_SCRATCHPADHR, + .scratch_sr_addr = DOSX_SCRATCHPADSR, + .switch_addr = PROTO_PROCESSORMODE, + .watchdog_addr = DOSX_WATCHDOGCONTROL, + }, }; static void wifi_sw_work_func(struct work_struct *work) From 3fa44c7973e16ef572560a75236f3d475bc168c1 Mon Sep 17 00:00:00 2001 From: Nathan Sullivan Date: Wed, 3 Dec 2014 15:27:55 -0600 Subject: [PATCH 28/83] nizynqcpld: Update LED triggers to match macb mdio name Change the default trigger names to match the name the cadence macb driver gives its mdio bus. Signed-off-by: Nathan Sullivan Acked-by: Jaeden Amero Acked-by: Ben Shelton Acked-by: Gratian Crisan Natinst-ReviewBoard-ID: 84557 --- drivers/misc/nizynqcpld.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/misc/nizynqcpld.c b/drivers/misc/nizynqcpld.c index dcfdff8331445..a759bae049862 100644 --- a/drivers/misc/nizynqcpld.c +++ b/drivers/misc/nizynqcpld.c @@ -1068,13 +1068,13 @@ static struct nizynqcpld_led_desc proto_leds[] = { .name = "nilrt:eth1:green", .addr = PROTO_ETHERNETLED, .bit = 1 << 1, - .default_trigger = "e000b000:00:100Mb", + .default_trigger = "e000b000.etherne:00:100Mb", }, { .name = "nilrt:eth1:yellow", .addr = PROTO_ETHERNETLED, .bit = 1 << 0, - .default_trigger = "e000b000:00:Gb", + .default_trigger = "e000b000.etherne:00:Gb", }, }; @@ -1116,25 +1116,25 @@ static struct nizynqcpld_led_desc dosx_leds[] = { .name = "nilrt:eth1:green", .addr = DOSX_ETHERNETLED, .bit = 1 << 3, - .default_trigger = "e000b000:01:100Mb", + .default_trigger = "e000b000.etherne:01:100Mb", }, { .name = "nilrt:eth1:yellow", .addr = DOSX_ETHERNETLED, .bit = 1 << 2, - .default_trigger = "e000b000:01:Gb", + .default_trigger = "e000b000.etherne:01:Gb", }, { .name = "nilrt:eth0:green", .addr = DOSX_ETHERNETLED, .bit = 1 << 1, - .default_trigger = "e000b000:00:100Mb", + .default_trigger = "e000b000.etherne:00:100Mb", }, { .name = "nilrt:eth0:yellow", .addr = DOSX_ETHERNETLED, .bit = 1 << 0, - .default_trigger = "e000b000:00:Gb", + .default_trigger = "e000b000.etherne:00:Gb", }, }; @@ -1157,25 +1157,25 @@ static struct nizynqcpld_led_desc sol_leds[] = { .name = "nilrt:eth1:green", .addr = DOSX_ETHERNETLED, .bit = 1 << 3, - .default_trigger = "e000b000:01:100Mb", + .default_trigger = "e000b000.etherne:01:100Mb", }, { .name = "nilrt:eth1:yellow", .addr = DOSX_ETHERNETLED, .bit = 1 << 2, - .default_trigger = "e000b000:01:Gb", + .default_trigger = "e000b000.etherne:01:Gb", }, { .name = "nilrt:eth0:green", .addr = DOSX_ETHERNETLED, .bit = 1 << 1, - .default_trigger = "e000b000:00:100Mb", + .default_trigger = "e000b000.etherne:00:100Mb", }, { .name = "nilrt:eth0:yellow", .addr = DOSX_ETHERNETLED, .bit = 1 << 0, - .default_trigger = "e000b000:00:Gb", + .default_trigger = "e000b000.etherne:00:Gb", }, }; @@ -1198,13 +1198,13 @@ static struct nizynqcpld_led_desc tecate_leds[] = { .name = "nilrt:eth0:green", .addr = DOSX_ETHERNETLED, .bit = 1 << 1, - .default_trigger = "e000b000:00:100Mb", + .default_trigger = "e000b000.etherne:00:100Mb", }, { .name = "nilrt:eth0:yellow", .addr = DOSX_ETHERNETLED, .bit = 1 << 0, - .default_trigger = "e000b000:00:Gb", + .default_trigger = "e000b000.etherne:00:Gb", }, }; From e303308fc62eca9fe778bbde366b21d910132c09 Mon Sep 17 00:00:00 2001 From: Jaeden Amero Date: Thu, 26 Feb 2015 17:55:47 -0600 Subject: [PATCH 29/83] nizynqcpld: Strobe the watchdog control register The CPLD watchdog control register is a strobe register, full of a mix of read-only and write-only bits. Because it is a strobe register, this driver was in error doing read, modify, write when updating the watchdog control register. Some bad things happened because of the driver's misuse of this register. A specific example of a failure due to read, modify, write of the watchdog control register follows. Bit 7 of the watchdog control register is "Watchdog Mode". A value of 1 here means "Boot Mode". A value of 0 means "User Mode". Bit 4 ("Watchdog Pet") is a write only bit that pets the watchdog when set to 1. When attempting to pet the watchdog while the watchdog is in boot mode, the driver would do a read, see that bit 7 is set (indicating that the watchdog is in boot mode), or this value with bit 4 (0x10) to say "I want to pet the boot mode watch dog," and end up writing both bit 7 and bit 4 as 1. Writing a 1 to bit 7 means "I want the watchdog to enter user mode," so no petting occurs, despite the driver's intent to pet the watch dog and not to enter user mode. Signed-off-by: Jaeden Amero Reviewed-by: Ben Shelton Reviewed-by: Gratian Crisan Natinst-ReviewBoard-ID: 90484 Natinst-CAR-ID: 521301 Natinst-ReviewBoard-ID: 95393 --- drivers/misc/nizynqcpld.c | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/drivers/misc/nizynqcpld.c b/drivers/misc/nizynqcpld.c index a759bae049862..dfac18e0211e9 100644 --- a/drivers/misc/nizynqcpld.c +++ b/drivers/misc/nizynqcpld.c @@ -63,6 +63,9 @@ #define DOSX_WATCHDOGCONTROL_RESET 0x02 #define DOSX_WATCHDOGCONTROL_ALARM 0x01 +#define DOSX_WATCHDOGCONTROL_RW_BITS \ + (DOSX_WATCHDOGCONTROL_PROC_INTERRUPT | DOSX_WATCHDOGCONTROL_PROC_RESET) + #define DOSX_WATCHDOG_MAX_COUNTER 0x00FFFFFF #define DOSX_WATCHDOG_COUNTER_BYTES 3 @@ -715,28 +718,18 @@ static int nizynqcpld_watchdog_check_action(u32 action) static int nizynqcpld_watchdog_add_action(struct nizynqcpld *cpld, u32 action) { int err; - u8 action_mask; - u8 control; + u8 action_bit; if (NIWATCHDOG_ACTION_INTERRUPT == action) - action_mask = DOSX_WATCHDOGCONTROL_PROC_INTERRUPT; + action_bit = DOSX_WATCHDOGCONTROL_PROC_INTERRUPT; else if (NIWATCHDOG_ACTION_RESET == action) - action_mask = DOSX_WATCHDOGCONTROL_PROC_RESET; + action_bit = DOSX_WATCHDOGCONTROL_PROC_RESET; else return -ENOTSUPP; nizynqcpld_lock(cpld); - err = nizynqcpld_read(cpld, DOSX_WATCHDOGCONTROL, &control); - - if (err) { - dev_err(cpld->dev, - "Error %d reading watchdog control.\n", err); - goto out_unlock; - } - control |= action_mask; - - err = nizynqcpld_write(cpld, DOSX_WATCHDOGCONTROL, control); + err = nizynqcpld_write(cpld, DOSX_WATCHDOGCONTROL, action_bit); if (err) { dev_err(cpld->dev, @@ -764,6 +757,9 @@ static int nizynqcpld_watchdog_start(struct nizynqcpld *cpld) goto out_unlock; } + /* Mask off all the read-only and write-only bits. */ + control &= DOSX_WATCHDOGCONTROL_RW_BITS; + err = nizynqcpld_write(cpld, DOSX_WATCHDOGCONTROL, control | DOSX_WATCHDOGCONTROL_RESET); if (err) { @@ -802,6 +798,9 @@ static int nizynqcpld_watchdog_pet(struct nizynqcpld *cpld, u32 *state) goto out_unlock; } + /* Mask off all the read-only and write-only bits. */ + control &= DOSX_WATCHDOGCONTROL_RW_BITS; + control |= DOSX_WATCHDOGCONTROL_PET; err = nizynqcpld_write(cpld, DOSX_WATCHDOGCONTROL, control); @@ -855,6 +854,9 @@ static int nizynqcpld_watchdog_counter_get(struct nizynqcpld *cpld, goto out_unlock; } + /* Mask off all the read-only and write-only bits. */ + control &= DOSX_WATCHDOGCONTROL_RW_BITS; + err = nizynqcpld_write(cpld, DOSX_WATCHDOGCONTROL, control | DOSX_WATCHDOGCONTROL_CAPTURECOUNTER); if (err) { @@ -906,6 +908,9 @@ static irqreturn_t nizynqcpld_watchdog_irq(int irq, void *data) cpld->watchdog.expired = true; + /* Mask off all the read-only and write-only bits. */ + control &= DOSX_WATCHDOGCONTROL_RW_BITS; + /* Acknowledge the interrupt. */ control |= DOSX_WATCHDOGCONTROL_RESET; err = nizynqcpld_write(cpld, DOSX_WATCHDOGCONTROL, control); From 6eb49988e5688a714b2a72316342cb0f994f5a90 Mon Sep 17 00:00:00 2001 From: Jaeden Amero Date: Fri, 6 Mar 2015 17:19:15 -0600 Subject: [PATCH 30/83] nizynqcpld: Remove THIS_MODULE We don't need it. Signed-off-by: Jaeden Amero Reviewed-by: Ben Shelton Reviewed-by: Josh Cartwright Natinst-ReviewBoard-ID: 91284 --- drivers/misc/nizynqcpld.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/misc/nizynqcpld.c b/drivers/misc/nizynqcpld.c index dfac18e0211e9..a66fb618ff2f2 100644 --- a/drivers/misc/nizynqcpld.c +++ b/drivers/misc/nizynqcpld.c @@ -1634,7 +1634,6 @@ MODULE_DEVICE_TABLE(i2c, nizynqcpld_ids); static struct i2c_driver nizynqcpld_driver = { .driver = { .name = "nizynqcpld", - .owner = THIS_MODULE, }, .probe = nizynqcpld_probe, .remove = nizynqcpld_remove, From df42930e845be1f53547930f8ced6a9a5f18983d Mon Sep 17 00:00:00 2001 From: Jaeden Amero Date: Fri, 6 Mar 2015 17:19:29 -0600 Subject: [PATCH 31/83] nizynqcpld: Use module_i2c_driver macro Use the module_i2c_driver macro to register with the i2c driver instead of explicitly rewriting the code that the macro creates for us. This is cleaner, and clean is nice. Signed-off-by: Jaeden Amero Reviewed-by: Ben Shelton Reviewed-by: Josh Cartwright Natinst-ReviewBoard-ID: 91284 --- drivers/misc/nizynqcpld.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/drivers/misc/nizynqcpld.c b/drivers/misc/nizynqcpld.c index a66fb618ff2f2..becc0eef2add0 100644 --- a/drivers/misc/nizynqcpld.c +++ b/drivers/misc/nizynqcpld.c @@ -1640,17 +1640,7 @@ static struct i2c_driver nizynqcpld_driver = { .id_table = nizynqcpld_ids, }; -static int __init nizynqcpld_init(void) -{ - return i2c_add_driver(&nizynqcpld_driver); -} -module_init(nizynqcpld_init); - -static void __exit nizynqcpld_exit(void) -{ - i2c_del_driver(&nizynqcpld_driver); -} -module_exit(nizynqcpld_exit); +module_i2c_driver(nizynqcpld_driver); MODULE_DESCRIPTION("Driver for CPLD on NI's Zynq RIO products"); MODULE_AUTHOR("National Instruments"); From 0f7e17cd1c6ad65f5599ad41dcdc9aed54cccc47 Mon Sep 17 00:00:00 2001 From: Jaeden Amero Date: Fri, 6 Mar 2015 11:24:25 -0600 Subject: [PATCH 32/83] nizynqcpld: Read LED information from device tree Instead of maintaining a table of board-specific LED information for each board, use device tree to store LED properties 'max-brightness', 'default-trigger', and 'label'. This allows boards to vary these properties without also requiring driver modifications. Signed-off-by: Jaeden Amero Reviewed-by: Ben Shelton Reviewed-by: Josh Cartwright Natinst-ReviewBoard-ID: 91284 Natinst-ReviewBoard-ID: 93389 --- drivers/misc/nizynqcpld.c | 160 +++++++++++++++++++++++++------------- 1 file changed, 105 insertions(+), 55 deletions(-) diff --git a/drivers/misc/nizynqcpld.c b/drivers/misc/nizynqcpld.c index becc0eef2add0..b3a4a82151fc9 100644 --- a/drivers/misc/nizynqcpld.c +++ b/drivers/misc/nizynqcpld.c @@ -77,13 +77,11 @@ #define MYRIO_WIFISWCTRL_RELIRQ 0x40 struct nizynqcpld_led_desc { - const char *name; - const char *default_trigger; + const char *of_node_name; u8 addr; u8 bit; u8 pattern_lo_addr; u8 pattern_hi_addr; - int max_brightness; }; struct nizynqcpld; @@ -136,6 +134,7 @@ struct nizynqcpld_desc { struct nizynqcpld { struct device *dev; + int irq; struct nizynqcpld_desc *desc; struct nizynqcpld_led *leds; struct nizynqcpld_watchdog watchdog; @@ -244,6 +243,8 @@ static int nizynqcpld_led_register(struct nizynqcpld *cpld, { int err; u8 tmp; + struct device_node *leds_node; + struct device_node *node; nizynqcpld_lock(cpld); err = nizynqcpld_read(cpld, desc->addr, &tmp); @@ -257,10 +258,33 @@ static int nizynqcpld_led_register(struct nizynqcpld *cpld, led->on = !!(tmp & desc->bit); INIT_WORK(&led->deferred_work, nizynqcpld_set_brightness_work); - led->cdev.name = desc->name; - led->cdev.default_trigger = desc->default_trigger; - led->cdev.max_brightness = desc->max_brightness ? desc->max_brightness - : 1; + /* Find the LEDs node. */ + leds_node = of_find_node_by_name(cpld->client->dev.of_node, + "leds"); + if (!leds_node) + return -ENOENT; + + /* For the current led, get the device node under 'leds'. */ + node = of_get_child_by_name(leds_node, desc->of_node_name); + if (!node) { + /* Don't register the LED if the LED is not specified in device + * tree. */ + err = -ENOENT; + goto err_out; + } + + /* Read the label from device tree. */ + led->cdev.name = of_get_property(node, "label", NULL) ? : node->name; + + /* Read the default trigger from device tree. */ + led->cdev.default_trigger = of_get_property(node, + "linux,default-trigger", NULL); + + /* Read the max brightness from device tree. */ + led->cdev.max_brightness = 1; /* Default to max of 1 */ + of_property_read_u32(node, "max-brightness", + &led->cdev.max_brightness); + led->cdev.brightness_set = nizynqcpld_led_set_brightness; led->cdev.brightness_get = nizynqcpld_led_get_brightness; @@ -271,6 +295,7 @@ static int nizynqcpld_led_register(struct nizynqcpld *cpld, } err_led: + of_node_put(node); err_out: return err; } @@ -931,15 +956,31 @@ static int nizynqcpld_watchdog_misc_open(struct inode *inode, struct miscdevice *misc_dev = file->private_data; struct nizynqcpld *cpld = container_of(misc_dev, struct nizynqcpld, watchdog.misc_dev); + struct device_node *watchdogs_node; + struct device_node *boot_watchdog_node; + file->private_data = cpld; + /* Find the watchdogs node. */ + watchdogs_node = of_find_node_by_name(cpld->client->dev.of_node, + "watchdogs"); + if (!watchdogs_node) + return -ENOENT; + + /* Get the boot watchdog node. */ + boot_watchdog_node = of_find_node_by_name(watchdogs_node, + "boot-watchdog"); + if (!boot_watchdog_node) + return -ENOENT; + if (!atomic_dec_and_test(&cpld->watchdog.available)) { atomic_inc(&cpld->watchdog.available); return -EBUSY; } - return request_threaded_irq(cpld->client->irq, - NULL, nizynqcpld_watchdog_irq, + cpld->irq = irq_of_parse_and_map(boot_watchdog_node, 0); + + return request_threaded_irq(cpld->irq, NULL, nizynqcpld_watchdog_irq, 0, NIWATCHDOG_NAME, cpld); } @@ -947,7 +988,7 @@ static int nizynqcpld_watchdog_misc_release(struct inode *inode, struct file *file) { struct nizynqcpld *cpld = file->private_data; - free_irq(cpld->client->irq, cpld); + free_irq(cpld->irq, cpld); atomic_inc(&cpld->watchdog.available); return 0; } @@ -1055,161 +1096,146 @@ static const struct file_operations nizynqcpld_watchdog_misc_fops = { static struct nizynqcpld_led_desc proto_leds[] = { { - .name = "nilrt:user1:green", + .of_node_name = "user1-0", .addr = PROTO_SWITCHANDLED, .bit = 1 << 4, }, { - .name = "nilrt:user1:yellow", + .of_node_name = "user1-1", .addr = PROTO_SWITCHANDLED, .bit = 1 << 3, }, { - .name = "nilrt:status:yellow", + .of_node_name = "status-0", .addr = PROTO_SWITCHANDLED, .bit = 1 << 2, }, { - .name = "nilrt:eth1:green", + .of_node_name = "eth1-0", .addr = PROTO_ETHERNETLED, .bit = 1 << 1, - .default_trigger = "e000b000.etherne:00:100Mb", }, { - .name = "nilrt:eth1:yellow", + .of_node_name = "eth1-1", .addr = PROTO_ETHERNETLED, .bit = 1 << 0, - .default_trigger = "e000b000.etherne:00:Gb", }, }; static struct nizynqcpld_led_desc dosx_leds[] = { { - .name = "nilrt:user1:green", + .of_node_name = "user1-0", .addr = DOSX_LED, .bit = 1 << 5, }, { - .name = "nilrt:user1:yellow", + .of_node_name = "user1-1", .addr = DOSX_LED, .bit = 1 << 4, }, { - .name = "nilrt:status:red", + .of_node_name = "status-0", .addr = DOSX_LED, .bit = 1 << 3, }, { - .name = "nilrt:status:yellow", + .of_node_name = "status-1", .addr = DOSX_LED, .bit = 1 << 2, .pattern_lo_addr = DOSX_STATUSLEDSHIFTBYTE0, .pattern_hi_addr = DOSX_STATUSLEDSHIFTBYTE1, - .max_brightness = 0xffff, }, { - .name = "nilrt:wifi:primary", + .of_node_name = "wifi-0", .addr = DOSX_ETHERNETLED, .bit = 1 << 5, }, { - .name = "nilrt:wifi:secondary", + .of_node_name = "wifi-1", .addr = DOSX_ETHERNETLED, .bit = 1 << 4, }, { - .name = "nilrt:eth1:green", + .of_node_name = "eth1-0", .addr = DOSX_ETHERNETLED, .bit = 1 << 3, - .default_trigger = "e000b000.etherne:01:100Mb", }, { - .name = "nilrt:eth1:yellow", + .of_node_name = "eth1-1", .addr = DOSX_ETHERNETLED, .bit = 1 << 2, - .default_trigger = "e000b000.etherne:01:Gb", }, { - .name = "nilrt:eth0:green", + .of_node_name = "eth0-0", .addr = DOSX_ETHERNETLED, .bit = 1 << 1, - .default_trigger = "e000b000.etherne:00:100Mb", }, { - .name = "nilrt:eth0:yellow", + .of_node_name = "eth0-1", .addr = DOSX_ETHERNETLED, .bit = 1 << 0, - .default_trigger = "e000b000.etherne:00:Gb", }, }; static struct nizynqcpld_led_desc sol_leds[] = { { - .name = "nilrt:user1:green", + .of_node_name = "user1-0", .addr = DOSX_LED, .bit = 1 << 5, }, { - .name = "nilrt:status:yellow", + .of_node_name = "status-0", .addr = DOSX_LED, .bit = 1 << 2, .pattern_lo_addr = DOSX_STATUSLEDSHIFTBYTE0, /* write byte 1 first */ .pattern_hi_addr = DOSX_STATUSLEDSHIFTBYTE1, - .max_brightness = 0xffff, }, { - .name = "nilrt:eth1:green", + .of_node_name = "eth1-0", .addr = DOSX_ETHERNETLED, .bit = 1 << 3, - .default_trigger = "e000b000.etherne:01:100Mb", }, { - .name = "nilrt:eth1:yellow", + .of_node_name = "eth1-1", .addr = DOSX_ETHERNETLED, .bit = 1 << 2, - .default_trigger = "e000b000.etherne:01:Gb", }, { - .name = "nilrt:eth0:green", + .of_node_name = "eth0-0", .addr = DOSX_ETHERNETLED, .bit = 1 << 1, - .default_trigger = "e000b000.etherne:00:100Mb", }, { - .name = "nilrt:eth0:yellow", + .of_node_name = "eth0-1", .addr = DOSX_ETHERNETLED, .bit = 1 << 0, - .default_trigger = "e000b000.etherne:00:Gb", }, }; static struct nizynqcpld_led_desc tecate_leds[] = { { - .name = "nilrt:user1:green", + .of_node_name = "user1-0", .addr = DOSX_LED, .bit = 1 << 5, }, { - .name = "nilrt:status:yellow", + .of_node_name = "status-0", .addr = DOSX_LED, .bit = 1 << 2, .pattern_lo_addr = DOSX_STATUSLEDSHIFTBYTE0, /* write byte 1 first */ .pattern_hi_addr = DOSX_STATUSLEDSHIFTBYTE1, - .max_brightness = 0xffff, }, { - .name = "nilrt:eth0:green", + .of_node_name = "eth0-0", .addr = DOSX_ETHERNETLED, .bit = 1 << 1, - .default_trigger = "e000b000.etherne:00:100Mb", }, { - .name = "nilrt:eth0:yellow", + .of_node_name = "eth0-1", .addr = DOSX_ETHERNETLED, .bit = 1 << 0, - .default_trigger = "e000b000.etherne:00:Gb", }, }; @@ -1409,12 +1435,26 @@ static int myrio_wifi_sw_init(struct nizynqcpld *cpld) u8 data; int err = 0; struct input_dev *input; + struct device_node *switches_node; + struct device_node *wifi_switch_node; if (!cpld->desc->wifi_sw_addr) goto wifi_sw_init_exit; INIT_WORK(&cpld->wifi_sw.deferred_work, wifi_sw_work_func); - cpld->wifi_sw.irq = irq_of_parse_and_map(cpld->client->dev.of_node, 1); + + /* Find the switches node. */ + switches_node = of_find_node_by_name(cpld->client->dev.of_node, + "switches"); + if (!switches_node) + goto wifi_sw_init_exit; + + /* Find the WiFi switch node. */ + wifi_switch_node = of_find_node_by_name(switches_node, "wifi-switch"); + if (!wifi_switch_node) + goto wifi_sw_init_exit; + + cpld->wifi_sw.irq = irq_of_parse_and_map(wifi_switch_node, 0); /* ensure that the interrupt was mapped */ if (!cpld->wifi_sw.irq) @@ -1544,8 +1584,12 @@ static int nizynqcpld_probe(struct i2c_client *client, for (i = 0; i < desc->num_led_descs; i++) { err = nizynqcpld_led_register(cpld, &desc->led_descs[i], &cpld->leds[i]); + /* Skip LEDs that are missing from device tree, but continue + * adding other LEDs. */ if (err) - goto err_led; + dev_dbg(&client->dev, + "Omitting %s LED\n", + desc->led_descs[i].of_node_name); } /* don't care about errors */ @@ -1591,7 +1635,6 @@ static int nizynqcpld_probe(struct i2c_client *client, sysfs_remove_files(&client->dev.kobj, desc->attrs); err_sysfs_create_files: myrio_wifi_sw_uninit(cpld); -err_led: while (i--) nizynqcpld_led_unregister(&cpld->leds[i]); kfree(cpld->leds); @@ -1625,15 +1668,22 @@ static int nizynqcpld_remove(struct i2c_client *client) return 0; } +static const struct of_device_id nizynqcpld_dt_ids[] = { + { .compatible = "ni,cpld" }, + { } +}; +MODULE_DEVICE_TABLE(of, nizynqcpld_dt_ids); + static const struct i2c_device_id nizynqcpld_ids[] = { - { .name = "nizynqcpld" }, + { .name = "cpld" }, { }, }; MODULE_DEVICE_TABLE(i2c, nizynqcpld_ids); static struct i2c_driver nizynqcpld_driver = { .driver = { - .name = "nizynqcpld", + .name = "nicpld", + .of_match_table = nizynqcpld_dt_ids, }, .probe = nizynqcpld_probe, .remove = nizynqcpld_remove, From 79ea01a0c0cc1bc4c9808bdf986a29b8142f5c9b Mon Sep 17 00:00:00 2001 From: Jaeden Amero Date: Fri, 6 Mar 2015 12:05:30 -0600 Subject: [PATCH 33/83] nizynqcpld: Remove tecate_leds Tecate isn't so special that it needs its own duplicate LED section. The only reason it needed one before was to avoid registering eth1 LEDs. Now that we specify LEDs via the device tree, any LEDs not present in the device tree will not get registered. The Tecate device tree doesn't specify LEDs that it doesn't have, so we'll still be avoiding registering eth1 LEDs even after removing tecate_leds. Signed-off-by: Jaeden Amero Reviewed-by: Ben Shelton Reviewed-by: Josh Cartwright Natinst-ReviewBoard-ID: 91284 --- drivers/misc/nizynqcpld.c | 30 ++---------------------------- 1 file changed, 2 insertions(+), 28 deletions(-) diff --git a/drivers/misc/nizynqcpld.c b/drivers/misc/nizynqcpld.c index b3a4a82151fc9..92ca8116c62ad 100644 --- a/drivers/misc/nizynqcpld.c +++ b/drivers/misc/nizynqcpld.c @@ -1213,32 +1213,6 @@ static struct nizynqcpld_led_desc sol_leds[] = { }, }; -static struct nizynqcpld_led_desc tecate_leds[] = { - { - .of_node_name = "user1-0", - .addr = DOSX_LED, - .bit = 1 << 5, - }, - { - .of_node_name = "status-0", - .addr = DOSX_LED, - .bit = 1 << 2, - .pattern_lo_addr = DOSX_STATUSLEDSHIFTBYTE0, - /* write byte 1 first */ - .pattern_hi_addr = DOSX_STATUSLEDSHIFTBYTE1, - }, - { - .of_node_name = "eth0-0", - .addr = DOSX_ETHERNETLED, - .bit = 1 << 1, - }, - { - .of_node_name = "eth0-1", - .addr = DOSX_ETHERNETLED, - .bit = 1 << 0, - }, -}; - static struct nizynqcpld_watchdog_desc dosxv4_watchdog_desc = { .watchdog_period_ns = 24000, }; @@ -1321,8 +1295,8 @@ static struct nizynqcpld_desc nizynqcpld_descs[] = { .supported_version = 1, .supported_product = 2, .watchdog_desc = &dosxv5_watchdog_desc, - .led_descs = tecate_leds, - .num_led_descs = ARRAY_SIZE(tecate_leds), + .led_descs = sol_leds, + .num_led_descs = ARRAY_SIZE(sol_leds), .reboot_addr = DOSX_PROCESSORRESET, .scratch_hr_addr = DOSX_SCRATCHPADHR, .scratch_sr_addr = DOSX_SCRATCHPADSR, From 2567a80ba79c90eec6350e6ae068d6aecd483ed0 Mon Sep 17 00:00:00 2001 From: Kyle Roeschley Date: Wed, 17 Feb 2016 10:08:26 -0600 Subject: [PATCH 34/83] nizynqcpld: Use oneshot interrupt flag Using the IRQF_ONESHOT flag keeps us from losing our handler entirely after a recent IRQ change in the RT patch, commit 62c6757fc4ef ("genirq: Handle force threading of interrupts with primary and thread handler"). While that commit caused our immediate problem, we should have been using this all along and were only saved by the fact that our interrupts are edge-triggered. Signed-off-by: Kyle Roeschley Signed-off-by: Brad Mouring Acked-by: Josh Cartwright Natinst-CAR-ID: 568224 Natinst-CAR-ID: 572611 Natinst-ReviewBoard-ID: 127047 --- drivers/misc/nizynqcpld.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/misc/nizynqcpld.c b/drivers/misc/nizynqcpld.c index 92ca8116c62ad..f6a92267aad23 100644 --- a/drivers/misc/nizynqcpld.c +++ b/drivers/misc/nizynqcpld.c @@ -981,7 +981,7 @@ static int nizynqcpld_watchdog_misc_open(struct inode *inode, cpld->irq = irq_of_parse_and_map(boot_watchdog_node, 0); return request_threaded_irq(cpld->irq, NULL, nizynqcpld_watchdog_irq, - 0, NIWATCHDOG_NAME, cpld); + IRQF_ONESHOT, NIWATCHDOG_NAME, cpld); } static int nizynqcpld_watchdog_misc_release(struct inode *inode, @@ -1385,8 +1385,8 @@ static int wifi_sw_open(struct input_dev *dev) struct nizynqcpld *cpld = container_of(wifi_sw, struct nizynqcpld, wifi_sw); - err = request_threaded_irq(wifi_sw->irq, - NULL, wifi_sw_hnd, 0, "wifi_sw", wifi_sw); + err = request_threaded_irq(wifi_sw->irq, NULL, wifi_sw_hnd, + IRQF_ONESHOT, "wifi_sw", wifi_sw); if (err) { dev_err(&cpld->client->dev, "error %d registering irq handle for wifi_sw\n", err); From e6ea1e0395effadd5d872b344704b59d8198665d Mon Sep 17 00:00:00 2001 From: Josh Cartwright Date: Thu, 26 Feb 2015 10:28:19 -0600 Subject: [PATCH 35/83] nizynqcpld: make poll() and ioctl() functions static These functions are not used outside nizynqcpld. Mark them static. Reviewed-by: Jaeden Amero Reviewed-by: Gratian Crisan Reviewed-by: Brad Mouring Reviewed-by: Ben Shelton Signed-off-by: Josh Cartwright Natinst-ReviewBoard-ID: 90460 --- drivers/misc/nizynqcpld.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/misc/nizynqcpld.c b/drivers/misc/nizynqcpld.c index f6a92267aad23..1ee4b6ceaaf42 100644 --- a/drivers/misc/nizynqcpld.c +++ b/drivers/misc/nizynqcpld.c @@ -993,6 +993,7 @@ static int nizynqcpld_watchdog_misc_release(struct inode *inode, return 0; } +static long nizynqcpld_watchdog_misc_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { @@ -1072,6 +1073,7 @@ long nizynqcpld_watchdog_misc_ioctl(struct file *file, unsigned int cmd, return err; } +static unsigned int nizynqcpld_watchdog_misc_poll(struct file *file, struct poll_table_struct *wait) { From 9fb8af744fc78cb4b4ff0b222306f03482a42129 Mon Sep 17 00:00:00 2001 From: Josh Cartwright Date: Fri, 20 Mar 2015 10:40:15 -0500 Subject: [PATCH 36/83] nizynqcpld: use restart_handler mechanism for triggering restart The restart_handler mechanism is a much cleaner way to hook into the restart codepaths. Make the CPLD driver higher priority than the Zynq-provided SLCR reset mechanism to allow the CPLD to track the reason why the Zynq was reset. Signed-off-by: Josh Cartwright Reviewed-by: Ben Shelton Reviewed-by: Jaeden Amero Natinst-ReviewBoard-ID: 90458 --- drivers/misc/nizynqcpld.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/drivers/misc/nizynqcpld.c b/drivers/misc/nizynqcpld.c index 1ee4b6ceaaf42..6b47e92fc4f43 100644 --- a/drivers/misc/nizynqcpld.c +++ b/drivers/misc/nizynqcpld.c @@ -19,8 +19,8 @@ #include #include #include -#include #include +#include #include #include #include @@ -140,7 +140,7 @@ struct nizynqcpld { struct nizynqcpld_watchdog watchdog; struct i2c_client *client; struct mutex lock; - struct ni_zynq_board_reset reset; + struct notifier_block restart_nb; struct myrio_wifi_sw wifi_sw; }; @@ -330,12 +330,15 @@ static int nizynqcpld_read(struct nizynqcpld *cpld, u8 reg, u8 *data) return err == ARRAY_SIZE(msgs) ? 0 : err; } -static void nizynqcpld_reset(struct ni_zynq_board_reset *reset) +static int nizynqcpld_restart(struct notifier_block *nb, + unsigned long action, void *data) { - struct nizynqcpld *cpld = container_of(reset, struct nizynqcpld, reset); + struct nizynqcpld *cpld = container_of(nb, struct nizynqcpld, + restart_nb); struct nizynqcpld_desc *desc = cpld->desc; nizynqcpld_write(cpld, desc->reboot_addr, 0x80); + return 0; } static inline ssize_t nizynqcpld_scratch_show(struct nizynqcpld *cpld, @@ -1596,8 +1599,9 @@ static int nizynqcpld_probe(struct i2c_client *client, } } - cpld->reset.reset = nizynqcpld_reset; - ni_zynq_board_reset = &cpld->reset; + cpld->restart_nb.notifier_call = nizynqcpld_restart; + cpld->restart_nb.priority = 255; + register_restart_handler(&cpld->restart_nb); i2c_set_clientdata(client, cpld); @@ -1628,7 +1632,7 @@ static int nizynqcpld_remove(struct i2c_client *client) struct nizynqcpld_desc *desc = cpld->desc; int i; - ni_zynq_board_reset = NULL; + unregister_restart_handler(&cpld->restart_nb); if (desc->watchdog_desc) misc_deregister(&cpld->watchdog.misc_dev); From 6a7aa11d7f43655ab1ba379690b0d133da1fda38 Mon Sep 17 00:00:00 2001 From: Jaeden Amero Date: Fri, 6 Mar 2015 11:51:40 -0600 Subject: [PATCH 37/83] nizynqcpld: Document device tree bindings Document how nizynqcpld uses device tree, including the required and optional settings for the nizynqcpld node and its children nodes. Signed-off-by: Jaeden Amero Reviewed-by: Ben Shelton Reviewed-by: Josh Cartwright Natinst-ReviewBoard-ID: 91284 --- .../devicetree/bindings/misc/ni,cpld.txt | 156 ++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100644 Documentation/devicetree/bindings/misc/ni,cpld.txt diff --git a/Documentation/devicetree/bindings/misc/ni,cpld.txt b/Documentation/devicetree/bindings/misc/ni,cpld.txt new file mode 100644 index 0000000000000..a1abde6f5f0e9 --- /dev/null +++ b/Documentation/devicetree/bindings/misc/ni,cpld.txt @@ -0,0 +1,156 @@ +National Instruments CPLD + +National Instruments (NI) boards often have CPLDs on them to handle +board-specific tasks like LED control, board switches and buttons, +power sequencing, and CPU-independent watchdogs. + +NI's CPLDs are connected over i2c. As such, 'nicpld' must be a child +of an i2c node. + +nicpld properties: +- compatible : (required) + Should be "ni,cpld" +- reg: (required) + Address of the CPLD on the i2c bus + +Required sub-nodes: +- watchdogs : A node containing sub-nodes describing watchdogs + +Optional sub-nodes: +- switches : A node containing sub-nodes describing switches +- leds : A node containing sub-nodes describing LEDs + + +Watchdogs Child Node +==================== + +Each watchdog controlled by the CPLD is represented as a sub-node of +the nicpld's 'watchdogs' node. Each sub-node of 'watchdogs' has the +following properties. + +Required properties: +- interrupts : Should be the CPLD watchdog interrupt specifier + +Optional properties: +- label: A name for the CPLD switch + + +Switches Child Node +=================== + +Each switch or button controlled by the CPLD is represented as a +sub-node of the nicpld's 'switches' node. Each sub-node of 'switches' +has the following properties. + +Required properties: +- interrupts : The CPLD switch interrupt specifier + + +LEDs Child Node +=============== + +Each LED controlled by the CPLD is represented as a sub-node of the +nicpld's 'leds' node. The name of each LED node corresponds to an +LED type. The "-0" or "-1" suffixes specify an LED element (single +color) within a multi-color LED. + +Possible LED types: +- user1-0 +- user1-1 +- status-0 +- status-1 +- temp-alert-0 +- wifi-0 +- wifi-1 +- eth0-0 +- eth0-1 +- eth1-0 +- eth1-1 + +Different CPLDs support different LED types. The set of LEDs that +various CPLDs support can be determined by examining their product +code. The product code for a CPLD can be determined by reading the +"NICPLD_PRODUCT" (0x1D) register of the CPLD over i2c. Below is a +list of which CPLDs support which LED types. + +CPLD Products 0x00 and 0x01 +--------------------------- +user1-0 +user1-1 +status-0 +status-1 +wifi-0 +wifi-1 +eth0-0 +eth0-1 +eth1-0 +eth1-1 + +CPLD Product 0x02 +----------------- +status-0 +temp-alert-0 +eth0-0 +eth0-1 +eth1-0 +eth1-1 + +CPLD Products 0x03 and 0x04 +--------------------------- +user1-0 +status-0 +eth0-0 +eth0-1 +eth1-0 +eth1-1 + + +LED sub-node properties: +- label : (optional) + see bindings/leds/common.txt +- max-brightness : (optional) + The number of possible special blinking patterns. Selecting a + brightness will pick the blink pattern. +- linux,default-trigger : (optional) + see bindings/leds/common.txt + +Example: + +nicpld@40 { + compatible = "ni,cpld"; + reg = <0x40>; + + watchdogs { + boot-watchdog { + interrupt-parent = <&gpio>; + interrupts = <24 0>; + }; + }; + + switches { + wifi-switch { + interrupt-parent = <&gpio>; + interrupts = <25 0>; + }; + }; + + leds { + user1-0 { + label = "nilrt:user1:green"; + }; + status-0 { + label = "nilrt:status:yellow"; + max-brightness = <0xFFFF>; + }; + eth0-0 { + label = "nilrt:eth0:green"; + linux,default-trigger = + "e000b000.etherne:00:100Mb"; + }; + eth0-1 { + label = "nilrt:eth0:yellow"; + linux,default-trigger = + "e000b000.etherne:00:Gb"; + }; + }; +}; From eab6ee885e0afded0816f3cdc97068120f8b2cd5 Mon Sep 17 00:00:00 2001 From: Kyle Roeschley Date: Fri, 9 Dec 2016 10:41:20 -0600 Subject: [PATCH 38/83] nizynqcpld: Unblock poll() callers on highly-loaded systems On systems under high load, our IRQ handler hangs on I2C read because the I2C IRQ thread priority is lower than load priority. To work around this, we set watchdog.expired and wake up poll() callers before trying I2C communication. This does assume that we will never have spurious interrupts on this line, but since it's only driven by the CPLD we should never run into that case. Signed-off-by: Kyle Roeschley Signed-off-by: Brad Mouring Tested-by: Ovidiu Vancea Acked-by: Julia Cartwright Natinst-CAR-ID: 577311 Natinst-ReviewBoard-ID: 168702 --- drivers/misc/nizynqcpld.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/drivers/misc/nizynqcpld.c b/drivers/misc/nizynqcpld.c index 6b47e92fc4f43..1a6497b42e8b6 100644 --- a/drivers/misc/nizynqcpld.c +++ b/drivers/misc/nizynqcpld.c @@ -922,6 +922,11 @@ static irqreturn_t nizynqcpld_watchdog_irq(int irq, void *data) nizynqcpld_lock(cpld); + cpld->watchdog.expired = true; + + /* Signal the watchdog event. */ + wake_up_all(&cpld->watchdog.irq_event); + err = nizynqcpld_read(cpld, DOSX_WATCHDOGCONTROL, &control); if (err) { @@ -934,8 +939,6 @@ static irqreturn_t nizynqcpld_watchdog_irq(int irq, void *data) goto out_unlock; } - cpld->watchdog.expired = true; - /* Mask off all the read-only and write-only bits. */ control &= DOSX_WATCHDOGCONTROL_RW_BITS; @@ -943,9 +946,6 @@ static irqreturn_t nizynqcpld_watchdog_irq(int irq, void *data) control |= DOSX_WATCHDOGCONTROL_RESET; err = nizynqcpld_write(cpld, DOSX_WATCHDOGCONTROL, control); - /* Signal the watchdog event. */ - wake_up_all(&cpld->watchdog.irq_event); - ret = IRQ_HANDLED; out_unlock: @@ -1081,14 +1081,10 @@ unsigned int nizynqcpld_watchdog_misc_poll(struct file *file, struct poll_table_struct *wait) { struct nizynqcpld *cpld = file->private_data; - unsigned int mask = 0; - poll_wait(file, &cpld->watchdog.irq_event, wait); - nizynqcpld_lock(cpld); - if (cpld->watchdog.expired) - mask = POLLIN; - nizynqcpld_unlock(cpld); - return mask; + if (READ_ONCE(cpld->watchdog.expired)) + return POLLIN; + return 0; } static const struct file_operations nizynqcpld_watchdog_misc_fops = { From d4ae98f4a78a61bdb33cc220b0866244c384ea36 Mon Sep 17 00:00:00 2001 From: Xander Huff Date: Tue, 18 Oct 2016 11:23:31 -0500 Subject: [PATCH 39/83] nizynqcpld: Code style cleanup Fix checkpatch error/warnings: Prefer 'unsigned int' to bare use of 'unsigned' Block comments use a trailing */ on a separate line Missing a blank line after declarations Block comments use * on subsequent lines line over 80 characters space required after that ',' (ctx:VnV) Comparisons should place the constant on the right side of the test quoted string split across lines Prefer kcalloc over kzalloc with multiply Signed-off-by: Xander Huff Natinst-ReviewBoard-ID: 157395 --- drivers/misc/nizynqcpld.c | 57 ++++++++++++++++++++++++++------------- 1 file changed, 39 insertions(+), 18 deletions(-) diff --git a/drivers/misc/nizynqcpld.c b/drivers/misc/nizynqcpld.c index 1a6497b42e8b6..1a92c7c1c5e6c 100644 --- a/drivers/misc/nizynqcpld.c +++ b/drivers/misc/nizynqcpld.c @@ -122,7 +122,7 @@ struct nizynqcpld_desc { u8 supported_version; u8 supported_product; struct nizynqcpld_led_desc *led_descs; - unsigned num_led_descs; + unsigned int num_led_descs; struct nizynqcpld_watchdog_desc *watchdog_desc; u8 reboot_addr; u8 scratch_hr_addr; @@ -157,7 +157,8 @@ static inline void nizynqcpld_unlock(struct nizynqcpld *cpld) } /* Can't issue i2c transfers in set_brightness, because - * they can sleep */ + * they can sleep + */ static void nizynqcpld_set_brightness_work(struct work_struct *work) { struct nizynqcpld_led *led = container_of(work, struct nizynqcpld_led, @@ -195,9 +196,11 @@ static void nizynqcpld_led_set_brightness(struct led_classdev *led_cdev, enum led_brightness brightness) { struct nizynqcpld_led *led = to_nizynqcpld_led(led_cdev); + led->on = !!brightness; /* some LED's support a blink pattern instead of a variable brightness, - and blink_set isn't flexible enough for the supported patterns */ + * and blink_set isn't flexible enough for the supported patterns + */ led->blink_pattern = brightness; schedule_work(&led->deferred_work); } @@ -216,7 +219,8 @@ nizynqcpld_led_get_brightness(struct led_classdev *led_cdev) nizynqcpld_unlock(cpld); /* for the status LED, the blink pattern used for brightness on write - is write-only, so we just return on/off for all LED's */ + * is write-only, so we just return on/off for all LED's + */ return tmp & desc->bit ? LED_FULL : 0; } @@ -268,7 +272,8 @@ static int nizynqcpld_led_register(struct nizynqcpld *cpld, node = of_get_child_by_name(leds_node, desc->of_node_name); if (!node) { /* Don't register the LED if the LED is not specified in device - * tree. */ + * tree. + */ err = -ENOENT; goto err_out; } @@ -366,6 +371,7 @@ static ssize_t nizynqcpld_scratchsr_show(struct device *dev, { struct nizynqcpld *cpld = dev_get_drvdata(dev); struct nizynqcpld_desc *desc = cpld->desc; + return nizynqcpld_scratch_show(cpld, attr, buf, desc->scratch_sr_addr); } @@ -374,6 +380,7 @@ static ssize_t nizynqcpld_scratchhr_show( { struct nizynqcpld *cpld = dev_get_drvdata(dev); struct nizynqcpld_desc *desc = cpld->desc; + return nizynqcpld_scratch_show(cpld, attr, buf, desc->scratch_hr_addr); } @@ -411,6 +418,7 @@ static ssize_t nizynqcpld_scratchsr_store(struct device *dev, { struct nizynqcpld *cpld = dev_get_drvdata(dev); struct nizynqcpld_desc *desc = cpld->desc; + return nizynqcpld_scratch_store(cpld, attr, buf, count, desc->scratch_sr_addr); } @@ -421,6 +429,7 @@ static ssize_t nizynqcpld_scratchhr_store(struct device *dev, { struct nizynqcpld *cpld = dev_get_drvdata(dev); struct nizynqcpld_desc *desc = cpld->desc; + return nizynqcpld_scratch_store(cpld, attr, buf, count, desc->scratch_hr_addr); } @@ -564,11 +573,12 @@ static inline ssize_t nizynqcpld_powerstatus_show(struct device *dev, return sprintf(buf, "%u\n", !!(data & pa->bit)); } -#define POWERSTATUS_ATTR(_name,_bit) \ - struct powerstatus_attribute dev_attr_##_name = { \ - .bit = _bit, \ - .dev_attr = \ - __ATTR(_name, 0444, nizynqcpld_powerstatus_show, NULL), \ +#define POWERSTATUS_ATTR(_name, _bit) \ + struct powerstatus_attribute dev_attr_##_name = { \ + .bit = _bit, \ + .dev_attr = \ + __ATTR(_name, 0444, nizynqcpld_powerstatus_show, \ + NULL), \ } static POWERSTATUS_ATTR(pwr_aux_valid, 1 << 4); @@ -615,7 +625,8 @@ static ssize_t dosequiscpld_wdmode_show(struct device *dev, return err; /* you write a 1 to the bit to enter user mode, but it reads as a - 0 in user mode for backwards compatibility */ + * 0 in user mode for backwards compatibility + */ tmp &= DOSX_WATCHDOGCONTROL_ENTER_USER_MODE; return sprintf(buf, "%s\n", tmp ? "boot" : "user"); } @@ -748,9 +759,9 @@ static int nizynqcpld_watchdog_add_action(struct nizynqcpld *cpld, u32 action) int err; u8 action_bit; - if (NIWATCHDOG_ACTION_INTERRUPT == action) + if (action == NIWATCHDOG_ACTION_INTERRUPT) action_bit = DOSX_WATCHDOGCONTROL_PROC_INTERRUPT; - else if (NIWATCHDOG_ACTION_RESET == action) + else if (action == NIWATCHDOG_ACTION_RESET) action_bit = DOSX_WATCHDOGCONTROL_PROC_RESET; else return -ENOTSUPP; @@ -898,7 +909,7 @@ static int nizynqcpld_watchdog_counter_get(struct nizynqcpld *cpld, DOSX_WATCHDOGCOUNTER2, DOSX_WATCHDOG_COUNTER_BYTES, data); - if (DOSX_WATCHDOG_COUNTER_BYTES == err) + if (err == DOSX_WATCHDOG_COUNTER_BYTES) err = 0; else { dev_err(cpld->dev, @@ -991,6 +1002,7 @@ static int nizynqcpld_watchdog_misc_release(struct inode *inode, struct file *file) { struct nizynqcpld *cpld = file->private_data; + free_irq(cpld->irq, cpld); atomic_inc(&cpld->watchdog.available); return 0; @@ -1009,18 +1021,21 @@ long nizynqcpld_watchdog_misc_ioctl(struct file *file, unsigned int cmd, switch (cmd) { case NIWATCHDOG_IOCTL_PERIOD_NS: { __u32 period = desc->watchdog_period_ns; + err = copy_to_user((__u32 *)arg, &period, sizeof(__u32)); break; } case NIWATCHDOG_IOCTL_MAX_COUNTER: { __u32 counter = DOSX_WATCHDOG_MAX_COUNTER; + err = copy_to_user((__u32 *)arg, &counter, sizeof(__u32)); break; } case NIWATCHDOG_IOCTL_COUNTER_SET: { __u32 counter; + err = copy_from_user(&counter, (__u32 *)arg, sizeof(__u32)); if (!err) @@ -1029,6 +1044,7 @@ long nizynqcpld_watchdog_misc_ioctl(struct file *file, unsigned int cmd, } case NIWATCHDOG_IOCTL_CHECK_ACTION: { __u32 action; + err = copy_from_user(&action, (__u32 *)arg, sizeof(__u32)); if (!err) @@ -1037,6 +1053,7 @@ long nizynqcpld_watchdog_misc_ioctl(struct file *file, unsigned int cmd, } case NIWATCHDOG_IOCTL_ADD_ACTION: { __u32 action; + err = copy_from_user(&action, (__u32 *)arg, sizeof(__u32)); if (!err) @@ -1049,6 +1066,7 @@ long nizynqcpld_watchdog_misc_ioctl(struct file *file, unsigned int cmd, } case NIWATCHDOG_IOCTL_PET: { __u32 state; + err = nizynqcpld_watchdog_pet(cpld, &state); if (!err) err = copy_to_user((__u32 *)arg, &state, @@ -1061,6 +1079,7 @@ long nizynqcpld_watchdog_misc_ioctl(struct file *file, unsigned int cmd, } case NIWATCHDOG_IOCTL_COUNTER_GET: { __u32 counter; + err = nizynqcpld_watchdog_counter_get(cpld, &counter); if (!err) { err = copy_to_user((__u32 *)arg, &counter, @@ -1374,6 +1393,7 @@ static void wifi_sw_work_func(struct work_struct *work) static irqreturn_t wifi_sw_hnd(int irq, void *irq_data) { struct myrio_wifi_sw *wifi_sw = (struct myrio_wifi_sw *)irq_data; + schedule_work(&wifi_sw->deferred_work); return IRQ_HANDLED; @@ -1541,14 +1561,14 @@ static int nizynqcpld_probe(struct i2c_client *client, if (!desc) { err = -ENODEV; dev_err(cpld->dev, - "this driver does not support cpld with version %d and" - " product %d.\n", version, product); + "this driver does not support cpld with version %d and product %d.\n", + version, product); goto err_no_version; } cpld->desc = desc; - cpld->leds = kzalloc(sizeof(*cpld->leds) * desc->num_led_descs, + cpld->leds = kcalloc(desc->num_led_descs, sizeof(*cpld->leds), GFP_KERNEL); if (!cpld->leds) { err = -ENOMEM; @@ -1560,7 +1580,8 @@ static int nizynqcpld_probe(struct i2c_client *client, err = nizynqcpld_led_register(cpld, &desc->led_descs[i], &cpld->leds[i]); /* Skip LEDs that are missing from device tree, but continue - * adding other LEDs. */ + * adding other LEDs. + */ if (err) dev_dbg(&client->dev, "Omitting %s LED\n", From 281116b5016f0c9834e57e919fe506c3669e3350 Mon Sep 17 00:00:00 2001 From: Kyle Roeschley Date: Wed, 2 Aug 2017 08:12:52 -0500 Subject: [PATCH 40/83] nizynqcpld: Request IRQ on probe instead of miscdevice open Do what most sane drivers do and request our IRQ on probe rather than doing it every time someone opens our char device. This ensures that our thread exists at boot time, which means priority changes can be done in user mode. Signed-off-by: Kyle Roeschley Signed-off-by: Brad Mouring Acked-by: Ovidiu Vancea Acked-by: Zach Brown Acked-by: Julia Cartwright Natinst-CAR-ID: 649766 Natinst-ReviewBoard-ID: 197577 --- drivers/misc/nizynqcpld.c | 47 +++++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 19 deletions(-) diff --git a/drivers/misc/nizynqcpld.c b/drivers/misc/nizynqcpld.c index 1a92c7c1c5e6c..59278ebe8424c 100644 --- a/drivers/misc/nizynqcpld.c +++ b/drivers/misc/nizynqcpld.c @@ -970,32 +970,15 @@ static int nizynqcpld_watchdog_misc_open(struct inode *inode, struct miscdevice *misc_dev = file->private_data; struct nizynqcpld *cpld = container_of(misc_dev, struct nizynqcpld, watchdog.misc_dev); - struct device_node *watchdogs_node; - struct device_node *boot_watchdog_node; file->private_data = cpld; - /* Find the watchdogs node. */ - watchdogs_node = of_find_node_by_name(cpld->client->dev.of_node, - "watchdogs"); - if (!watchdogs_node) - return -ENOENT; - - /* Get the boot watchdog node. */ - boot_watchdog_node = of_find_node_by_name(watchdogs_node, - "boot-watchdog"); - if (!boot_watchdog_node) - return -ENOENT; - if (!atomic_dec_and_test(&cpld->watchdog.available)) { atomic_inc(&cpld->watchdog.available); return -EBUSY; } - cpld->irq = irq_of_parse_and_map(boot_watchdog_node, 0); - - return request_threaded_irq(cpld->irq, NULL, nizynqcpld_watchdog_irq, - IRQF_ONESHOT, NIWATCHDOG_NAME, cpld); + return 0; } static int nizynqcpld_watchdog_misc_release(struct inode *inode, @@ -1003,7 +986,6 @@ static int nizynqcpld_watchdog_misc_release(struct inode *inode, { struct nizynqcpld *cpld = file->private_data; - free_irq(cpld->irq, cpld); atomic_inc(&cpld->watchdog.available); return 0; } @@ -1599,12 +1581,39 @@ static int nizynqcpld_probe(struct i2c_client *client, if (desc->watchdog_desc) { struct nizynqcpld_watchdog *watchdog = &cpld->watchdog; + struct device_node *node; watchdog->desc = desc->watchdog_desc; atomic_set(&watchdog->available, 1); init_waitqueue_head(&watchdog->irq_event); watchdog->expired = false; + /* Find the watchdogs node. */ + node = of_find_node_by_name(cpld->client->dev.of_node, + "watchdogs"); + if (!node) { + err = -ENOENT; + goto err_watchdog_register; + } + + /* Get the boot watchdog node. */ + node = of_find_node_by_name(node, "boot-watchdog"); + if (!node) { + err = -ENOENT; + goto err_watchdog_register; + } + + cpld->irq = irq_of_parse_and_map(node, 0); + + err = devm_request_threaded_irq(&client->dev, cpld->irq, NULL, + nizynqcpld_watchdog_irq, + IRQF_ONESHOT, NIWATCHDOG_NAME, + cpld); + if (err) { + dev_err(cpld->dev, "failed to get irq\n"); + goto err_watchdog_register; + } + watchdog->misc_dev.minor = MISC_DYNAMIC_MINOR; watchdog->misc_dev.name = NIWATCHDOG_NAME; watchdog->misc_dev.fops = &nizynqcpld_watchdog_misc_fops; From 8481e536e876c1f47bad232a631800e63d4d0620 Mon Sep 17 00:00:00 2001 From: Adrian Papp Date: Wed, 22 Jan 2014 14:42:36 +0200 Subject: [PATCH 41/83] myRIO: fix argument passed to free_irq called in wifi_sw_close Signed-off-by: Adrian Papp Natinst-CAR-ID: 445041 --- drivers/misc/nizynqcpld.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/misc/nizynqcpld.c b/drivers/misc/nizynqcpld.c index 59278ebe8424c..5627313f5bf0e 100644 --- a/drivers/misc/nizynqcpld.c +++ b/drivers/misc/nizynqcpld.c @@ -1404,7 +1404,7 @@ static void wifi_sw_close(struct input_dev *dev) struct myrio_wifi_sw *wifi_sw = input_get_drvdata(dev); if (wifi_sw->irq_registered) - free_irq(wifi_sw->irq, wifi_sw_hnd); + free_irq(wifi_sw->irq, wifi_sw); } static int myrio_wifi_sw_init(struct nizynqcpld *cpld) From 400adecd60da4bdc31479faac7a0d35f75729f5d Mon Sep 17 00:00:00 2001 From: Jason VanFickell Date: Fri, 17 Jan 2014 13:02:14 -0600 Subject: [PATCH 42/83] myRIO: add inversion support to the LED driver Inversion support in the LED driver is needed for the WiFi LED feature. Signed-off-by: Jason VanFickell (joshc: use DEVICE_ATTR_RW() to declare inverted attribute) Signed-off-by: Josh Cartwright (Haris Okanovic: fixup squash: led_get_brightness function inverting led value) Signed-off-by: Zach Brown Signed-off-by: Brad Mouring Acked-by: Xander Huff Acked-by: James Minor Natinst-CAR-ID: 624268 Natinst-ReviewBoard-ID: 170771 --- drivers/leds/led-class.c | 34 ++++++++++++++++++++++++++++++++++ drivers/leds/led-core.c | 6 ++++++ include/linux/leds.h | 1 + 3 files changed, 41 insertions(+) diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c index 6b9fa060c3a11..b5724e4c3bd48 100644 --- a/drivers/leds/led-class.c +++ b/drivers/leds/led-class.c @@ -84,6 +84,39 @@ static ssize_t max_brightness_show(struct device *dev, } static DEVICE_ATTR_RO(max_brightness); +static ssize_t inverted_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct led_classdev *led_cdev = dev_get_drvdata(dev); + + return sprintf(buf, "%u\n", led_cdev->inverted); +} + +static ssize_t inverted_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t size) +{ + struct led_classdev *led_cdev = dev_get_drvdata(dev); + u8 inverted; + int ret; + + ret = kstrtou8(buf, 10, &inverted); + if (ret < 0) + return ret; + + if (inverted > 1) + return -EINVAL; + + led_cdev->inverted = inverted; + + /* Note: The LED brightness is not immediately + * updated as a result of changing the inversion. + */ + + return size; +} + +static DEVICE_ATTR_RW(inverted); + #ifdef CONFIG_LEDS_TRIGGERS static const BIN_ATTR(trigger, 0644, led_trigger_read, led_trigger_write, 0); static const struct bin_attribute *const led_trigger_bin_attrs[] = { @@ -98,6 +131,7 @@ static const struct attribute_group led_trigger_group = { static struct attribute *led_class_attrs[] = { &dev_attr_brightness.attr, &dev_attr_max_brightness.attr, + &dev_attr_inverted.attr, NULL, }; diff --git a/drivers/leds/led-core.c b/drivers/leds/led-core.c index 59473f286b31f..1e549f3bbf8ad 100644 --- a/drivers/leds/led-core.c +++ b/drivers/leds/led-core.c @@ -331,6 +331,9 @@ EXPORT_SYMBOL_GPL(led_set_brightness); void led_set_brightness_nopm(struct led_classdev *led_cdev, unsigned int value) { + if (led_cdev->inverted) + value = value ? LED_OFF : LED_FULL; + /* Use brightness_set op if available, it is guaranteed not to sleep */ if (!__led_set_brightness(led_cdev, value)) return; @@ -375,6 +378,9 @@ int led_set_brightness_sync(struct led_classdev *led_cdev, unsigned int value) if (led_cdev->blink_delay_on || led_cdev->blink_delay_off) return -EBUSY; + if (led_cdev->inverted) + value = value ? LED_OFF : LED_FULL; + led_cdev->brightness = min(value, led_cdev->max_brightness); if (led_cdev->flags & LED_SUSPENDED) diff --git a/include/linux/leds.h b/include/linux/leds.h index b16b803cc1ac5..f4c173f66153d 100644 --- a/include/linux/leds.h +++ b/include/linux/leds.h @@ -233,6 +233,7 @@ struct led_classdev { */ struct device *(*hw_control_get_device)(struct led_classdev *led_cdev); #endif + u8 inverted; #ifdef CONFIG_LEDS_BRIGHTNESS_HW_CHANGED int brightness_hw_changed; From e7e2ebcbb9679e8844159b7ce162d2165e406488 Mon Sep 17 00:00:00 2001 From: Jeff Westfahl Date: Tue, 29 Apr 2014 09:35:46 -0500 Subject: [PATCH 43/83] i2c: cadence: Support reading the bus number from the device tree When multiple I2C busses are present, we need a way to deterministically specify the bus number for each bus. Here we add support for reading a bus-id field from the device tree. We must use i2c_add_numbered_adapter when specifying a bus number. We use a default value of -1 if the bus number isn't specified in the device tree, which gives the same behavior as using i2c_add_adapter. Signed-off-by: Jeff Westfahl --- drivers/i2c/busses/i2c-cadence.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-cadence.c b/drivers/i2c/busses/i2c-cadence.c index 0fb728ade92e4..c397e4c8cdab1 100644 --- a/drivers/i2c/busses/i2c-cadence.c +++ b/drivers/i2c/busses/i2c-cadence.c @@ -1530,6 +1530,15 @@ static int cdns_i2c_probe(struct platform_device *pdev) return irq; id->adap.owner = THIS_MODULE; + + /* + * A bus number of -1 means dynamically assign, default to that if + * bus-id isn't specified in the device tree. + */ + ret = of_property_read_u32(pdev->dev.of_node, "bus-id", &id->adap.nr); + if (ret) + id->adap.nr = -1; + id->adap.dev.of_node = pdev->dev.of_node; id->adap.algo = &cdns_i2c_algo; id->adap.timeout = CDNS_I2C_TIMEOUT; @@ -1597,7 +1606,7 @@ static int cdns_i2c_probe(struct platform_device *pdev) } cdns_i2c_init(id); - ret = i2c_add_adapter(&id->adap); + ret = i2c_add_numbered_adapter(&id->adap); if (ret < 0) goto err_clk_notifier_unregister; From 7cc86758c6470eb33f948aa206c40f190ccfff3e Mon Sep 17 00:00:00 2001 From: Joe Hershberger Date: Thu, 29 Aug 2013 20:36:21 -0500 Subject: [PATCH 44/83] xiic: Read the bus number from the device tree This allows the controller to play nicely with other i2c controllers in the same device. Signed-off-by: Joe Hershberger --- drivers/i2c/busses/i2c-xiic.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-xiic.c b/drivers/i2c/busses/i2c-xiic.c index 28015d77599d1..dcc0de48be3aa 100644 --- a/drivers/i2c/busses/i2c-xiic.c +++ b/drivers/i2c/busses/i2c-xiic.c @@ -1430,6 +1430,9 @@ static int xiic_i2c_probe(struct platform_device *pdev) int ret, irq; u8 i; u32 sr; +#ifdef CONFIG_OF + const unsigned int *prop; +#endif i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL); if (!i2c) @@ -1461,6 +1464,18 @@ static int xiic_i2c_probe(struct platform_device *pdev) snprintf(i2c->adap.name, sizeof(i2c->adap.name), DRIVER_NAME " %s", pdev->name); + /* a bus number of -1 means dynamically assign, default to that if + * bus-id isn't specified in the device tree + */ + i2c->adap.nr = -1; +#ifdef CONFIG_OF + prop = of_get_property(pdev->dev.of_node, "bus-id", NULL); + if (prop) + i2c->adap.nr = be32_to_cpup(prop); +#endif + + xiic_reinit(i2c); + mutex_init(&i2c->lock); spin_lock_init(&i2c->atomic_lock); @@ -1514,7 +1529,7 @@ static int xiic_i2c_probe(struct platform_device *pdev) } /* add i2c adapter to i2c tree */ - ret = i2c_add_adapter(&i2c->adap); + ret = i2c_add_numbered_adapter(&i2c->adap); if (ret) { xiic_deinit(i2c); goto err_pm_disable; From eae31ab799f12732bbb6419d86baa203c9b3d3a0 Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Thu, 16 Feb 2017 14:03:16 -0600 Subject: [PATCH 45/83] i2c: xiic: Handle devices that do not specify a clock With the addition of commit e9aacb08ff9d ("i2c: xiic: Implement power management") the xiic driver failed to load if a clock was not specified in the dts. This commit changes the behavior so that a clock does not need to be specified in order for the driver to function. [cvadrevu: Fixed trivial conflict] Signed-off-by: Chaitanya Vadrevu Fixes: e9aacb08ff9d ("i2c: xiic: Implement power management") Signed-off-by: Zach Brown Signed-off-by: Brad Mouring Acked-by: Kyle Roeschley Acked-by: Julia Cartwright Acked-by: Brandon Streiff Natinst-CAR-ID: 630351 Natinst-ReviewBoard-ID: 173828 --- drivers/i2c/busses/i2c-xiic.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/i2c/busses/i2c-xiic.c b/drivers/i2c/busses/i2c-xiic.c index dcc0de48be3aa..2521012922ce8 100644 --- a/drivers/i2c/busses/i2c-xiic.c +++ b/drivers/i2c/busses/i2c-xiic.c @@ -1480,10 +1480,16 @@ static int xiic_i2c_probe(struct platform_device *pdev) spin_lock_init(&i2c->atomic_lock); i2c->clk = devm_clk_get_enabled(&pdev->dev, NULL); - if (IS_ERR(i2c->clk)) - return dev_err_probe(&pdev->dev, PTR_ERR(i2c->clk), - "failed to enable input clock.\n"); - + if (IS_ERR(i2c->clk)) { + if (PTR_ERR(i2c->clk) != -ENOENT) { + dev_err(&pdev->dev, + "error while finding input clock. %ld\n", + PTR_ERR(i2c->clk)); + return PTR_ERR(i2c->clk); + } + dev_err(&pdev->dev, "Optional input clock not found.\n"); + i2c->clk = NULL; + } i2c->dev = &pdev->dev; pm_runtime_set_autosuspend_delay(i2c->dev, XIIC_PM_TIMEOUT); pm_runtime_use_autosuspend(i2c->dev); From 8d3ed3762f69269cd24201eac94a0fd2b5ec9184 Mon Sep 17 00:00:00 2001 From: Wilson Lee Date: Tue, 19 Dec 2017 20:15:14 -0800 Subject: [PATCH 46/83] auxdisplay: sh1107: Sino Wealth SH1107 OLED driver Sino Wealth SH1107 OLED display driver are not supported at this moment. This commit is to add SH1107 driver to support SH1107 OLED driver. This driver will use i2c communication to transfer data to SH1107 IC. Cc: Miguel Ojeda Sandonis Cc: Greg Kroah-Hartman Signed-off-by: Wilson Lee Acked-by: Julia Cartwright Natinst-ReviewBoard-ID: 205126 Signed-off-by: Brad Mouring [cvadrevu: Fixed trivial conflicts due to newer module.] [cvadrevu: Kconfig: Changed --help-- to help] [cvadrevu: Updated sh1107_probe args and removed sh1107_remove to build on 6.18 kernel] Signed-off-by: Chaitanya Vadrevu --- drivers/auxdisplay/Kconfig | 13 ++ drivers/auxdisplay/Makefile | 1 + drivers/auxdisplay/sh1107.c | 309 ++++++++++++++++++++++++++++++++++++ drivers/auxdisplay/sh1107.h | 78 +++++++++ 4 files changed, 401 insertions(+) create mode 100644 drivers/auxdisplay/sh1107.c create mode 100644 drivers/auxdisplay/sh1107.h diff --git a/drivers/auxdisplay/Kconfig b/drivers/auxdisplay/Kconfig index bedc6133f970a..7d7deda52488c 100644 --- a/drivers/auxdisplay/Kconfig +++ b/drivers/auxdisplay/Kconfig @@ -422,6 +422,19 @@ config KS0108_DELAY If you compile this as a module, you can still override this value using the module parameters. +config SH1107 + tristate "SH1107 LCD Controller" + depends on I2C + help + If you have a LCD controlled by one or more sh1107 + controller, say Y. You will need also another more specific + driver for your LCD. + + To compile this as a module, choose M here: + the module will be called sh1107. + + If unsure, say N. + config CFAG12864B tristate "CFAG12864B LCD" depends on X86 diff --git a/drivers/auxdisplay/Makefile b/drivers/auxdisplay/Makefile index f5c13ed1cd4f5..c75b396bb42b9 100644 --- a/drivers/auxdisplay/Makefile +++ b/drivers/auxdisplay/Makefile @@ -16,3 +16,4 @@ obj-$(CONFIG_LINEDISP) += line-display.o obj-$(CONFIG_MAX6959) += max6959.o obj-$(CONFIG_PARPORT_PANEL) += panel.o obj-$(CONFIG_SEG_LED_GPIO) += seg-led-gpio.o +obj-$(CONFIG_SH1107) += sh1107.o diff --git a/drivers/auxdisplay/sh1107.c b/drivers/auxdisplay/sh1107.c new file mode 100644 index 0000000000000..352ef6f0e491e --- /dev/null +++ b/drivers/auxdisplay/sh1107.c @@ -0,0 +1,309 @@ +/* + * Copyright (C) 2017 National Instruments Corp. + * + * Based on ks0108 driver (v0.1.0) + * Copyright (C) 2006 by Miguel Ojeda Sandonis + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "sh1107.h" + +#define SH1107_CMDBYTE 0x00 +#define SH1107_DATABYTE 0x40 + +#define SH1107_SET_DC_HI 0xAD +#define SH1107_SET_DC_LO 0x80 +#define SH1107_SET_DC_MASK 0x0F +#define SH1107_SET_VCOM 0xDB +#define SH1107_SET_PHASE_PERIOD 0xD9 +#define SH1107_SET_ENTIRE_DISP 0xA4 +#define SH1107_SET_DISP 0xAE +#define SH1107_SET_INVERT_DISP 0xA6 +#define SH1107_SET_DISP_CONTRAST 0x81 +#define SH1107_SET_SCANDIR 0xC0 +#define SH1107_SET_DISP_FREQ 0xD5 +#define SH1107_SET_MULTIPLEX_RATIO 0xA8 +#define SH1107_SET_MULTIPLEX_RATIO_MASK 0x7F +#define SH1107_SET_ADDR_MODE 0x20 +#define SH1107_SET_REMAP_SEG 0xA0 +#define SH1107_SET_STARTLINE 0xDC +#define SH1107_SET_STARTLINE_MASK 0x7F +#define SH1107_SET_COL_ADDR_LO 0x00 +#define SH1107_SET_COL_ADDR_HI 0x10 +#define SH1107_SET_COL_ADDR_LO_MASK 0x0F +#define SH1107_SET_COL_ADDR_HI_MASK 0x70 +#define SH1107_SET_PAGE 0xB0 +#define SH1107_SET_PAGE_MASK 0x0F +#define SH1107_SET_OFFSET 0xD3 +#define SH1107_SET_OFFSET_MASK 0x7F + +struct sh1107 { + struct device *dev; /* sh1107 device */ + struct i2c_client *client; +}; + +int sh1107_writedata(struct sh1107 *sh, unsigned char byte) +{ + unsigned char tdata[2] = { SH1107_DATABYTE, byte }; + int ret; + + /* write control byte, then data */ + struct i2c_msg msg = { + .addr = sh->client->addr, + .len = 2, + .buf = tdata, + }; + + ret = i2c_transfer(sh->client->adapter, &msg, 1); + + return ret == 1 ? 0 : ret; +} +EXPORT_SYMBOL_GPL(sh1107_writedata); + +int sh1107_writecontrol(struct sh1107 *sh, unsigned char byte) +{ + unsigned char tdata[2] = { SH1107_CMDBYTE, byte }; + int ret; + + /* write control byte, then data */ + struct i2c_msg msg = { + .addr = sh->client->addr, + .len = 2, + .buf = tdata, + }; + + ret = i2c_transfer(sh->client->adapter, &msg, 1); + + return ret == 1 ? 0 : ret; +} +EXPORT_SYMBOL_GPL(sh1107_writecontrol); + +int sh1107_dccontrol(struct sh1107 *sh, unsigned char value) +{ + int ret; + + ret = sh1107_writecontrol(sh, SH1107_SET_DC_HI); + if (ret) + return ret; + + return sh1107_writecontrol(sh, SH1107_SET_DC_LO | + (value & SH1107_SET_DC_MASK)); +} +EXPORT_SYMBOL_GPL(sh1107_dccontrol); + +int sh1107_vcomcontrol(struct sh1107 *sh, unsigned char vcom) +{ + int ret; + + ret = sh1107_writecontrol(sh, SH1107_SET_VCOM); + if (ret) + return ret; + + return sh1107_writecontrol(sh, vcom); +} +EXPORT_SYMBOL_GPL(sh1107_vcomcontrol); + +int sh1107_phaseperiod(struct sh1107 *sh, unsigned char period) +{ + int ret; + + ret = sh1107_writecontrol(sh, SH1107_SET_PHASE_PERIOD); + if (ret) + return ret; + + return sh1107_writecontrol(sh, period); +} +EXPORT_SYMBOL_GPL(sh1107_phaseperiod); + +int sh1107_entiredisplaystate(struct sh1107 *sh, unsigned char state) +{ + return sh1107_writecontrol(sh, SH1107_SET_ENTIRE_DISP | + (state ? BIT(0) : 0)); +} +EXPORT_SYMBOL_GPL(sh1107_entiredisplaystate); + +int sh1107_displaystate(struct sh1107 *sh, unsigned char state) +{ + return sh1107_writecontrol(sh, SH1107_SET_DISP | + (state ? BIT(0) : 0)); +} +EXPORT_SYMBOL_GPL(sh1107_displaystate); + +int sh1107_displayinvert(struct sh1107 *sh, unsigned char invert) +{ + return sh1107_writecontrol(sh, SH1107_SET_INVERT_DISP | + (invert ? BIT(0) : 0)); +} +EXPORT_SYMBOL_GPL(sh1107_displayinvert); + +int sh1107_displaycontrast(struct sh1107 *sh, unsigned char contrast) +{ + int ret; + + ret = sh1107_writecontrol(sh, SH1107_SET_DISP_CONTRAST); + if (ret) + return ret; + + return sh1107_writecontrol(sh, contrast); +} +EXPORT_SYMBOL_GPL(sh1107_displaycontrast); + +int sh1107_scandir(struct sh1107 *sh, unsigned char direction) +{ + return sh1107_writecontrol(sh, SH1107_SET_SCANDIR | + (direction ? BIT(3) : 0)); +} +EXPORT_SYMBOL_GPL(sh1107_scandir); + +int sh1107_displayfreq(struct sh1107 *sh, unsigned char frequency) +{ + int ret; + + ret = sh1107_writecontrol(sh, SH1107_SET_DISP_FREQ); + if (ret) + return ret; + + return sh1107_writecontrol(sh, frequency); +} +EXPORT_SYMBOL_GPL(sh1107_displayfreq); + +int sh1107_multiplexratio(struct sh1107 *sh, unsigned char ratio) +{ + int ret; + + ret = sh1107_writecontrol(sh, SH1107_SET_MULTIPLEX_RATIO); + if (ret) + return ret; + + return sh1107_writecontrol(sh, ratio & + SH1107_SET_MULTIPLEX_RATIO_MASK); +} +EXPORT_SYMBOL_GPL(sh1107_multiplexratio); + +int sh1107_addressingmode(struct sh1107 *sh, unsigned char memmode) +{ + return sh1107_writecontrol(sh, SH1107_SET_ADDR_MODE | + (memmode ? BIT(0) : 0)); +} +EXPORT_SYMBOL_GPL(sh1107_addressingmode); + +int sh1107_segremap(struct sh1107 *sh, unsigned char uprotation) +{ + return sh1107_writecontrol(sh, SH1107_SET_REMAP_SEG | + (uprotation ? BIT(0) : 0)); +} +EXPORT_SYMBOL_GPL(sh1107_segremap); + +int sh1107_startline(struct sh1107 *sh, unsigned char startline) +{ + int ret; + + ret = sh1107_writecontrol(sh, SH1107_SET_STARTLINE); + if (ret) + return ret; + + return sh1107_writecontrol(sh, startline & SH1107_SET_STARTLINE_MASK); +} +EXPORT_SYMBOL_GPL(sh1107_startline); + +int sh1107_address(struct sh1107 *sh, unsigned char address) +{ + int ret; + + ret = sh1107_writecontrol(sh, SH1107_SET_COL_ADDR_LO | + (address & SH1107_SET_COL_ADDR_LO_MASK)); + if (ret) + return ret; + + return sh1107_writecontrol(sh, SH1107_SET_COL_ADDR_HI | + ((address & SH1107_SET_COL_ADDR_HI_MASK) + >> 4)); +} +EXPORT_SYMBOL_GPL(sh1107_address); + +int sh1107_page(struct sh1107 *sh, unsigned char page) +{ + return sh1107_writecontrol(sh, SH1107_SET_PAGE | + (page & SH1107_SET_PAGE_MASK)); +} +EXPORT_SYMBOL_GPL(sh1107_page); + +int sh1107_offset(struct sh1107 *sh, unsigned char offset) +{ + int ret; + + ret = sh1107_writecontrol(sh, SH1107_SET_OFFSET); + if (ret) + return ret; + + return sh1107_writecontrol(sh, offset & SH1107_SET_OFFSET_MASK); +} +EXPORT_SYMBOL_GPL(sh1107_offset); + +static int sh1107_probe(struct i2c_client *client) +{ + struct device *dev = &client->dev; + struct sh1107 *sh; + + sh = devm_kzalloc(dev, sizeof(*sh), GFP_KERNEL); + if (!sh) + return -ENOMEM; + + sh->dev = dev; + sh->client = client; + + /* Test write data into OLED module (RAM) */ + if (sh1107_writedata(sh, 0)) + return -ENODEV; + + dev_set_drvdata(dev, sh); + dev_info(dev, "%s OLED module found.\n", client->name); + + return devm_of_platform_populate(dev); +} + +static const struct of_device_id sh1107_dt_ids[] = { + { .compatible = "sinowealth,sh1107" }, + { }, +}; +MODULE_DEVICE_TABLE(of, sh1107_dt_ids); + +static const struct i2c_device_id sh1107_ids[] = { + { "sh1107", 0 }, + { }, +}; +MODULE_DEVICE_TABLE(i2c, sh1107_ids); + +static struct i2c_driver sh1107_driver = { + .driver = { + .name = KBUILD_MODNAME, + .of_match_table = sh1107_dt_ids, + }, + .probe = sh1107_probe, + .id_table = sh1107_ids, +}; +module_i2c_driver(sh1107_driver); + +MODULE_DESCRIPTION("Driver for SH1107 LCD Driver"); +MODULE_AUTHOR("Wilson Lee "); +MODULE_LICENSE("GPL"); diff --git a/drivers/auxdisplay/sh1107.h b/drivers/auxdisplay/sh1107.h new file mode 100644 index 0000000000000..0e277a4923b76 --- /dev/null +++ b/drivers/auxdisplay/sh1107.h @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2017 National Instruments Corp. + * + * Based on ks0108 driver (v0.1.0) + * Copyright (C) 2006 by Miguel Ojeda Sandonis + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _SH1107_H_ +#define _SH1107_H_ + +/* sh1107 device private data */ +struct sh1107; + +/* Write a byte to the data port */ +int sh1107_writedata(struct sh1107 *sh, unsigned char byte); + +/* Write a byte to the control port */ +int sh1107_writecontrol(struct sh1107 *sh, unsigned char byte); + +/* Set internal DC-DC control register (0..15) */ +int sh1107_dccontrol(struct sh1107 *sh, unsigned char value); + +/* Set controller VCOM level (0..255) */ +int sh1107_vcomcontrol(struct sh1107 *sh, unsigned char vcom); + +/* Set controller pre/dis-charge period (0..255) */ +int sh1107_phaseperiod(struct sh1107 *sh, unsigned char period); + +/* Set the forcibly turn entire display state (0..1) */ +int sh1107_entiredisplaystate(struct sh1107 *sh, unsigned char state); + +/* Set the controller current display state (0..1) */ +int sh1107_displaystate(struct sh1107 *sh, unsigned char state); + +/* Set invert display (0..1) */ +int sh1107_displayinvert(struct sh1107 *sh, unsigned char invert); + +/* Set display contrast level (0..255) */ +int sh1107_displaycontrast(struct sh1107 *sh, unsigned char contrast); + +/* Set the controller common output scan direction (0..1) */ +int sh1107_scandir(struct sh1107 *sh, unsigned char direction); + +/* Set the controller internal display clocks. (0..255) */ +int sh1107_displayfreq(struct sh1107 *sh, unsigned char frequency); + +/* Set the controller multiplex mode to any multiplex ratio (0..127) */ +int sh1107_multiplexratio(struct sh1107 *sh, unsigned char ratio); + +/* Set the controller memory addressing mode (0..1) */ +int sh1107_addressingmode(struct sh1107 *sh, unsigned char memmode); + +/* Set the controller segment remap (0..1) */ +int sh1107_segremap(struct sh1107 *sh, unsigned char uprotation); + +/* Set the controller current startline (0..127) */ +int sh1107_startline(struct sh1107 *sh, unsigned char startline); + +/* Set the controller current address (0..127) */ +int sh1107_address(struct sh1107 *sh, unsigned char address); + +/* Set the controller current page (0..15) */ +int sh1107_page(struct sh1107 *sh, unsigned char page); + +/* Set the controller offset (0..127) */ +int sh1107_offset(struct sh1107 *sh, unsigned char offset); + +#endif /* _SH1107_H_ */ From f2e324a64b5b5e7cc2bc839339dce8fbc1fb2753 Mon Sep 17 00:00:00 2001 From: Wilson Lee Date: Tue, 19 Dec 2017 20:22:07 -0800 Subject: [PATCH 47/83] doc: auxdisplay: sh1107: Documentation of Sino Wealth SH1107 driver This commit is to add documentation for Sino Wealth SH1107 driver. This commit will provide the required parameters and example of enabling SH1107 in devicetree. Signed-off-by: Wilson Lee Acked-by: Julia Cartwright Natinst-ReviewBoard-ID: 205126 Signed-off-by: Brad Mouring --- .../devicetree/bindings/auxdisplay/sh1107.txt | 12 ++++++++++++ MAINTAINERS | 7 +++++++ 2 files changed, 19 insertions(+) create mode 100644 Documentation/devicetree/bindings/auxdisplay/sh1107.txt diff --git a/Documentation/devicetree/bindings/auxdisplay/sh1107.txt b/Documentation/devicetree/bindings/auxdisplay/sh1107.txt new file mode 100644 index 0000000000000..fa288b0c67058 --- /dev/null +++ b/Documentation/devicetree/bindings/auxdisplay/sh1107.txt @@ -0,0 +1,12 @@ +Binding for Sinowealth OLED driver + +Required properties: + - compatible: Compatibility string. Must be "sinowealth,sh1107". + - reg : i2c address of Truly OLED module (0x3C or 0x3D) + +Example: + + oleddriver@3C { + compatible = "sinowealth,sh1107"; + reg = <0x3C>; + }; diff --git a/MAINTAINERS b/MAINTAINERS index 554e881b05bea..e8a39b7879eda 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -23452,6 +23452,13 @@ S: Orphan F: drivers/media/platform/renesas/sh_vou.c F: include/media/drv-intf/sh_vou.h +SH1107 OLED CONTROLLER DRIVER +M: Wilson Lee +S: Maintained +F: Documentation/devicetree/bindings/auxdisplay/sh1107.txt +F: drivers/auxdisplay/sh1107.c +F: drivers/auxdisplay/sh1107.h + SI2157 MEDIA DRIVER L: linux-media@vger.kernel.org S: Orphan From 706ba6c8756686c827112aa9342668a6e3b71bdc Mon Sep 17 00:00:00 2001 From: Wilson Lee Date: Tue, 19 Dec 2017 20:28:21 -0800 Subject: [PATCH 48/83] auxdisplay: oel9m1027: Truly OEL9M1027 OLED module driver Truly OEL9M1027 OLED display module are not supported at this moment. This commit is to add driver to support Truly OEL9M1027 OLED module. This driver will interact with Sino Wealth SH1107 driver and provide a framebuffer to userspace (/dev/fbX) for user application to interact with OLED display. Cc: Miguel Ojeda Sandonis Cc: Greg Kroah-Hartman Signed-off-by: Wilson Lee Acked-by: Julia Cartwright Natinst-ReviewBoard-ID: 205126 Signed-off-by: Brad Mouring [cvadrevu: Fixed trivial conflicts due to newer module] [cvadrevu: Kconfig: Changed --help-- to help] [cvadrevu: Kconfig: Updated to use FB_SYSMEM_FOPS due to 27ad64eac10f ("fbdev: Rename FB_SYS_FOPS token to FB_SYSMEM_FOPS")] [cvadrevu: Update oel9m1027_remove args for 6.18 kernel] [cvadrevu: Remove FBINFO_FLAG_DEFAULT as per 8a4675ebbd30 ("fbdev: Remove FBINFO_FLAG_DEFAULT from framebuffer_alloc()'ed structs")] Signed-off-by: Chaitanya Vadrevu oel9m1027_core: Fix build. Not sure if changes are correct. TODO --- drivers/auxdisplay/Kconfig | 24 +++ drivers/auxdisplay/Makefile | 2 + drivers/auxdisplay/oel9m1027.h | 83 +++++++ drivers/auxdisplay/oel9m1027_core.c | 323 ++++++++++++++++++++++++++++ drivers/auxdisplay/oel9m1027_fb.c | 169 +++++++++++++++ 5 files changed, 601 insertions(+) create mode 100644 drivers/auxdisplay/oel9m1027.h create mode 100644 drivers/auxdisplay/oel9m1027_core.c create mode 100644 drivers/auxdisplay/oel9m1027_fb.c diff --git a/drivers/auxdisplay/Kconfig b/drivers/auxdisplay/Kconfig index 7d7deda52488c..dc372cd227ad4 100644 --- a/drivers/auxdisplay/Kconfig +++ b/drivers/auxdisplay/Kconfig @@ -513,6 +513,30 @@ config HT16K33 Say yes here to add support for Holtek HT16K33, RAM mapping 16*8 LED controller driver with keyscan. +config OEL9M1027 + tristate "OEL9M1027 LCD" + depends on FB + depends on SH1107 + select FB_SYS_FILLRECT + select FB_SYS_COPYAREA + select FB_SYS_IMAGEBLIT + select FB_SYSMEM_FOPS + default n + help + If you have a Truly 64x128 2-color LCD, OEL9M1027 Series, + say Y. You also need the sh1107 LCD Controller driver. + + Depends on the framebuffer support. + + The LCD framebuffer driver can be attached to a console. + It will work fine. However, you can't attach it to the fbdev driver + of the xorg server. + + To compile this as a module, choose M here: + the modules will be called oel9m1027 and oel9m1027fb. + + If unsure, say N. + config MAX6959 tristate "Maxim MAX6958/6959 7-segment LED controller" depends on I2C diff --git a/drivers/auxdisplay/Makefile b/drivers/auxdisplay/Makefile index c75b396bb42b9..c3e12065a2176 100644 --- a/drivers/auxdisplay/Makefile +++ b/drivers/auxdisplay/Makefile @@ -17,3 +17,5 @@ obj-$(CONFIG_MAX6959) += max6959.o obj-$(CONFIG_PARPORT_PANEL) += panel.o obj-$(CONFIG_SEG_LED_GPIO) += seg-led-gpio.o obj-$(CONFIG_SH1107) += sh1107.o +obj-$(CONFIG_OEL9M1027) += oel9m1027.o +oel9m1027-y += oel9m1027_core.o oel9m1027_fb.o diff --git a/drivers/auxdisplay/oel9m1027.h b/drivers/auxdisplay/oel9m1027.h new file mode 100644 index 0000000000000..ba8fa8caacb0e --- /dev/null +++ b/drivers/auxdisplay/oel9m1027.h @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2017 National Instruments Corp. + * + * Based on cfag12864b driver (v0.1.0) + * Copyright (C) 2006 by Miguel Ojeda Sandonis + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _OEL9M1027_H_ +#define _OEL9M1027_H_ + +#define OEL9M1027_WIDTH (64) +#define OEL9M1027_HEIGHT (128) + +#define OEL9M1027_PAGES (16) +#define OEL9M1027_ADDRESSES (64) +#define OEL9M1027_ADDRESSES_OFFSET (32) +#define OEL9M1027_SIZE ((OEL9M1027_PAGES) * \ + (OEL9M1027_ADDRESSES)) + +#define OEL9M1027_DISPLAYON 1 +#define OEL9M1027_DISPLAYOFF 0 +#define OEL9M1027_DISPNORMAL 0 +#define OEL9M1027_DISPINVERT 1 + +/* + * Default parameter that recommended by Truly manufacturer. + * + * Don't change if you unsure. This value is sufficient by + * default. + */ +#define OEL9M1027_DEF_MULTIRATIO 0x3F +#define OEL9M1027_DEF_DISPFREQ 0xF1 +#define OEL9M1027_DEF_SCANDIR 0x00 +#define OEL9M1027_DEF_DISPOFFSET 0x60 +#define OEL9M1027_DEF_STARTLINE 0x20 +#define OEL9M1027_DEF_ADDRMODE 0x00 +#define OEL9M1027_DEF_CONTRAST 0xFF +#define OEL9M1027_DEF_SEGREMAP 0x00 +#define OEL9M1027_DEF_DCCONTROL 0x0A +#define OEL9M1027_DEF_PHASEPERIOD 0x22 +#define OEL9M1027_DEF_VCOMCONTROL 0x35 + +/* + * OEL9M1027 device private data + */ +struct oel9m1027 { + struct device *dev; /* oel9m1027 device */ + struct sh1107 *sh; /* sh1107 privdata */ + + struct fb_info *fb; /* oel9m1027 framebuffer info */ + unsigned char *framebuffer; + + unsigned char contrast; /* oled display contrast */ + + struct delayed_work dwork; /* oled update worker */ + struct mutex lock; +}; + +/* + * Register OEL9M1027 framebuffer device + * + * Returns 0 if registered successfully, + * or != 0 if failed to register. + */ +int oel9m1027fb_init(struct oel9m1027 *oled); + +/* + * Remove OEL9M1027 framebuffer device + */ +void oel9m1027fb_exit(struct oel9m1027 *oled); + +#endif /* _OEL9M1027_H_ */ + diff --git a/drivers/auxdisplay/oel9m1027_core.c b/drivers/auxdisplay/oel9m1027_core.c new file mode 100644 index 0000000000000..4f30c320a89e9 --- /dev/null +++ b/drivers/auxdisplay/oel9m1027_core.c @@ -0,0 +1,323 @@ +/* + * Copyright (C) 2017 National Instruments Corp. + * + * Based on cfag12864b driver (v0.1.0) + * Copyright (C) 2006 by Miguel Ojeda Sandonis + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "sh1107.h" +#include "oel9m1027.h" + +/* + * OEL9M1027 Internal Commands + */ + +static int oel9m1027_clear(struct oel9m1027 *oled) +{ + unsigned char i, j; + int ret; + + mutex_lock(&oled->lock); + + for (i = 0; i < OEL9M1027_PAGES; i++) { + ret = sh1107_page(oled->sh, i); + if (ret) + goto fail; + + ret = sh1107_address(oled->sh, OEL9M1027_ADDRESSES_OFFSET); + if (ret) + goto fail; + + for (j = 0; j < OEL9M1027_ADDRESSES; j++) { + ret = sh1107_writedata(oled->sh, 0); + if (ret) + goto fail; + } + } + +fail: + mutex_unlock(&oled->lock); + return ret; +} + +static int oel9m1027_off(struct oel9m1027 *oled) +{ + int ret; + + mutex_lock(&oled->lock); + ret = sh1107_displaystate(oled->sh, OEL9M1027_DISPLAYOFF); + mutex_unlock(&oled->lock); + + return ret; +} + +static int oel9m1027_on(struct oel9m1027 *oled) +{ + int ret; + + mutex_lock(&oled->lock); + + ret = sh1107_multiplexratio(oled->sh, OEL9M1027_DEF_MULTIRATIO); + if (ret) + goto fail; + + ret = sh1107_displayfreq(oled->sh, OEL9M1027_DEF_DISPFREQ); + if (ret) + goto fail; + + ret = sh1107_scandir(oled->sh, OEL9M1027_DEF_SCANDIR); + if (ret) + goto fail; + + ret = sh1107_offset(oled->sh, OEL9M1027_DEF_DISPOFFSET); + if (ret) + goto fail; + + ret = sh1107_startline(oled->sh, OEL9M1027_DEF_STARTLINE); + if (ret) + goto fail; + + ret = sh1107_addressingmode(oled->sh, OEL9M1027_DEF_ADDRMODE); + if (ret) + goto fail; + + ret = sh1107_displaycontrast(oled->sh, oled->contrast); + if (ret) + goto fail; + + ret = sh1107_segremap(oled->sh, OEL9M1027_DEF_SEGREMAP); + if (ret) + goto fail; + + ret = sh1107_entiredisplaystate(oled->sh, OEL9M1027_DISPLAYOFF); + if (ret) + goto fail; + + ret = sh1107_displayinvert(oled->sh, OEL9M1027_DISPNORMAL); + if (ret) + goto fail; + + ret = sh1107_dccontrol(oled->sh, OEL9M1027_DEF_DCCONTROL); + if (ret) + goto fail; + + ret = sh1107_phaseperiod(oled->sh, OEL9M1027_DEF_PHASEPERIOD); + if (ret) + goto fail; + + ret = sh1107_vcomcontrol(oled->sh, OEL9M1027_DEF_VCOMCONTROL); + if (ret) + goto fail; + + ret = sh1107_displaystate(oled->sh, OEL9M1027_DISPLAYON); + if (ret) + goto fail; + +fail: + mutex_unlock(&oled->lock); + return ret; +} + +static void oel9m1027_update(struct work_struct *work) +{ + struct oel9m1027 *oled = container_of(to_delayed_work(work), + struct oel9m1027, + dwork); + unsigned short page, addr, bit; + unsigned char c_buff; + unsigned int pos; + int ret; + + mutex_lock(&oled->lock); + + for (page = 0; page < OEL9M1027_PAGES; page++) { + ret = sh1107_page(oled->sh, page); + if (ret) + goto fail; + + ret = sh1107_address(oled->sh, + OEL9M1027_ADDRESSES_OFFSET); + if (ret) + goto fail; + + for (addr = 0; addr < OEL9M1027_ADDRESSES; addr++) { + for (c_buff = 0, bit = 0; bit < 8; bit++) { + pos = addr / 8 + (page * 8 + bit) * + OEL9M1027_WIDTH / 8; + + if (oled->framebuffer[pos] & BIT(addr % 8)) + c_buff |= BIT(bit); + } + + ret = sh1107_writedata(oled->sh, c_buff); + if (ret) + goto fail; + } + } + + mutex_unlock(&oled->lock); + return; + +fail: + mutex_unlock(&oled->lock); + + /* Error occur, retry after 100ms */ + dev_warn(oled->dev, "ERROR: OLED update fail.\n"); + queue_delayed_work(system_wq, &oled->dwork, HZ / 10); +} + +static ssize_t oel9m1027_contrast_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct oel9m1027 *oled = dev_get_drvdata(dev); + + return sprintf(buf, "%d\n", oled->contrast); +} + +static ssize_t oel9m1027_contrast_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct oel9m1027 *oled = dev_get_drvdata(dev); + int ret; + + ret = kstrtou8(buf, 10, &oled->contrast); + if (ret) + return -EINVAL; + + /* Restart for new contrast setting to take effect */ + ret = oel9m1027_off(oled); + if (ret) + return ret; + + ret = oel9m1027_on(oled); + + return ret ? ret : count; +} + +static DEVICE_ATTR(contrast, 0644, oel9m1027_contrast_show, + oel9m1027_contrast_store); + +static int oel9m1027_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct oel9m1027 *oled; + int ret; + + oled = devm_kzalloc(dev, sizeof(*oled), GFP_KERNEL); + if (!oled) { + ret = -ENOMEM; + goto none; + } + + platform_set_drvdata(pdev, oled); + oled->dev = dev; + oled->sh = dev_get_drvdata(dev->parent); + mutex_init(&oled->lock); + oled->contrast = OEL9M1027_DEF_CONTRAST; + + ret = device_create_file(dev, &dev_attr_contrast); + if (ret) { + dev_warn(dev, "ERROR: OLED sysfs create fail.\n"); + goto mutexcreated; + } + + ret = oel9m1027_off(oled); + if (ret) { + dev_warn(dev, "ERROR: OLED switch off fail.\n"); + goto mutexcreated; + } + + ret = oel9m1027_clear(oled); + if (ret) { + dev_warn(dev, "ERROR: OLED buffer clear fail.\n"); + goto mutexcreated; + } + + ret = oel9m1027_on(oled); + if (ret) { + dev_err(dev, "ERROR: OLED switch on fail.\n"); + goto mutexcreated; + } + + INIT_DELAYED_WORK(&oled->dwork, oel9m1027_update); + + ret = oel9m1027fb_init(oled); + if (ret) { + dev_err(dev, "ERROR: can't initialize framebuffer\n"); + goto oledturnedon; + } + + return 0; + +oledturnedon: + oel9m1027_off(oled); + +mutexcreated: + mutex_destroy(&oled->lock); + +none: + return ret; +} + +static void oel9m1027_remove(struct platform_device *pdev) +{ + struct oel9m1027 *oled = platform_get_drvdata(pdev); + + oel9m1027fb_exit(oled); + flush_delayed_work(&oled->dwork); + cancel_delayed_work_sync(&oled->dwork); + oel9m1027_off(oled); + mutex_destroy(&oled->lock); +} + +static const struct of_device_id oel9m1027_of_match[] = { + { .compatible = "truly,oel9m1027" }, + { }, +}; +MODULE_DEVICE_TABLE(of, oel9m1027_of_match); + +static struct platform_driver oel9m1027_driver = { + .probe = oel9m1027_probe, + .remove = oel9m1027_remove, + .driver = { + .name = KBUILD_MODNAME, + .of_match_table = oel9m1027_of_match, + }, +}; + +module_platform_driver(oel9m1027_driver); + +MODULE_DESCRIPTION("OEL9M1027 OLED driver"); +MODULE_AUTHOR("Wilson Lee "); +MODULE_LICENSE("GPL"); diff --git a/drivers/auxdisplay/oel9m1027_fb.c b/drivers/auxdisplay/oel9m1027_fb.c new file mode 100644 index 0000000000000..76f7bd5922e53 --- /dev/null +++ b/drivers/auxdisplay/oel9m1027_fb.c @@ -0,0 +1,169 @@ +/* + * Copyright (C) 2017 National Instruments Corp. + * + * Based on cfag12864b driver (v0.1.0) + * Copyright (C) 2006 by Miguel Ojeda Sandonis + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "oel9m1027.h" + +static ssize_t oel9m1027fb_write(struct fb_info *fb, + const char __user *buf, + size_t count, loff_t *ppos) +{ + struct oel9m1027 *oled = dev_get_drvdata(fb->device); + ssize_t ret; + + ret = fb_sys_write(fb, buf, count, ppos); + if (ret < 0) + return ret; + + queue_delayed_work(system_wq, &oled->dwork, 0); + return ret; +} + +static void oel9m1027fb_fillrect(struct fb_info *fb, + const struct fb_fillrect *rect) +{ + struct oel9m1027 *oled = dev_get_drvdata(fb->device); + + sys_fillrect(fb, rect); + queue_delayed_work(system_wq, &oled->dwork, 0); +} + +static void oel9m1027fb_copyarea(struct fb_info *fb, + const struct fb_copyarea *area) +{ + struct oel9m1027 *oled = dev_get_drvdata(fb->device); + + sys_copyarea(fb, area); + queue_delayed_work(system_wq, &oled->dwork, 0); +} + +static void oel9m1027fb_imageblit(struct fb_info *fb, + const struct fb_image *image) +{ + struct oel9m1027 *oled = dev_get_drvdata(fb->device); + + sys_imageblit(fb, image); + queue_delayed_work(system_wq, &oled->dwork, 0); +} + +static const struct fb_fix_screeninfo oel9m1027fb_fix = { + .id = "oel9m1027", + .type = FB_TYPE_PACKED_PIXELS, + .visual = FB_VISUAL_MONO10, + .xpanstep = 0, + .ypanstep = 0, + .ywrapstep = 0, + .line_length = OEL9M1027_WIDTH / 8, + .accel = FB_ACCEL_NONE, +}; + +static const struct fb_var_screeninfo oel9m1027fb_var = { + .xres = OEL9M1027_WIDTH, + .yres = OEL9M1027_HEIGHT, + .xres_virtual = OEL9M1027_WIDTH, + .yres_virtual = OEL9M1027_HEIGHT, + .bits_per_pixel = 1, + .red = { 0, 1, 0 }, + .green = { 0, 1, 0 }, + .blue = { 0, 1, 0 }, + .left_margin = 0, + .right_margin = 0, + .upper_margin = 0, + .lower_margin = 0, + .vmode = FB_VMODE_NONINTERLACED, +}; + +static struct fb_ops oel9m1027fb_ops = { + .owner = THIS_MODULE, + .fb_read = fb_sys_read, + .fb_write = oel9m1027fb_write, + .fb_fillrect = oel9m1027fb_fillrect, + .fb_copyarea = oel9m1027fb_copyarea, + .fb_imageblit = oel9m1027fb_imageblit, +}; + +int oel9m1027fb_init(struct oel9m1027 *oled) +{ + int ret; + struct fb_info *fb = framebuffer_alloc(0, oled->dev); + + if (!fb) { + ret = -EINVAL; + goto none; + } + + oled->framebuffer = vzalloc(sizeof(unsigned char) * + OEL9M1027_SIZE); + if (!oled->framebuffer) { + ret = -ENOMEM; + goto fbinfoalloced; + } + + fb->screen_base = (char __iomem *)oled->framebuffer; + fb->screen_size = OEL9M1027_SIZE; + fb->fbops = &oel9m1027fb_ops; + fb->fix = oel9m1027fb_fix; + fb->fix.smem_start = page_to_phys(vmalloc_to_page(oled->framebuffer)); + fb->fix.smem_len = sizeof(unsigned char) * OEL9M1027_SIZE; + fb->var = oel9m1027fb_var; + fb->pseudo_palette = NULL; + fb->par = NULL; + oled->fb = fb; + + if (register_framebuffer(fb) < 0) { + ret = -EINVAL; + goto fballoced; + } + + fb_info(fb, "%s framebuffer device\n", fb->fix.id); + + return 0; + +fballoced: + vfree(oled->framebuffer); + +fbinfoalloced: + framebuffer_release(fb); + +none: + return ret; +} + +void oel9m1027fb_exit(struct oel9m1027 *oled) +{ + unregister_framebuffer(oled->fb); + vfree(oled->framebuffer); + framebuffer_release(oled->fb); +} + +MODULE_DESCRIPTION("OEL9M1027 OLED frame buffer driver"); +MODULE_AUTHOR("Wilson Lee "); +MODULE_LICENSE("GPL"); From 865aa81ffebd7d9fe4d8ae66f6eee19446e94e17 Mon Sep 17 00:00:00 2001 From: Wilson Lee Date: Tue, 19 Dec 2017 20:34:50 -0800 Subject: [PATCH 49/83] doc: auxdisplay: oel9m1027: Documentation of Truly OEL9M1027 driver This commit is to add document for describing Truly OEL9M1027 driver. This commit will specific the required parameter and example for enabling this driver in devicetree. Signed-off-by: Wilson Lee Acked-by: Julia Cartwright Natinst-ReviewBoard-ID: 205126 Signed-off-by: Brad Mouring [cvadrevu: Fixed trivial conflicts due to newer module] Signed-off-by: Chaitanya Vadrevu --- .../devicetree/bindings/auxdisplay/oel9m1027.txt | 15 +++++++++++++++ MAINTAINERS | 8 ++++++++ 2 files changed, 23 insertions(+) create mode 100644 Documentation/devicetree/bindings/auxdisplay/oel9m1027.txt diff --git a/Documentation/devicetree/bindings/auxdisplay/oel9m1027.txt b/Documentation/devicetree/bindings/auxdisplay/oel9m1027.txt new file mode 100644 index 0000000000000..ee0c1a59cadfc --- /dev/null +++ b/Documentation/devicetree/bindings/auxdisplay/oel9m1027.txt @@ -0,0 +1,15 @@ +Binding for OEL9M1027 OLED display module manufactured by Truly + +Required properties: + - compatible : Compatibility string. Must be "truly,oel9m1027". + +Example: + + oleddriver@3C { + compatible = "sinowealth,sh1107"; + reg = <0x3C>; + + oledmodule { + compatible = "truly,oel9m1027"; + }; + }; diff --git a/MAINTAINERS b/MAINTAINERS index e8a39b7879eda..6161a4507e4ec 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -18763,6 +18763,14 @@ F: drivers/misc/ocxl/ F: include/misc/ocxl* F: include/uapi/misc/ocxl.h +OEL9M1027 TRULY OLED MODULE DRIVER +M: Wilson Lee +S: Maintained +F: Documentation/devicetree/bindings/auxdisplay/oel9m1027.txt +F: drivers/auxdisplay/oel9m1027.c +F: drivers/auxdisplay/oel9m1027fb.c +F: drivers/auxdisplay/oel9m1027.h + OMAP AUDIO SUPPORT M: Peter Ujfalusi M: Jarkko Nikula From a4464501b2980e4d8d00028f266106a34f328e40 Mon Sep 17 00:00:00 2001 From: Wilson Lee Date: Mon, 14 Aug 2017 20:22:29 -0700 Subject: [PATCH 50/83] nizynqcpld: Add NI ELVIS III/III+ CPLD support NI ELVIS III was introduced a WiFi LED for display WiFi status. Hence, it required new driver support for NI ELVIS III. Without the new driver support for NI ELVIS III, the CPLD WiFi LED will fail to function. Signed-off-by: Chen Yee Chew Signed-off-by: Wilson Lee Signed-off-by: Brad Mouring Acked-by: Joe Hershberger Acked-by: Chen Yee chew Natinst-ReviewBoard-ID: 206904 --- drivers/misc/nizynqcpld.c | 47 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/drivers/misc/nizynqcpld.c b/drivers/misc/nizynqcpld.c index 5627313f5bf0e..d8734a00f0331 100644 --- a/drivers/misc/nizynqcpld.c +++ b/drivers/misc/nizynqcpld.c @@ -76,6 +76,8 @@ #define MYRIO_WIFISWCTRL_ENRELIRQ 0x04 #define MYRIO_WIFISWCTRL_RELIRQ 0x40 +#define ELVISIII_WIFILEDCTRL_ADDR 0x0A + struct nizynqcpld_led_desc { const char *of_node_name; u8 addr; @@ -1215,6 +1217,37 @@ static struct nizynqcpld_led_desc sol_leds[] = { }, }; +static struct nizynqcpld_led_desc elvisiii_leds[] = { + { + .of_node_name = "status-0", + .addr = DOSX_LED, + .bit = 1 << 2, + .pattern_lo_addr = DOSX_STATUSLEDSHIFTBYTE0, + /* write byte 1 first */ + .pattern_hi_addr = DOSX_STATUSLEDSHIFTBYTE1, + }, + { + .of_node_name = "eth0-0", + .addr = DOSX_ETHERNETLED, + .bit = 1 << 1, + }, + { + .of_node_name = "eth0-1", + .addr = DOSX_ETHERNETLED, + .bit = 1 << 0, + }, + { + .of_node_name = "wifi-0", + .addr = ELVISIII_WIFILEDCTRL_ADDR, + .bit = 1 << 1, + }, + { + .of_node_name = "wifi-1", + .addr = ELVISIII_WIFILEDCTRL_ADDR, + .bit = 1 << 0, + }, +}; + static struct nizynqcpld_watchdog_desc dosxv4_watchdog_desc = { .watchdog_period_ns = 24000, }; @@ -1333,6 +1366,20 @@ static struct nizynqcpld_desc nizynqcpld_descs[] = { .switch_addr = PROTO_PROCESSORMODE, .watchdog_addr = DOSX_WATCHDOGCONTROL, }, + /* ELVIS III CPLD */ + { + .attrs = dosequis6_attrs, + .supported_version = 1, + .supported_product = 6, + .watchdog_desc = &dosxv5_watchdog_desc, + .led_descs = elvisiii_leds, + .num_led_descs = ARRAY_SIZE(elvisiii_leds), + .reboot_addr = DOSX_PROCESSORRESET, + .scratch_hr_addr = DOSX_SCRATCHPADHR, + .scratch_sr_addr = DOSX_SCRATCHPADSR, + .switch_addr = PROTO_PROCESSORMODE, + .watchdog_addr = DOSX_WATCHDOGCONTROL, + }, }; static void wifi_sw_work_func(struct work_struct *work) From 42a0bf751b44cf71c9cfb50fbe9782f6aa72b3c1 Mon Sep 17 00:00:00 2001 From: Nathan Sullivan Date: Tue, 9 Dec 2014 11:18:32 -0600 Subject: [PATCH 51/83] macb: Handle FPGA reprogramming notifications Add support for taking Ethernet down and up when the FPGA is reloaded. Signed-off-by: Nathan Sullivan Acked-by: Jaeden Amero Acked-by: Ben Shelton Natinst-ReviewBoard-ID: 84654 Natinst-ReviewBoard-ID: 99911 Natinst-CAR-ID: 528734 Natinst-CAR-ID: 527188 (joshc: minor checkpatch cleanups) Signed-off-by: Josh Cartwright [cvadrevu: Fixed trivial merge conflicts] [cvadrevu: Make macb_fpga_notifier static to avoid build warning] Signed-off-by: Chaitanya Vadrevu macb_main: Add declaration for macb_fpga_notifier. TODO: fixup original commit later --- drivers/net/ethernet/cadence/macb.h | 5 ++ drivers/net/ethernet/cadence/macb_main.c | 91 ++++++++++++++++++++++++ 2 files changed, 96 insertions(+) diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h index 0830c48973aa0..6c99417898860 100644 --- a/drivers/net/ethernet/cadence/macb.h +++ b/drivers/net/ethernet/cadence/macb.h @@ -1317,6 +1317,11 @@ struct macb { struct gem_stats gem; } hw_stats; +#ifdef CONFIG_FPGA_PERIPHERAL + struct notifier_block fpga_notifier; + bool fpga_down; +#endif + struct macb_or_gem_ops macbgem_ops; struct mii_bus *mii_bus; diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c index 17d4a3e039458..e3d39f0d20cab 100644 --- a/drivers/net/ethernet/cadence/macb_main.c +++ b/drivers/net/ethernet/cadence/macb_main.c @@ -39,6 +39,12 @@ #include #include #include + +#ifdef CONFIG_FPGA_PERIPHERAL +#include +#include +#endif + #include "macb.h" /* This structure is only used for MACB on SiFive FU540 devices */ @@ -3076,6 +3082,15 @@ static int macb_open(struct net_device *dev) if (err < 0) return err; +#ifdef CONFIG_FPGA_PERIPHERAL + /* If we're being opened while the FPGA is being reprogrammed, we can + * just return. The interface will be brought up when the FPGA is back + * up. + */ + if (bp->fpga_down) + return 0; +#endif + /* RX buffers initialization */ macb_init_rx_buffer_size(bp, bufsz); @@ -3133,6 +3148,14 @@ static int macb_close(struct net_device *dev) unsigned long flags; unsigned int q; +#ifdef CONFIG_FPGA_PERIPHERAL + /* If we're being closed while the FPGA is being reprogrammed, the + * interface is already down. We can just return. + */ + if (bp->fpga_down) + return 0; +#endif + netif_tx_stop_all_queues(dev); for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) { @@ -4436,6 +4459,60 @@ static const struct net_device_ops macb_netdev_ops = { .ndo_setup_tc = macb_setup_tc, }; +#ifdef CONFIG_FPGA_PERIPHERAL +static int macb_fpga_notifier(struct notifier_block *nb, unsigned long val, void *data) +{ + struct macb *bp = container_of(nb, struct macb, fpga_notifier); + + switch (val) { + case FPGA_PERIPHERAL_DOWN: + netdev_dbg(bp->dev, + "macb_fpga_notifier: going down\n"); + + /* Synchronize with macb_open/close. */ + rtnl_lock(); + if (!bp->fpga_down) { + /* If the interface has been opened. */ + if (netif_running(bp->dev)) + macb_close(bp->dev); + + bp->fpga_down = 1; + } + rtnl_unlock(); + break; + + case FPGA_PERIPHERAL_UP: + netdev_dbg(bp->dev, + "macb_fpga_notifier: coming up\n"); + + BUG_ON(!bp->fpga_down); + + /* Synchronize with macb_open/close. */ + rtnl_lock(); + + bp->fpga_down = 0; + + /* If the interface has been opened. */ + if (netif_running(bp->dev)) + macb_open(bp->dev); + + rtnl_unlock(); + break; + + case FPGA_PERIPHERAL_FAILED: + /* This interface is not coming back up. */ + break; + + default: + netdev_err(bp->dev, + "unsupported FPGA notifier value %lu\n", val); + break; + } + + return notifier_from_errno(0); +} +#endif + /* Configure peripheral capabilities according to device tree * and integration options used */ @@ -4617,6 +4694,14 @@ static int macb_init(struct platform_device *pdev) bp->tx_ring_size = DEFAULT_TX_RING_SIZE; bp->rx_ring_size = DEFAULT_RX_RING_SIZE; +#ifdef CONFIG_FPGA_PERIPHERAL + bp->fpga_notifier.notifier_call = macb_fpga_notifier; + + blocking_notifier_chain_register( + &fpgaperipheral_notifier_list, + &bp->fpga_notifier); +#endif + /* set the queue register mapping once for all: queue0 has a special * register mapping but we don't want to test the queue index then * compute the corresponding register offset at run time. @@ -5750,6 +5835,12 @@ static void macb_remove(struct platform_device *pdev) if (dev) { bp = netdev_priv(dev); + +#ifdef CONFIG_FPGA_PERIPHERAL + blocking_notifier_chain_unregister( + &fpgaperipheral_notifier_list, &bp->fpga_notifier); +#endif + unregister_netdev(dev); phy_exit(bp->sgmii_phy); mdiobus_unregister(bp->mii_bus); From ec1430f0ade1dc01c611a40e9bb49685dd49e5e1 Mon Sep 17 00:00:00 2001 From: Mihai Neagu Date: Thu, 12 Mar 2015 18:53:00 +0200 Subject: [PATCH 52/83] HACK net/macb: Totally disable TX checksum offloading Since hardware checksumming is not supported, reset the TXCOEN bit in DMACFG. If unitialized, this bit causes checksum offloading to be left on in hardware, with software thinking it is off, and for a checksum offloading bug in hardware to cause small UDP packets (<= 2 bytes) to be sent with an incorrect checksum (0xffff). We can't fix this problem by zeroing the checksum field in outgoing UDPv4 packets as implemented by Jeff Westfahl or Xilinx in their xemacps driver because it breaks packet forwarding (where it is illegal to modify the checksum of forwarded packets with unknown validity). We don't yet know a way to fix this problem other than to not use hardware checksum offloading. This commit will need to be reworked before it is upstreamable. We just need a fix in the LabVIEW RT Linux kernel right now for release. Ideally, we'd continue to work with upstream to solve the problem, but this is an emergency and we need to test and ship right away. Signed-off-by: Mihai Neagu Signed-off-by: Jaeden Amero Reviewed-by: Ben Shelton Reviewed-by: Josh Cartwright Natinst-CAR-ID: 516373 Natinst-ReviewBoard-ID: 97988 (joshc: also hack up hw_features to never advertise hw csum support) Signed-off-by: Josh Cartwright --- drivers/net/ethernet/cadence/macb_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c index e3d39f0d20cab..5128c08a7d614 100644 --- a/drivers/net/ethernet/cadence/macb_main.c +++ b/drivers/net/ethernet/cadence/macb_main.c @@ -2894,7 +2894,7 @@ static void macb_configure_dma(struct macb *bp) else dmacfg |= GEM_BIT(ENDIA_DESC); /* CPU in big endian */ - if (bp->dev->features & NETIF_F_HW_CSUM) + if (0 && bp->dev->features & NETIF_F_HW_CSUM) dmacfg |= GEM_BIT(TXCOEN); else dmacfg &= ~GEM_BIT(TXCOEN); @@ -4785,7 +4785,7 @@ static int macb_init(struct platform_device *pdev) dev->hw_features |= MACB_NETIF_LSO; /* Checksum offload is only available on gem with packet buffer */ - if (macb_is_gem(bp) && !(bp->caps & MACB_CAPS_FIFO_MODE)) + if (0 && macb_is_gem(bp) && !(bp->caps & MACB_CAPS_FIFO_MODE)) dev->hw_features |= NETIF_F_HW_CSUM | NETIF_F_RXCSUM; if (bp->caps & MACB_CAPS_SG_DISABLED) dev->hw_features &= ~NETIF_F_SG; From c6b16c27d15ac8e5f5b84e4017db147fc72c8d9d Mon Sep 17 00:00:00 2001 From: Nathan Sullivan Date: Tue, 19 May 2015 13:37:07 -0500 Subject: [PATCH 53/83] net: macb: Disable phy interrupts during FPGA load Even when the PHY is stopped by macb_close, it still hangs on to its irq. Explicitly call phy_stop_interrupts to make sure the interrupt line is ignored while the FPGA is reloading to avoid interrupt storms from floating lines. Signed-off-by: Nathan Sullivan Reviewed-by: Ben Shelton Reviewed-by: Jaeden Amero Natinst-ReviewBoard-ID: 98279 --- drivers/net/ethernet/cadence/macb_main.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c index 5128c08a7d614..2545ab90ac830 100644 --- a/drivers/net/ethernet/cadence/macb_main.c +++ b/drivers/net/ethernet/cadence/macb_main.c @@ -4463,6 +4463,7 @@ static const struct net_device_ops macb_netdev_ops = { static int macb_fpga_notifier(struct notifier_block *nb, unsigned long val, void *data) { struct macb *bp = container_of(nb, struct macb, fpga_notifier); + struct net_device *dev = bp->dev; switch (val) { case FPGA_PERIPHERAL_DOWN: @@ -4473,8 +4474,11 @@ static int macb_fpga_notifier(struct notifier_block *nb, unsigned long val, void rtnl_lock(); if (!bp->fpga_down) { /* If the interface has been opened. */ - if (netif_running(bp->dev)) + if (netif_running(bp->dev)) { macb_close(bp->dev); + phy_stop_interrupts(dev->phydev); + phy_stop_machine(dev->phydev); + } bp->fpga_down = 1; } @@ -4493,8 +4497,11 @@ static int macb_fpga_notifier(struct notifier_block *nb, unsigned long val, void bp->fpga_down = 0; /* If the interface has been opened. */ - if (netif_running(bp->dev)) + if (netif_running(bp->dev)) { + phy_start_machine(dev->phydev); + phy_start_interrupts(dev->phydev); macb_open(bp->dev); + } rtnl_unlock(); break; From 7c59eb4fbd80ba4054a978219bfd311eef40cb27 Mon Sep 17 00:00:00 2001 From: Nathan Sullivan Date: Thu, 4 Jan 2018 13:04:09 -0600 Subject: [PATCH 54/83] phy: add phy_stop_machine_nolink This function stops the PHY state machine, but without running the machine. Ever since 7ad813f20, phy_stop_machine runs it and brings the link down, which isn't always what you want. Signed-off-by: Nathan Sullivan Signed-off-by: Brad Mouring Acked-by: James Minor Natinst-ReviewBoard-ID: 214996 [cvadrevu: Fixed trivial conflicts with 59088b5a946: ("net: phy: avoid kernel warning dump when stopping an errored PHY") a3320bcf28e: ("net: phy: make phy_trigger_machine static")] Signed-off-by: Chaitanya Vadrevu --- drivers/net/phy/phy.c | 19 +++++++++++++++++++ include/linux/phy.h | 1 + 2 files changed, 20 insertions(+) diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 02da4a203ddd4..8201ec5db7b78 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -1347,6 +1347,25 @@ static void phy_error_precise(struct phy_device *phydev, phy_process_error(phydev); } +/** + * phy_stop_machine_nolink - stop the PHY state machine tracking + * @phydev: target phy_device struct + * + * Description: Stops the state machine timer, sets the state to UP + * (unless it wasn't up yet). This function must be called BEFORE + * phy_detach. Does not run the state machine to avoid taking the + * link down. + */ +void phy_stop_machine_nolink(struct phy_device *phydev) +{ + cancel_delayed_work_sync(&phydev->state_queue); + + mutex_lock(&phydev->lock); + if (phydev->state > PHY_UP && phydev->state != PHY_HALTED) + phydev->state = PHY_UP; + mutex_unlock(&phydev->lock); +} + /** * phy_error - enter ERROR state for this PHY device * @phydev: target phy_device struct diff --git a/include/linux/phy.h b/include/linux/phy.h index 0bc00a4cceb24..6ad414f0bc712 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -2042,6 +2042,7 @@ void phy_trigger_machine(struct phy_device *phydev); void phy_mac_interrupt(struct phy_device *phydev); void phy_start_machine(struct phy_device *phydev); void phy_stop_machine(struct phy_device *phydev); +void phy_stop_machine_nolink(struct phy_device *phydev); void phy_ethtool_ksettings_get(struct phy_device *phydev, struct ethtool_link_ksettings *cmd); int phy_ethtool_ksettings_set(struct phy_device *phydev, From f9f69b3e9db0c2f4c74dcecb2cc5046b31ef735a Mon Sep 17 00:00:00 2001 From: Nathan Sullivan Date: Thu, 4 Jan 2018 13:06:46 -0600 Subject: [PATCH 55/83] macb: call phy_stop_machine_nolink Use this new function to avoid bringing the link down when an FPGA bitfile is loaded. This minimizes the time spent with no network afterwards. Signed-off-by: Nathan Sullivan Signed-off-by: Brad Mouring Acked-by: James Minor Natinst-ReviewBoard-ID: 214996 --- drivers/net/ethernet/cadence/macb_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c index 2545ab90ac830..6c8166ea5aed8 100644 --- a/drivers/net/ethernet/cadence/macb_main.c +++ b/drivers/net/ethernet/cadence/macb_main.c @@ -4477,7 +4477,7 @@ static int macb_fpga_notifier(struct notifier_block *nb, unsigned long val, void if (netif_running(bp->dev)) { macb_close(bp->dev); phy_stop_interrupts(dev->phydev); - phy_stop_machine(dev->phydev); + phy_stop_machine_nolink(dev->phydev); } bp->fpga_down = 1; From a4e9ec389438d7185c4f58e2f679bd0142e09055 Mon Sep 17 00:00:00 2001 From: Nathan Sullivan Date: Tue, 30 Jan 2018 13:42:20 -0600 Subject: [PATCH 56/83] macb: deactivate queues in fpga notifier In order to synchronize macb_stop and macb_start_xmit, turn all the tx queues off before going down and back on again before going up during FPGA reloads. Not synchronizing these functions would result in a crash during the reload if frames are transmitted. Signed-off-by: Nathan Sullivan Signed-off-by: Brad Mouring Acked-by: Zach Brown Acked-by: James Minor Natinst-ReviewBoard-ID: 218609 Natinst-CAR-ID: 672398 --- drivers/net/ethernet/cadence/macb_main.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c index 6c8166ea5aed8..475defef6ecf0 100644 --- a/drivers/net/ethernet/cadence/macb_main.c +++ b/drivers/net/ethernet/cadence/macb_main.c @@ -42,6 +42,7 @@ #ifdef CONFIG_FPGA_PERIPHERAL #include +#include #include #endif @@ -4475,6 +4476,7 @@ static int macb_fpga_notifier(struct notifier_block *nb, unsigned long val, void if (!bp->fpga_down) { /* If the interface has been opened. */ if (netif_running(bp->dev)) { + dev_deactivate(bp->dev); macb_close(bp->dev); phy_stop_interrupts(dev->phydev); phy_stop_machine_nolink(dev->phydev); @@ -4501,6 +4503,7 @@ static int macb_fpga_notifier(struct notifier_block *nb, unsigned long val, void phy_start_machine(dev->phydev); phy_start_interrupts(dev->phydev); macb_open(bp->dev); + dev_activate(bp->dev); } rtnl_unlock(); From 559772280e34beb313259fef5e47668363a1ee0c Mon Sep 17 00:00:00 2001 From: James Minor Date: Mon, 2 Mar 2015 14:37:42 -0600 Subject: [PATCH 57/83] wl12xx: Disable uncalibrated channel 14 (not supported on LSR) NI uses a module from LSR that does not have calibration constants for channel 14. As such, channel 14 should never be used. This change is to retain parity with NI's shipped 3.2 kernel for purposes of compliance, so it should not be upstreamed. Signed-off-by: James Minor --- drivers/net/wireless/ti/wlcore/main.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index bdb06584d7e45..057bc2cec0690 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -5933,7 +5933,6 @@ static struct ieee80211_channel wl1271_channels[] = { { .hw_value = 11, .center_freq = 2462, .max_power = WLCORE_MAX_TXPWR }, { .hw_value = 12, .center_freq = 2467, .max_power = WLCORE_MAX_TXPWR }, { .hw_value = 13, .center_freq = 2472, .max_power = WLCORE_MAX_TXPWR }, - { .hw_value = 14, .center_freq = 2484, .max_power = WLCORE_MAX_TXPWR }, }; /* can't be const, mac80211 writes to this */ From c9b1159ce9376d24c655493537fc10960fb71215 Mon Sep 17 00:00:00 2001 From: James Minor Date: Tue, 3 Mar 2015 12:20:11 -0600 Subject: [PATCH 58/83] wl12xx: Disallow channels above 11 until beacons are seen In order to prevent us from sending out anything on channels that are illegal in some countries, we wait until we see beacons from the AP before trying to connect on those channels. This change is to retain parity with NI's shipped 3.2 kernel for purposes of compliance, so it should not be upstreamed. Signed-off-by: Tim Ousley [reworked for 3.14 branch and for coding style ] Signed-off-by: James Minor --- drivers/net/wireless/ti/wlcore/main.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index 057bc2cec0690..2bbd4797a0ce4 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -32,6 +32,8 @@ #define WL1271_BOOT_RETRIES 3 #define WL1271_WAKEUP_TIMEOUT 500 +#define MAX_GLOBAL_80211_ISM_CENTER_FREQ 2462 + static char *fwlog_param; static int fwlog_mem_blocks = -1; static int bug_on_recovery = -1; @@ -67,6 +69,9 @@ static int wl12xx_set_authorized(struct wl1271 *wl, struct wl12xx_vif *wlvif) static void wl1271_reg_notify(struct wiphy *wiphy, struct regulatory_request *request) { + struct ieee80211_supported_band *band; + struct ieee80211_channel *ch; + int i; struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); struct wl1271 *wl = hw->priv; @@ -74,6 +79,18 @@ static void wl1271_reg_notify(struct wiphy *wiphy, if (request) wl->dfs_region = request->dfs_region; + /* Never speak first on channels 12, 13, and 14 even if + * the user hints that it's OK + */ + band = wiphy->bands[IEEE80211_BAND_2GHZ]; + for (i = 0; i < band->n_channels; i++) { + ch = &band->channels[i]; + if (ch->flags & IEEE80211_CHAN_DISABLED) + continue; + if (ch->center_freq > MAX_GLOBAL_80211_ISM_CENTER_FREQ) + ch->flags |= IEEE80211_CHAN_NO_IR; + } + wlcore_regdomain_config(wl); } From 6aad9eea6aa917035a5d0a396fbb23d6745fe8d8 Mon Sep 17 00:00:00 2001 From: Gratian Crisan Date: Tue, 3 Mar 2015 12:20:11 -0600 Subject: [PATCH 59/83] wl12xx: Switch to using nl80211_band enum Commit 57fbcce37be7 ("cfg80211: remove enum ieee80211_band") upstream removed the ieee80211_band enum in favour of using the nl80211_band enum directly. Convert the TI wl12xx driver's use of ieee80211_band to nl80211_band enum. Fixes: ce3a405b2e61 ("wl12xx: Disallow channels above 11 until beacons are seen") Signed-off-by: Gratian Crisan --- drivers/net/wireless/ti/wlcore/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index 2bbd4797a0ce4..7ecd32672146a 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -82,7 +82,7 @@ static void wl1271_reg_notify(struct wiphy *wiphy, /* Never speak first on channels 12, 13, and 14 even if * the user hints that it's OK */ - band = wiphy->bands[IEEE80211_BAND_2GHZ]; + band = wiphy->bands[NL80211_BAND_2GHZ]; for (i = 0; i < band->n_channels; i++) { ch = &band->channels[i]; if (ch->flags & IEEE80211_CHAN_DISABLED) From 2ac42d0a935b8a13730b90fdbfe3cb7ee7fb8ba0 Mon Sep 17 00:00:00 2001 From: Kyle Roeschley Date: Thu, 31 Aug 2017 19:58:11 -0500 Subject: [PATCH 60/83] mmc: core: Wait for Vdd to settle on card power off The SD spec version 6.0 section 6.4.1.5 requires that Vdd must be lowered to less than 0.5V for a minimum of 1 ms when powering off a card. Increase our wait to 15 ms so that voltage has time to drain down to 0.5V. Signed-off-by: Kyle Roeschley Signed-off-by: Brad Mouring Acked-by: James Minor Acked-by: Brandon Streiff Natinst-ReviewBoard-ID: 203804 --- drivers/mmc/host/sdhci.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 3d5e062b8cfd4..67f72d98fb824 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -2416,6 +2416,9 @@ void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) else sdhci_set_power(host, ios->power_mode, ios->vdd); + if (ios->power_mode == MMC_POWER_OFF) + mdelay(15); + if (host->ops->platform_send_init_74_clocks) host->ops->platform_send_init_74_clocks(host, ios->power_mode); From 90e2d7cf1d9b45f04672c92a8b72d0963334317e Mon Sep 17 00:00:00 2001 From: Kyle Roeschley Date: Tue, 24 Apr 2018 08:27:03 -0500 Subject: [PATCH 61/83] mmc: sdhci: Disable SD card clock before changing parameters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Per the SD Host Controller Simplified Specification v4.20 §3.2.3, change the SD card clock parameters only after first disabling the external card clock. Doing this fixes a spurious clock pulse on Baytrail and Apollo Lake SD controllers which otherwise breaks voltage switching with a specific Swissbit SD card. Signed-off-by: Kyle Roeschley Signed-off-by: Brad Mouring Acked-by: Tony Liechty Acked-by: Nathan Sullivan Natinst-ReviewBoard-ID: 236135 Natinst-CAR-ID: 694815 --- drivers/mmc/host/sdhci.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 67f72d98fb824..16c1c539b2a6a 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -2066,10 +2066,15 @@ void sdhci_set_clock(struct sdhci_host *host, unsigned int clock) host->mmc->actual_clock = 0; - sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL); + clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); + if (clk & SDHCI_CLOCK_CARD_EN) + sdhci_writew(host, clk & ~SDHCI_CLOCK_CARD_EN, + SDHCI_CLOCK_CONTROL); - if (clock == 0) + if (clock == 0) { + sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL); return; + } clk = sdhci_calc_clk(host, clock, &host->mmc->actual_clock); sdhci_enable_clk(host, clk); From b297e5f000b4585c0e130c2cab626c4e0502a156 Mon Sep 17 00:00:00 2001 From: Kyle Roeschley Date: Mon, 14 May 2018 13:58:17 -0500 Subject: [PATCH 62/83] mmc: sdhci: Add quirk for delay between clock disable and param change Some SD controllers require a delay between clearing SDHCI_CLOCK_CARD_EN and changing the SD clock dividers in order to avoid a runt clock pulse which can otherwise cause problems with some SD cards. Signed-off-by: Kyle Roeschley Signed-off-by: Brad Mouring Acked-by: Tony Liechty Acked-by: Nathan Sullivan Natinst-ReviewBoard-ID: 236135 [cvadrevu: Fixed trivial conflicts due to new quirks] Signed-off-by: Chaitanya Vadrevu --- drivers/mmc/host/sdhci.c | 6 ++++++ drivers/mmc/host/sdhci.h | 2 ++ 2 files changed, 8 insertions(+) diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 16c1c539b2a6a..e44e9d06c73a7 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -2071,6 +2071,12 @@ void sdhci_set_clock(struct sdhci_host *host, unsigned int clock) sdhci_writew(host, clk & ~SDHCI_CLOCK_CARD_EN, SDHCI_CLOCK_CONTROL); + if (host->quirks2 & SDHCI_QUIRK2_NEED_DELAY_AFTER_CLK_DISABLE) { + spin_unlock_irq(&host->lock); + usleep_range(900, 1100); + spin_lock_irq(&host->lock); + } + if (clock == 0) { sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL); return; diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index 3201d21af793a..9b595462deda7 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -536,6 +536,8 @@ struct sdhci_host { #define SDHCI_QUIRK2_USE_32BIT_BLK_CNT (1<<18) /* Issue CMD and DATA reset together */ #define SDHCI_QUIRK2_ISSUE_CMD_DAT_RESET_TOGETHER (1<<19) +/* Controller requires delay between card clock disable and param change */ +#define SDHCI_QUIRK2_NEED_DELAY_AFTER_CLK_DISABLE (1<<20) int irq; /* Device IRQ */ void __iomem *ioaddr; /* Mapped address */ From a79e3079023cc0339ad26392dd39d8126cd4953c Mon Sep 17 00:00:00 2001 From: Kyle Roeschley Date: Wed, 16 May 2018 16:45:01 -0500 Subject: [PATCH 63/83] mmc: sdhci: Add quirk work around double rescan On some SD host controllers, we can see two SD card insert interrupts when inserting a card. This causes mmc_rescan() to be called twice in quick succession and generate one or two SD card clock pulses, which can cause some SD cards to become unresponsive. Signed-off-by: Kyle Roeschley Signed-off-by: Brad Mouring Acked-by: Tony Liechty Acked-by: Nathan Sullivan Natinst-ReviewBoard-ID: 236135 [gratian: fix conflict with fec796739740 ("mmc: sdhci: Factor out sdhci_enable_clk")] Signed-off-by: Gratian Crisan [cvadrevu: Fixed trivial conflicts due to new quirks] Signed-off-by: Chaitanya Vadrevu --- drivers/mmc/host/sdhci.c | 8 +++++++- drivers/mmc/host/sdhci.h | 2 ++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index e44e9d06c73a7..8fb66edb82a01 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -2079,11 +2079,17 @@ void sdhci_set_clock(struct sdhci_host *host, unsigned int clock) if (clock == 0) { sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL); - return; + goto out_delay; } clk = sdhci_calc_clk(host, clock, &host->mmc->actual_clock); sdhci_enable_clk(host, clk); +out_delay: + if (host->quirks2 & SDHCI_QUIRK2_SPURIOUS_CARD_INSERT_INTERRUPT) { + spin_unlock_irq(&host->lock); + usleep_range(4900, 5100); + spin_lock_irq(&host->lock); + } } EXPORT_SYMBOL_GPL(sdhci_set_clock); diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index 9b595462deda7..ad5fb71cd729c 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -538,6 +538,8 @@ struct sdhci_host { #define SDHCI_QUIRK2_ISSUE_CMD_DAT_RESET_TOGETHER (1<<19) /* Controller requires delay between card clock disable and param change */ #define SDHCI_QUIRK2_NEED_DELAY_AFTER_CLK_DISABLE (1<<20) +/* Controller may interrupt multiple times for card insert */ +#define SDHCI_QUIRK2_SPURIOUS_CARD_INSERT_INTERRUPT (1<<21) int irq; /* Device IRQ */ void __iomem *ioaddr; /* Mapped address */ From 8abeeca2b16a4917643bc6f6398f2c2715642973 Mon Sep 17 00:00:00 2001 From: Kyle Roeschley Date: Thu, 17 May 2018 11:25:47 -0500 Subject: [PATCH 64/83] mmc: sdhci-pci: Use two delay quirks for Baytrail SD With the Baytrail SD controllers on cRIO-905x, we can run into two conditions which cause functional problems with the NI-recommended microSD card. The first is a runt pulse after SD card clock disable, which is fixed by using SDHCI_QUIRK2_NEED_DELAY_AFTER_CLK_DISABLE to wait after disabling the clock. The second is receiving two SDHCI_INT_CARD_INSERT interrupts, which causes us to set up the card twice a make our recommended microSD card unresponsive. Work around this by using SDHCI_QUIRK2_SPURIOUS_CARD_INSERT_INTERRUPT. Signed-off-by: Kyle Roeschley Signed-off-by: Brad Mouring Acked-by: Tony Liechty Acked-by: Nathan Sullivan Natinst-ReviewBoard-ID: 236135 Natinst-CAR-ID: 696865 Natinst-CAR-ID: 694815 --- drivers/mmc/host/sdhci-pci-core.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/mmc/host/sdhci-pci-core.c b/drivers/mmc/host/sdhci-pci-core.c index 47a0a738862b5..4419f0414bf1a 100644 --- a/drivers/mmc/host/sdhci-pci-core.c +++ b/drivers/mmc/host/sdhci-pci-core.c @@ -1137,6 +1137,10 @@ static int byt_sd_probe_slot(struct sdhci_pci_slot *slot) byt_needs_pwr_off(slot); + if (slot->chip->pdev->device == PCI_DEVICE_ID_INTEL_BYT_SD) + slot->host->quirks2 |= SDHCI_QUIRK2_NEED_DELAY_AFTER_CLK_DISABLE | + SDHCI_QUIRK2_SPURIOUS_CARD_INSERT_INTERRUPT; + return 0; } From df5009d38dca54825ba500f0a49a6ee4d1ab7aab Mon Sep 17 00:00:00 2001 From: Jeff Westfahl Date: Wed, 11 Jul 2012 22:14:17 +0200 Subject: [PATCH 65/83] Marvell 88E151x PHY: Configure interrupt output By default, the interrupt output of the Marvell 88E1512 PHY is configured as an LED output, and is driven low. If we have a case where eth1 is brought up before eth0, this causes an interrupt storm, and Linux eventually gives up and disables the PHY interrupt line. Adding a probe function to the Marvell 88E1512 PHY driver and moving the interrupt output configuration there resolves this problem. [bm: Adjust for d2fa47d9dd5c5f82d78c4503cf33989f67e8aa64 'phy: marvell: Add ethtool statistics counters'] Signed-off-by: Jeff Westfahl Signed-off-by: Mihaly Varga Acked-by: Brad Mouring Acked-by: Ben Shelton Acked-by: Jaeden Amero Natinst-ReviewBoard-ID: 81627 [bm: Restore correct page on LED/irq config] Signed-off-by: Brad Mouring Acked-by: Jeff Westfahl Natinst-ReviewBoard-ID: 148255 [gratian: split LED pin setup from m88e151x_probe; fixes conflict with 0b04680fdae4 ("phy: marvell: Add support for temperature sensor")] Signed-off-by: Gratian Crisan [cvadrevu: Fixed trivial conflict with b697d9d38a5a5 ("net: phy: marvell: add SFP support for 88E1510")] [cvadrevu: Updated marvell_get_page to marvell_read_page due to 424ca4c55121 ("net: phy: marvell: fix paged access races")] Signed-off-by: Chaitanya Vadrevu --- drivers/net/phy/marvell.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c index c248c90510ae5..35da758f64852 100644 --- a/drivers/net/phy/marvell.c +++ b/drivers/net/phy/marvell.c @@ -181,6 +181,8 @@ #define MII_88E3016_PHY_SPEC_CTRL 0x10 #define MII_88E3016_DISABLE_SCRAMBLER 0x0200 #define MII_88E3016_AUTO_MDIX_CROSSOVER 0x0030 +#define MII_88E1512_LEDTimerControl_InterruptEnable 0x0080 + #define MII_88E1510_GEN_CTRL_REG_1 0x14 #define MII_88E1510_GEN_CTRL_REG_1_MODE_MASK 0x7 @@ -3682,10 +3684,45 @@ static const struct sfp_upstream_ops m88e1510_sfp_ops = { .disconnect_phy = phy_sfp_disconnect_phy, }; +static int m88e151x_setup_interrupt_pin(struct phy_device *phydev) +{ + u32 led_timer_control; + int err, old_page; + + old_page = marvell_read_page(phydev); + if (old_page < 0) + return old_page; + + /* Enable the interrupt output. This is just a pin configuration, + * we're not actually enabling any interrupts here. But the default + * configuration causes our interrupt pin to be asserted. We need + * to stop that as early as possible. + */ + err = marvell_set_page(phydev, MII_MARVELL_LED_PAGE); + + if (err < 0) + return err; + + led_timer_control = phy_read(phydev, MII_88E1318S_PHY_LED_TCR); + led_timer_control |= MII_88E1512_LEDTimerControl_InterruptEnable; + + err = phy_write(phydev, MII_88E1318S_PHY_LED_TCR, led_timer_control); + if (err < 0) + return err; + + err = marvell_set_page(phydev, old_page); + + return err; +} + static int m88e1510_probe(struct phy_device *phydev) { int err; + err = m88e151x_setup_interrupt_pin(phydev); + if (err) + return err; + err = marvell_probe(phydev); if (err) return err; From 2ddc35f6f7999f779c86ab1669c29580cb022372 Mon Sep 17 00:00:00 2001 From: Kyle Roeschley Date: Tue, 20 Nov 2018 07:38:02 -0600 Subject: [PATCH 66/83] mmc: sdhci: Do not disable interrupts in sdhci_set_clock Upstream removed spin lock usage in the set_ios path with commit d1e4f74f911d ("mmc: sdhci: Do not use spin lock in set_ios paths"), which means that our calls to spin_(un)lock_irq() in sdhci_set_clock() now cause an error on boot if a card is not present or a crash if one is present. Remove these calls so we don't do that and to match upstream's change. Fixes: 815777e0a1fb2 ("mmc: sdhci: Add quirk for delay between clock disable and param change") Fixes: 30d2f458ba48f ("mmc: sdhci: Add quirk work around double rescan") Signed-off-by: Kyle Roeschley Acked-by: Gratian Crisan Acked-by: Brandon Streiff Natinst-ReviewBoard-ID: 264712 Natinst-CAR-ID: 720310 --- drivers/mmc/host/sdhci.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 8fb66edb82a01..15f09f7795cfa 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -2071,11 +2071,8 @@ void sdhci_set_clock(struct sdhci_host *host, unsigned int clock) sdhci_writew(host, clk & ~SDHCI_CLOCK_CARD_EN, SDHCI_CLOCK_CONTROL); - if (host->quirks2 & SDHCI_QUIRK2_NEED_DELAY_AFTER_CLK_DISABLE) { - spin_unlock_irq(&host->lock); - usleep_range(900, 1100); - spin_lock_irq(&host->lock); - } + if (host->quirks2 & SDHCI_QUIRK2_NEED_DELAY_AFTER_CLK_DISABLE) + mdelay(1); if (clock == 0) { sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL); @@ -2085,11 +2082,8 @@ void sdhci_set_clock(struct sdhci_host *host, unsigned int clock) clk = sdhci_calc_clk(host, clock, &host->mmc->actual_clock); sdhci_enable_clk(host, clk); out_delay: - if (host->quirks2 & SDHCI_QUIRK2_SPURIOUS_CARD_INSERT_INTERRUPT) { - spin_unlock_irq(&host->lock); - usleep_range(4900, 5100); - spin_lock_irq(&host->lock); - } + if (host->quirks2 & SDHCI_QUIRK2_SPURIOUS_CARD_INSERT_INTERRUPT) + mdelay(5); } EXPORT_SYMBOL_GPL(sdhci_set_clock); From 5f9de4bdd0ff4aa5180cda7ec08c802f1a76f2f0 Mon Sep 17 00:00:00 2001 From: Kim Khiam Lim Date: Tue, 26 Jan 2021 21:20:39 -0800 Subject: [PATCH 67/83] nizynqcpld: Add NI roboRIO 2.0 CPLD support NI roboRIO 2.0 has relocated the clock pin from 1.8V bank to 3.3V bank. Hence, it required to update both product and supported version to indicate the changes in HW. Signed-off-by: Kim Khiam Lim --- drivers/misc/nizynqcpld.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/misc/nizynqcpld.c b/drivers/misc/nizynqcpld.c index d8734a00f0331..5db065365893e 100644 --- a/drivers/misc/nizynqcpld.c +++ b/drivers/misc/nizynqcpld.c @@ -1380,6 +1380,20 @@ static struct nizynqcpld_desc nizynqcpld_descs[] = { .switch_addr = PROTO_PROCESSORMODE, .watchdog_addr = DOSX_WATCHDOGCONTROL, }, + /* roboRIO 2.0 CPLD */ + { + .attrs = dosequis6_attrs, + .supported_version = 1, + .supported_product = 7, + .watchdog_desc = &dosxv5_watchdog_desc, + .led_descs = dosx_leds, + .num_led_descs = ARRAY_SIZE(dosx_leds), + .reboot_addr = DOSX_PROCESSORRESET, + .scratch_hr_addr = DOSX_SCRATCHPADHR, + .scratch_sr_addr = DOSX_SCRATCHPADSR, + .switch_addr = PROTO_PROCESSORMODE, + .watchdog_addr = DOSX_WATCHDOGCONTROL, + }, }; static void wifi_sw_work_func(struct work_struct *work) From 2b31af16d5f23b0b8dad0e2982de6c7556d70a07 Mon Sep 17 00:00:00 2001 From: Chaitanya Vadrevu Date: Tue, 21 Jul 2026 18:02:45 -0500 Subject: [PATCH 68/83] ARM: dts: ni: Import Zynq device trees from Linux 4.14 Import the NI Zynq board device trees from the 4.14 kernel and add them to the Xilinx DTB build list. Signed-off-by: Chaitanya Vadrevu --- arch/arm/boot/dts/xilinx/Makefile | 26 +- arch/arm/boot/dts/xilinx/ni-762F.dts | 6 + arch/arm/boot/dts/xilinx/ni-76D3.dts | 6 + arch/arm/boot/dts/xilinx/ni-76D6.dts | 138 +++++++++++ arch/arm/boot/dts/xilinx/ni-76F2.dts | 195 +++++++++++++++ arch/arm/boot/dts/xilinx/ni-7740.dts | 6 + arch/arm/boot/dts/xilinx/ni-7741.dts | 6 + arch/arm/boot/dts/xilinx/ni-7742.dts | 6 + arch/arm/boot/dts/xilinx/ni-7743.dts | 6 + arch/arm/boot/dts/xilinx/ni-7744.dts | 6 + arch/arm/boot/dts/xilinx/ni-774C.dts | 6 + arch/arm/boot/dts/xilinx/ni-774E.dts | 6 + arch/arm/boot/dts/xilinx/ni-775E.dts | 153 ++++++++++++ arch/arm/boot/dts/xilinx/ni-77AC.dts | 6 + arch/arm/boot/dts/xilinx/ni-77B1.dts | 6 + arch/arm/boot/dts/xilinx/ni-77B2.dts | 6 + arch/arm/boot/dts/xilinx/ni-77D4.dts | 141 +++++++++++ arch/arm/boot/dts/xilinx/ni-77D5.dts | 257 ++++++++++++++++++++ arch/arm/boot/dts/xilinx/ni-77D6.dts | 243 ++++++++++++++++++ arch/arm/boot/dts/xilinx/ni-7885.dts | 52 ++++ arch/arm/boot/dts/xilinx/ni-7931.dts | 8 + arch/arm/boot/dts/xilinx/ni-7932.dts | 8 + arch/arm/boot/dts/xilinx/ni-7935.dts | 8 + arch/arm/boot/dts/xilinx/ni-793C.dts | 155 ++++++++++++ arch/arm/boot/dts/xilinx/ni-793x.dtsi | 101 ++++++++ arch/arm/boot/dts/xilinx/ni-7AAE.dts | 205 ++++++++++++++++ arch/arm/boot/dts/xilinx/ni-myrio.dtsi | 87 +++++++ arch/arm/boot/dts/xilinx/ni-solbetter.dtsi | 199 +++++++++++++++ arch/arm/boot/dts/xilinx/ni-solenetexp.dtsi | 108 ++++++++ arch/arm/boot/dts/xilinx/ni-solgood.dtsi | 126 ++++++++++ 30 files changed, 2281 insertions(+), 1 deletion(-) create mode 100644 arch/arm/boot/dts/xilinx/ni-762F.dts create mode 100644 arch/arm/boot/dts/xilinx/ni-76D3.dts create mode 100644 arch/arm/boot/dts/xilinx/ni-76D6.dts create mode 100644 arch/arm/boot/dts/xilinx/ni-76F2.dts create mode 100644 arch/arm/boot/dts/xilinx/ni-7740.dts create mode 100644 arch/arm/boot/dts/xilinx/ni-7741.dts create mode 100644 arch/arm/boot/dts/xilinx/ni-7742.dts create mode 100644 arch/arm/boot/dts/xilinx/ni-7743.dts create mode 100644 arch/arm/boot/dts/xilinx/ni-7744.dts create mode 100644 arch/arm/boot/dts/xilinx/ni-774C.dts create mode 100644 arch/arm/boot/dts/xilinx/ni-774E.dts create mode 100644 arch/arm/boot/dts/xilinx/ni-775E.dts create mode 100644 arch/arm/boot/dts/xilinx/ni-77AC.dts create mode 100644 arch/arm/boot/dts/xilinx/ni-77B1.dts create mode 100644 arch/arm/boot/dts/xilinx/ni-77B2.dts create mode 100644 arch/arm/boot/dts/xilinx/ni-77D4.dts create mode 100644 arch/arm/boot/dts/xilinx/ni-77D5.dts create mode 100644 arch/arm/boot/dts/xilinx/ni-77D6.dts create mode 100644 arch/arm/boot/dts/xilinx/ni-7885.dts create mode 100644 arch/arm/boot/dts/xilinx/ni-7931.dts create mode 100644 arch/arm/boot/dts/xilinx/ni-7932.dts create mode 100644 arch/arm/boot/dts/xilinx/ni-7935.dts create mode 100644 arch/arm/boot/dts/xilinx/ni-793C.dts create mode 100644 arch/arm/boot/dts/xilinx/ni-793x.dtsi create mode 100644 arch/arm/boot/dts/xilinx/ni-7AAE.dts create mode 100644 arch/arm/boot/dts/xilinx/ni-myrio.dtsi create mode 100644 arch/arm/boot/dts/xilinx/ni-solbetter.dtsi create mode 100644 arch/arm/boot/dts/xilinx/ni-solenetexp.dtsi create mode 100644 arch/arm/boot/dts/xilinx/ni-solgood.dtsi diff --git a/arch/arm/boot/dts/xilinx/Makefile b/arch/arm/boot/dts/xilinx/Makefile index 9233e539b192b..be4b160debac0 100644 --- a/arch/arm/boot/dts/xilinx/Makefile +++ b/arch/arm/boot/dts/xilinx/Makefile @@ -14,4 +14,28 @@ dtb-$(CONFIG_ARCH_ZYNQ) += \ zynq-zturn.dtb \ zynq-zturn-v5.dtb \ zynq-zybo.dtb \ - zynq-zybo-z7.dtb + zynq-zybo-z7.dtb \ + ni-7931.dtb \ + ni-7932.dtb \ + ni-7935.dtb \ + ni-762F.dtb \ + ni-76D3.dtb \ + ni-76D6.dtb \ + ni-76F2.dtb \ + ni-7740.dtb \ + ni-7741.dtb \ + ni-7742.dtb \ + ni-7743.dtb \ + ni-7744.dtb \ + ni-774C.dtb \ + ni-774E.dtb \ + ni-775E.dtb \ + ni-77AC.dtb \ + ni-77B1.dtb \ + ni-77B2.dtb \ + ni-77D4.dtb \ + ni-77D5.dtb \ + ni-77D6.dtb \ + ni-7885.dtb \ + ni-793C.dtb \ + ni-7AAE.dtb diff --git a/arch/arm/boot/dts/xilinx/ni-762F.dts b/arch/arm/boot/dts/xilinx/ni-762F.dts new file mode 100644 index 0000000000000..5e9b94dd530e9 --- /dev/null +++ b/arch/arm/boot/dts/xilinx/ni-762F.dts @@ -0,0 +1,6 @@ +/dts-v1/; +/include/ "ni-myrio.dtsi" + +/ { + model = "NI myRIO-1900"; +}; diff --git a/arch/arm/boot/dts/xilinx/ni-76D3.dts b/arch/arm/boot/dts/xilinx/ni-76D3.dts new file mode 100644 index 0000000000000..c5fcc1d079d23 --- /dev/null +++ b/arch/arm/boot/dts/xilinx/ni-76D3.dts @@ -0,0 +1,6 @@ +/dts-v1/; +/include/ "ni-myrio.dtsi" + +/ { + model = "NI myRIO-1950"; +}; diff --git a/arch/arm/boot/dts/xilinx/ni-76D6.dts b/arch/arm/boot/dts/xilinx/ni-76D6.dts new file mode 100644 index 0000000000000..22fd6b41cd3e4 --- /dev/null +++ b/arch/arm/boot/dts/xilinx/ni-76D6.dts @@ -0,0 +1,138 @@ +/dts-v1/; +/include/ "ni-zynq.dtsi" + +/ { + model = "NI cRIO-9068"; + compatible = "ni,zynq", "xlnx,zynq-7000"; + + amba@0 { + i2c0: i2c@e0004000 { + nicpld@40 { + watchdogs { + boot-watchdog { + interrupt-parent = <&gpio>; + interrupts = <46 2 /* IRQ_TYPE_EDGE_FALLING */>; + }; + }; + + leds { + user1-0 { + label = "nilrt:user1:green"; + }; + user1-1 { + label = "nilrt:user1:yellow"; + }; + status-0 { + label = "nilrt:status:red"; + }; + status-1 { + label = "nilrt:status:yellow"; + max-brightness = <0xFFFF>; + }; + eth0-0 { + label = "nilrt:eth0:green"; + linux,default-trigger = + "e000b000.ethernet-ffffffff:00:100Mbps"; + }; + eth0-1 { + label = "nilrt:eth0:yellow"; + linux,default-trigger = + "e000b000.ethernet-ffffffff:00:1Gbps"; + }; + eth1-0 { + label = "nilrt:eth1:green"; + linux,default-trigger = + "e000b000.ethernet-ffffffff:01:100Mbps"; + }; + eth1-1 { + label = "nilrt:eth1:yellow"; + linux,default-trigger = + "e000b000.ethernet-ffffffff:01:1Gbps"; + }; + }; + }; + + ds3231_rtc@68 { + status = "okay"; + }; + }; + }; +}; + +&gem0 { + status = "okay"; + phy-handle = <&phy0>; + phy-mode = "rgmii-id"; + #address-cells = <0x1>; + #size-cells = <0x0>; + + phy0: phy@0 { + compatible = "marvell,88e1512","ethernet-phy-ieee802.3-c22"; + device_type = "ethernet-phy"; + reg = <0x0>; + /* Interrupt on GPIO1, shared with phy1. */ + interrupts = <1 8 /* IRQ_TYPE_LEVEL_LOW */>; + interrupt-parent = <&gpio>; + + /* marvell,reg-init = + * + * reg-page = MII_MARVELL_LED_PAGE (3) + * reg = PHY_LED_CTRL (16) + * value = 0x1881 (LED[0] = on:link, blink:activity, off:no link) + */ + marvell,reg-init = <3 16 0 0x1881>; + }; + + phy1: phy@1 { + compatible = "marvell,88e1512","ethernet-phy-ieee802.3-c22"; + device_type = "ethernet-phy"; + reg = <0x1>; + /* Interrupt on GPIO1, shared with phy0. */ + interrupts = <1 8 /* IRQ_TYPE_LEVEL_LOW */>; + interrupt-parent = <&gpio>; + + /* marvell,reg-init = + * + * reg-page = MII_MARVELL_LED_PAGE (3) + * reg = PHY_LED_CTRL (16) + * value = 0x1881 (LED[0] = on:link, blink:activity, off:no link) + */ + marvell,reg-init = <3 16 0 0x1881>; + }; +}; + +&gem1 { + status = "okay"; + clocks = <&clkc 31>, <&clkc 14>, <&clkc 15>; + clock-names = "pclk", "hclk", "tx_clk"; + phy-handle = <&phy1>; + phy-mode = "rgmii-id"; + cdns,no_mdio_bus; + emio-speed-gpios = <0>, + <&gpio 54 0>; +}; + +&ni_uart0 { + status = "okay"; + transceiver = "RS-232"; +}; + +&ni_uart1 { + status = "okay"; + transceiver = "RS-232"; +}; + +&ni_uart2 { + status = "okay"; + transceiver = "RS-485"; +}; + +&usb0 { + status = "okay"; + dr_mode = "host"; +}; + +&clkc { + /* Enable fclk1 for serial. */ + fclk-enable = <0x2>; +}; diff --git a/arch/arm/boot/dts/xilinx/ni-76F2.dts b/arch/arm/boot/dts/xilinx/ni-76F2.dts new file mode 100644 index 0000000000000..ef161a68d0f68 --- /dev/null +++ b/arch/arm/boot/dts/xilinx/ni-76F2.dts @@ -0,0 +1,195 @@ +/dts-v1/; +/include/ "ni-zynq.dtsi" + +/ { + model = "NI roboRIO"; + compatible = "ni,zynq", "xlnx,zynq-7000"; + + aliases { + spi0 = &spi0; + spi1 = &spi1; + }; + + leds { + compatible = "gpio-leds"; + wlan1 { + /* green */ + label = "nilrt:wifi:primary"; + gpios = <&gpio 55 0>; + }; + + wlan2 { + /* red */ + label = "nilrt:wifi:secondary"; + gpios = <&gpio 56 0>; + }; + }; + + amba@0 { + adc: adc@f8007100 { + xlnx,channels { + #address-cells = <1>; + #size-cells = <0>; + /* Channel 0 maps to VPVN */ + channel@0 { + reg = <0>; + }; + /* Channel 1 maps to VAUX0 */ + channel@1 { + reg = <1>; + }; + /* Channel 2 maps to VAUX1 */ + channel@2 { + reg = <2>; + }; + /* Channel 3 maps to VAUX2 */ + channel@3 { + reg = <3>; + }; + /* Channel 4 maps to VAUX3 */ + channel@4 { + reg = <4>; + }; + /* Channel 5 maps to VAUX4 */ + channel@5 { + reg = <5>; + }; + /* Channel 9 maps to VAUX8 */ + channel@9 { + reg = <9>; + }; + /* Channel 10 maps to VAUX9 */ + channel@10 { + reg = <10>; + }; + /* Channel 11 maps to VAUX10 */ + channel@11 { + reg = <11>; + }; + /* Channel 12 maps to VAUX11 */ + channel@12 { + reg = <12>; + }; + }; + }; + + i2c0: i2c@e0004000 { + nicpld@40 { + watchdogs { + boot-watchdog { + interrupt-parent = <&gpio>; + interrupts = <24 2 /* IRQ_TYPE_EDGE_FALLING */>; + }; + }; + + leds { + status-1 { + label = "nilrt:status:yellow"; + max-brightness = <0xFFFF>; + }; + }; + }; + }; + + i2c1: i2c@e0005000 { + status = "okay"; + }; + + i2c2: i2c@81000000 { + status = "okay"; + }; + + spi0: spi@e0006000 { + status = "okay"; + num-cs = <7>; + is-decoded-cs = <1>; + speed-hz = <200000000>; + + spidev@0 { + compatible = "spidev"; + spi-max-frequency = <2000000>; + reg = <0>; + }; + spidev@1 { + compatible = "spidev"; + spi-max-frequency = <2000000>; + reg = <1>; + }; + spidev@2 { + compatible = "spidev"; + spi-max-frequency = <2000000>; + reg = <2>; + }; + spidev@3 { + compatible = "spidev"; + spi-max-frequency = <2000000>; + reg = <3>; + }; + }; + + spi1: spi@e0007000 { + status = "okay"; + num-cs = <3>; + is-decoded-cs = <0>; + speed-hz = <200000000>; + + spidev@0 { + compatible = "spidev"; + spi-max-frequency = <2000000>; + reg = <0>; + }; + }; + }; +}; + +&gem0 { + status = "okay"; + phy-handle = <&phy0>; + phy-mode = "rgmii-id"; + emio-speed-gpios = <&gpio 54 0>, + <0>; + #address-cells = <0x1>; + #size-cells = <0x0>; + + phy0: phy@0 { + compatible = "smsc,lan8720","ethernet-phy-ieee802.3-c22"; + device_type = "ethernet-phy"; + reg = <0x0>; + /* Interrupt pin is connected from PL pin to FPGA IRQ 3 */ + interrupts = <0 32 4>; + smsc,disable-energy-detect; + }; +}; + +&ni_uart0 { + status = "okay"; + transceiver = "RS-232"; +}; + +&ni_uart1 { + status = "okay"; + transceiver = "RS-232"; +}; + +&uart0 { + status = "okay"; +}; + +&can0 { + status = "okay"; +}; + +&usb0 { + status = "okay"; + dr_mode = "host"; +}; + +&usb1 { + status = "okay"; + dr_mode = "peripheral"; +}; + +&clkc { + /* Enable fclk1 for serial. */ + fclk-enable = <0x2>; +}; diff --git a/arch/arm/boot/dts/xilinx/ni-7740.dts b/arch/arm/boot/dts/xilinx/ni-7740.dts new file mode 100644 index 0000000000000..8fa59d7c8dcd1 --- /dev/null +++ b/arch/arm/boot/dts/xilinx/ni-7740.dts @@ -0,0 +1,6 @@ +/dts-v1/; +/include/ "ni-solgood.dtsi" + +/ { + model = "NI cRIO-9063"; +}; diff --git a/arch/arm/boot/dts/xilinx/ni-7741.dts b/arch/arm/boot/dts/xilinx/ni-7741.dts new file mode 100644 index 0000000000000..c7f1e246456a7 --- /dev/null +++ b/arch/arm/boot/dts/xilinx/ni-7741.dts @@ -0,0 +1,6 @@ +/dts-v1/; +/include/ "ni-solbetter.dtsi" + +/ { + model = "NI cRIO-9064"; +}; diff --git a/arch/arm/boot/dts/xilinx/ni-7742.dts b/arch/arm/boot/dts/xilinx/ni-7742.dts new file mode 100644 index 0000000000000..88ca0b6450e83 --- /dev/null +++ b/arch/arm/boot/dts/xilinx/ni-7742.dts @@ -0,0 +1,6 @@ +/dts-v1/; +/include/ "ni-solbetter.dtsi" + +/ { + model = "NI cRIO-9065"; +}; diff --git a/arch/arm/boot/dts/xilinx/ni-7743.dts b/arch/arm/boot/dts/xilinx/ni-7743.dts new file mode 100644 index 0000000000000..95f70a8383b56 --- /dev/null +++ b/arch/arm/boot/dts/xilinx/ni-7743.dts @@ -0,0 +1,6 @@ +/dts-v1/; +/include/ "ni-solgood.dtsi" + +/ { + model = "NI cRIO-9066"; +}; diff --git a/arch/arm/boot/dts/xilinx/ni-7744.dts b/arch/arm/boot/dts/xilinx/ni-7744.dts new file mode 100644 index 0000000000000..9f5a652c20eae --- /dev/null +++ b/arch/arm/boot/dts/xilinx/ni-7744.dts @@ -0,0 +1,6 @@ +/dts-v1/; +/include/ "ni-solbetter.dtsi" + +/ { + model = "NI cRIO-9067"; +}; diff --git a/arch/arm/boot/dts/xilinx/ni-774C.dts b/arch/arm/boot/dts/xilinx/ni-774C.dts new file mode 100644 index 0000000000000..c80a63c642266 --- /dev/null +++ b/arch/arm/boot/dts/xilinx/ni-774C.dts @@ -0,0 +1,6 @@ +/dts-v1/; +/include/ "ni-solenetexp.dtsi" + +/ { + model = "NI 9147"; +}; diff --git a/arch/arm/boot/dts/xilinx/ni-774E.dts b/arch/arm/boot/dts/xilinx/ni-774E.dts new file mode 100644 index 0000000000000..1557e8c5f8b3e --- /dev/null +++ b/arch/arm/boot/dts/xilinx/ni-774E.dts @@ -0,0 +1,6 @@ +/dts-v1/; +/include/ "ni-solenetexp.dtsi" + +/ { + model = "NI 9149"; +}; diff --git a/arch/arm/boot/dts/xilinx/ni-775E.dts b/arch/arm/boot/dts/xilinx/ni-775E.dts new file mode 100644 index 0000000000000..ed3f9c6e53953 --- /dev/null +++ b/arch/arm/boot/dts/xilinx/ni-775E.dts @@ -0,0 +1,153 @@ +/dts-v1/; +/include/ "ni-zynq.dtsi" + +/ { + model = "NI sbRIO-9651"; + compatible = "ni,zynq", "xlnx,zynq-7000"; + + amba@0 { + i2c0: i2c@e0004000 { + nicpld@40 { + watchdogs { + boot-watchdog { + interrupt-parent = <&gpio>; + interrupts = <15 2 /* IRQ_TYPE_EDGE_FALLING */>; + }; + }; + + leds { + status-0 { + label = "nilrt:status:yellow"; + max-brightness = <0xFFFF>; + }; + eth0-0 { + label = "nilrt:eth0:green"; + linux,default-trigger = + "e000b000.ethernet-ffffffff:00:100Mbps"; + }; + eth0-1 { + label = "nilrt:eth0:yellow"; + linux,default-trigger = + "e000b000.ethernet-ffffffff:00:1Gbps"; + }; + }; + }; + + ds3231_rtc@68 { + status = "okay"; + }; + }; + }; +}; + +&gem0 { + status = "okay"; + + /* No fpga_clk specified because we want our FPGA clock + * (fclk0) to always be 125 MHz. The bootloader sets + * fclk0 to 125 MHz and we just leave it like that. + */ + + phy-handle = <&phy0>; + phy-mode = "rgmii-id"; + #address-cells = <0x1>; + #size-cells = <0x0>; + + emio-speed-gpios = <0>, + <&gpio 54 0>; + + phy0: phy@0 { + compatible = "micrel,KSZ9031","ethernet-phy-ieee802.3-c22"; + device_type = "ethernet-phy"; + reg = <0x0>; + /* Interrupt on GPIO1. */ + interrupts = <1 8 /* IRQ_TYPE_LEVEL_LOW */>; + interrupt-parent = <&gpio>; + + /* Set RX_CLK Pad Skew [4:0] to 0b00000. */ + rxc-skew-ps = <0>; + }; +}; + +&gem1 { + status = "okay"; + + /* No fpga_clk specified because we want our FPGA clock (fclk0) to + * always be 125 MHz. The bootloader sets fclk0 to 125 MHz and we just + * leave it like that. + */ + + phy-handle = <&phy1>; + phy-mode = "rgmii-id"; + #address-cells = <0x1>; + #size-cells = <0x0>; + + emio-speed-gpios = <&gpio 56 0>, + <&gpio 55 0>; + + phy1: phy@1 { + compatible = "micrel,KSZ9031","ethernet-phy-ieee802.3-c22"; + device_type = "ethernet-phy"; + reg = <0x1>; + /* Interrupt on GPIO57. */ + interrupts = <57 8 /* IRQ_TYPE_LEVEL_LOW */>; + interrupt-parent = <&gpio>; + }; +}; + +&sdhci0 { + status = "okay"; +}; + +&ni_uart0 { + status = "okay"; + transceiver = "RS-232"; +}; + +&ni_uart1 { + status = "okay"; + transceiver = "RS-232"; +}; + +&ni_uart2 { + status = "okay"; + transceiver = "RS-232"; +}; + +&ni_uart3 { + status = "okay"; + transceiver = "RS-232"; +}; + +&ni_uart4 { + status = "okay"; + transceiver = "RS-485"; +}; + +&ni_uart5 { + status = "okay"; + transceiver = "RS-485"; +}; + +&can0 { + status = "okay"; +}; + +&can1 { + status = "okay"; +}; + +&usb0 { + status = "okay"; + dr_mode = "peripheral"; +}; + +&usb1 { + status = "okay"; + dr_mode = "host"; +}; + +&clkc { + /* Enable fclk0 for eth0 and eth1, fclk1 for serial. */ + fclk-enable = <0x3>; +}; diff --git a/arch/arm/boot/dts/xilinx/ni-77AC.dts b/arch/arm/boot/dts/xilinx/ni-77AC.dts new file mode 100644 index 0000000000000..a2456ca3cbe36 --- /dev/null +++ b/arch/arm/boot/dts/xilinx/ni-77AC.dts @@ -0,0 +1,6 @@ +/dts-v1/; +/include/ "ni-793x.dtsi" + +/ { + model = "NI 7935R"; +}; diff --git a/arch/arm/boot/dts/xilinx/ni-77B1.dts b/arch/arm/boot/dts/xilinx/ni-77B1.dts new file mode 100644 index 0000000000000..b78d89e3e36d6 --- /dev/null +++ b/arch/arm/boot/dts/xilinx/ni-77B1.dts @@ -0,0 +1,6 @@ +/dts-v1/; +/include/ "ni-793x.dtsi" + +/ { + model = "NI 7931R"; +}; diff --git a/arch/arm/boot/dts/xilinx/ni-77B2.dts b/arch/arm/boot/dts/xilinx/ni-77B2.dts new file mode 100644 index 0000000000000..c9c371e7cc302 --- /dev/null +++ b/arch/arm/boot/dts/xilinx/ni-77B2.dts @@ -0,0 +1,6 @@ +/dts-v1/; +/include/ "ni-793x.dtsi" + +/ { + model = "NI 7932R"; +}; diff --git a/arch/arm/boot/dts/xilinx/ni-77D4.dts b/arch/arm/boot/dts/xilinx/ni-77D4.dts new file mode 100644 index 0000000000000..571e48d34449f --- /dev/null +++ b/arch/arm/boot/dts/xilinx/ni-77D4.dts @@ -0,0 +1,141 @@ +/dts-v1/; +/include/ "ni-zynq.dtsi" + +/ { + model = "NI sbRIO-9637"; + compatible = "ni,zynq", "xlnx,zynq-7000"; + + amba@0 { + i2c0: i2c@e0004000 { + nicpld@40 { + watchdogs { + boot-watchdog { + interrupt-parent = <&gpio>; + interrupts = <1 2 /* IRQ_TYPE_EDGE_FALLING */>; + }; + }; + + leds { + user1-0 { + label = "nilrt:user1:green"; + }; + status-0 { + label = "nilrt:status:yellow"; + max-brightness = <0xFFFF>; + }; + eth0-0 { + label = "nilrt:eth0:green"; + linux,default-trigger = + "e000b000.ethernet-ffffffff:00:100Mbps"; + }; + eth0-1 { + label = "nilrt:eth0:yellow"; + linux,default-trigger = + "e000b000.ethernet-ffffffff:00:1Gbps"; + }; + }; + }; + + ds3231_rtc@68 { + status = "okay"; + }; + }; + }; +}; + +&gem0 { + status = "okay"; + clocks = <&clkc 30>, <&clkc 13>, <&clkc 15>; + clock-names = "pclk", "hclk", "tx_clk"; + phy-handle = <&phy0>; + phy-mode = "rgmii-id"; + emio-speed-gpios = <0>, + <&gpio 54 0>; + + #address-cells = <0x1>; + #size-cells = <0x0>; + + phy0: phy@0 { + compatible = "micrel,KSZ9031","ethernet-phy-ieee802.3-c22"; + device_type = "ethernet-phy"; + reg = <0x0>; + /* Interrupt on GPIO25. */ + interrupts = <25 8 /* IRQ_TYPE_LEVEL_LOW */>; + interrupt-parent = <&gpio>; + + /* RX_DV Pad Skew [7:4] = +0.30ns (0xC0) */ + /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 + * ps. 420 + 300 is 720 ps. + */ + rxdv-skew-ps = <720>; + + /* TX_EN Pad Skew [3:0] = -0.30ns (0x02) */ + /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 + * ps. 420 - 300 is 120 ps. + */ + txen-skew-ps = <120>; + + /* RXD 0-3 Pad Skew = +0.30ns (0xC) */ + /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 + * ps. 420 + 300 is 720 ps. + */ + rxd0-skew-ps = <720>; + rxd1-skew-ps = <720>; + rxd2-skew-ps = <720>; + rxd3-skew-ps = <720>; + + /* TXD 0-3 Pad Skew = -0.30ns (0x2) */ + /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 + * ps. 420 - 300 is 120 ps. + */ + txd0-skew-ps = <120>; + txd1-skew-ps = <120>; + txd2-skew-ps = <120>; + txd3-skew-ps = <120>; + + /* Write value to MMD Address 2h, Register 8h */ + /* RX_CLK Pad Skew [4:0] = -0.9ns (0x0) */ + /* Default is 0b01111, or 15. 15 * 60 ps = 900 ps. 0.90 ns is + * 900 ps. 900 - 900 is 0 ps. + */ + rxc-skew-ps = <0>; + /* GTX_CLK Pad Skew [9:5] = +0.96ns (0x3E) */ + /* Default is 0b01111, or 15. 15 * 60 ps = 900 ps. 0.96 ns is + * 960 ps. 900 + 960 is 1860 ps. + */ + txc-skew-ps = <1860>; + }; +}; + +&sdhci0 { + status = "okay"; +}; + +&ni_uart0 { + status = "okay"; + transceiver = "RS-232"; +}; + +&ni_uart1 { + status = "okay"; + transceiver = "RS-232"; +}; + +&ni_uart2 { + status = "okay"; + transceiver = "RS-485"; +}; + +&can0 { + status = "okay"; +}; + +&usb0 { + status = "okay"; + dr_mode = "host"; +}; + +&clkc { + /* Enable fclk1 for serial. */ + fclk-enable = <0x2>; +}; diff --git a/arch/arm/boot/dts/xilinx/ni-77D5.dts b/arch/arm/boot/dts/xilinx/ni-77D5.dts new file mode 100644 index 0000000000000..0e983d48037b8 --- /dev/null +++ b/arch/arm/boot/dts/xilinx/ni-77D5.dts @@ -0,0 +1,257 @@ +/dts-v1/; +/include/ "ni-zynq.dtsi" + +/ { + model = "NI sbRIO-9627"; + compatible = "ni,zynq", "xlnx,zynq-7000"; + + amba@0 { + i2c0: i2c@e0004000 { + nicpld@40 { + watchdogs { + boot-watchdog { + interrupt-parent = <&gpio>; + interrupts = <1 2 /* IRQ_TYPE_EDGE_FALLING */>; + }; + }; + + leds { + user1-0 { + label = "nilrt:user1:green"; + }; + status-0 { + label = "nilrt:status:yellow"; + max-brightness = <0xFFFF>; + }; + eth0-0 { + label = "nilrt:eth0:green"; + linux,default-trigger = + "e000b000.ethernet-ffffffff:00:100Mbps"; + }; + eth0-1 { + label = "nilrt:eth0:yellow"; + linux,default-trigger = + "e000b000.ethernet-ffffffff:00:1Gbps"; + }; + eth1-0 { + label = "nilrt:eth1:green"; + linux,default-trigger = + "e000b000.ethernet-ffffffff:01:100Mbps"; + }; + eth1-1 { + label = "nilrt:eth1:yellow"; + linux,default-trigger = + "e000b000.ethernet-ffffffff:01:1Gbps"; + }; + }; + }; + + ds3231_rtc@68 { + status = "okay"; + }; + }; + }; +}; + +&gem0 { + status = "okay"; + clocks = <&clkc 30>, <&clkc 13>, <&clkc 15>; + clock-names = "pclk", "hclk", "tx_clk"; + phy-handle = <&phy0>; + phy-mode = "rgmii-id"; + emio-speed-gpios = <0>, + <&gpio 54 0>; + + #address-cells = <0x1>; + #size-cells = <0x0>; + + phy0: phy@0 { + compatible = "micrel,KSZ9031","ethernet-phy-ieee802.3-c22"; + device_type = "ethernet-phy"; + reg = <0x0>; + /* Interrupt on GPIO25, shared with phy1. */ + interrupts = <25 8 /* IRQ_TYPE_LEVEL_LOW */>; + interrupt-parent = <&gpio>; + + /* RX_DV Pad Skew [7:4] = +0.30ns (0xC0) */ + /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 + * ps. 420 + 300 is 720 ps. + */ + rxdv-skew-ps = <720>; + + /* TX_EN Pad Skew [3:0] = -0.30ns (0x02) */ + /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 + * ps. 420 - 300 is 120 ps. + */ + txen-skew-ps = <120>; + + /* RXD 0-3 Pad Skew = +0.30ns (0xC) */ + /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 + * ps. 420 + 300 is 720 ps. + */ + rxd0-skew-ps = <720>; + rxd1-skew-ps = <720>; + rxd2-skew-ps = <720>; + rxd3-skew-ps = <720>; + + /* TXD 0-3 Pad Skew = -0.30ns (0x2) */ + /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 + * ps. 420 - 300 is 120 ps. + */ + txd0-skew-ps = <120>; + txd1-skew-ps = <120>; + txd2-skew-ps = <120>; + txd3-skew-ps = <120>; + + /* Write value to MMD Address 2h, Register 8h */ + /* RX_CLK Pad Skew [4:0] = -0.9ns (0x0) */ + /* Default is 0b01111, or 15. 15 * 60 ps = 900 ps. 0.90 ns is + * 900 ps. 900 - 900 is 0 ps. + */ + rxc-skew-ps = <0>; + /* GTX_CLK Pad Skew [9:5] = +0.96ns (0x3E) */ + /* Default is 0b01111, or 15. 15 * 60 ps = 900 ps. 0.96 ns is + * 960 ps. 900 + 960 is 1860 ps. + */ + txc-skew-ps = <1860>; + }; + + phy1: phy@1 { + compatible = "micrel,KSZ9031","ethernet-phy-ieee802.3-c22"; + device_type = "ethernet-phy"; + reg = <0x1>; + /* Interrupt on GPIO25, shared with phy0. */ + interrupts = <25 8 /* IRQ_TYPE_LEVEL_LOW */>; + interrupt-parent = <&gpio>; + + /* RX_DV Pad Skew [7:4] = +0.30ns (0xC0) */ + /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 + * ps. 420 + 300 is 720 ps. + */ + rxdv-skew-ps = <720>; + + /* TX_EN Pad Skew [3:0] = -0.30ns (0x02) */ + /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 + * ps. 420 - 300 is 120 ps. + */ + txen-skew-ps = <120>; + + /* RXD 0-3 Pad Skew = +0.30ns (0xC) */ + /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 + * ps. 420 + 300 is 720 ps. + */ + rxd0-skew-ps = <720>; + rxd1-skew-ps = <720>; + rxd2-skew-ps = <720>; + rxd3-skew-ps = <720>; + + /* TXD 0-3 Pad Skew = -0.30ns (0x2) */ + /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 + * ps. 420 - 300 is 120 ps. + */ + txd0-skew-ps = <120>; + txd1-skew-ps = <120>; + txd2-skew-ps = <120>; + txd3-skew-ps = <120>; + + /* Write value to MMD Address 2h, Register 8h */ + /* RX_CLK Pad Skew [4:0] = -0.9ns (0x0) */ + /* Default is 0b01111, or 15. 15 * 60 ps = 900 ps. 0.90 ns is + * 900 ps. 900 - 900 is 0 ps. + */ + rxc-skew-ps = <0>; + /* GTX_CLK Pad Skew [9:5] = +0.96ns (0x3E) */ + /* Default is 0b01111, or 15. 15 * 60 ps = 900 ps. 0.96 ns is + * 960 ps. 900 + 960 is 1860 ps. + */ + txc-skew-ps = <1860>; + }; +}; + +&gem1 { + status = "okay"; + clocks = <&clkc 31>, <&clkc 14>, <&clkc 17>; + clock-names = "pclk", "hclk", "tx_clk"; + phy-handle = <&phy1>; + phy-mode = "rgmii-id"; + cdns,no_mdio_bus; + emio-speed-gpios = <0>, + <&gpio 55 0>; +}; + +&sdhci0 { + status = "okay"; +}; + +&sdhci1 { + status = "okay"; + force-sd-standard; +}; + +&ni_uart0 { + status = "okay"; + transceiver = "RS-232"; +}; + +&ni_uart1 { + status = "okay"; + transceiver = "RS-232"; +}; + +&ni_uart2 { + status = "okay"; + transceiver = "RS-485"; +}; + +&ni_uart3 { + status = "okay"; + transceiver = "RS-232"; +}; + +&ni_uart4 { + status = "okay"; + transceiver = "RS-232"; +}; + +&ni_uart5 { + status = "okay"; + transceiver = "RS-232"; +}; + +&ni_uart6 { + status = "okay"; + transceiver = "RS-232"; +}; + +&ni_uart7 { + status = "okay"; + transceiver = "RS-485"; +}; + +&ni_uart8 { + status = "okay"; + transceiver = "RS-485"; +}; + +&can0 { + status = "okay"; +}; + +&can1 { + status = "okay"; +}; + +&usb0 { + status = "okay"; + dr_mode = "host"; +}; + +&usb1 { + status = "okay"; + dr_mode = "peripheral"; +}; + +&clkc { + /* Enable fclk1 for serial. */ + fclk-enable = <0x2>; +}; diff --git a/arch/arm/boot/dts/xilinx/ni-77D6.dts b/arch/arm/boot/dts/xilinx/ni-77D6.dts new file mode 100644 index 0000000000000..c344069dec3c0 --- /dev/null +++ b/arch/arm/boot/dts/xilinx/ni-77D6.dts @@ -0,0 +1,243 @@ +/dts-v1/; +/include/ "ni-zynq.dtsi" + +/ { + model = "NI sbRIO-9607"; + compatible = "ni,zynq", "xlnx,zynq-7000"; + + amba@0 { + i2c0: i2c@e0004000 { + nicpld@40 { + watchdogs { + boot-watchdog { + interrupt-parent = <&gpio>; + interrupts = <1 2 /* IRQ_TYPE_EDGE_FALLING */>; + }; + }; + + leds { + user1-0 { + label = "nilrt:user1:green"; + }; + status-0 { + label = "nilrt:status:yellow"; + max-brightness = <0xFFFF>; + }; + eth0-0 { + label = "nilrt:eth0:green"; + linux,default-trigger = + "e000b000.ethernet-ffffffff:00:100Mbps"; + }; + eth0-1 { + label = "nilrt:eth0:yellow"; + linux,default-trigger = + "e000b000.ethernet-ffffffff:00:1Gbps"; + }; + eth1-0 { + label = "nilrt:eth1:green"; + linux,default-trigger = + "e000b000.ethernet-ffffffff:01:100Mbps"; + }; + eth1-1 { + label = "nilrt:eth1:yellow"; + linux,default-trigger = + "e000b000.ethernet-ffffffff:01:1Gbps"; + }; + }; + }; + + ds3231_rtc@68 { + status = "okay"; + }; + }; + }; +}; + +&gem0 { + status = "okay"; + clocks = <&clkc 30>, <&clkc 13>, <&clkc 15>; + clock-names = "pclk", "hclk", "tx_clk"; + phy-handle = <&phy0>; + phy-mode = "rgmii-id"; + emio-speed-gpios = <0>, + <&gpio 54 0>; + + #address-cells = <0x1>; + #size-cells = <0x0>; + + phy0: phy@0 { + compatible = "micrel,KSZ9031","ethernet-phy-ieee802.3-c22"; + device_type = "ethernet-phy"; + reg = <0x0>; + /* Interrupt on GPIO25, shared with phy1. */ + interrupts = <25 8 /* IRQ_TYPE_LEVEL_LOW */>; + interrupt-parent = <&gpio>; + + /* RX_DV Pad Skew [7:4] = +0.30ns (0xC0) */ + /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 + * ps. 420 + 300 is 720 ps. + */ + rxdv-skew-ps = <720>; + + /* TX_EN Pad Skew [3:0] = -0.30ns (0x02) */ + /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 + * ps. 420 - 300 is 120 ps. + */ + txen-skew-ps = <120>; + + /* RXD 0-3 Pad Skew = +0.30ns (0xC) */ + /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 + * ps. 420 + 300 is 720 ps. + */ + rxd0-skew-ps = <720>; + rxd1-skew-ps = <720>; + rxd2-skew-ps = <720>; + rxd3-skew-ps = <720>; + + /* TXD 0-3 Pad Skew = -0.30ns (0x2) */ + /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 + * ps. 420 - 300 is 120 ps. + */ + txd0-skew-ps = <120>; + txd1-skew-ps = <120>; + txd2-skew-ps = <120>; + txd3-skew-ps = <120>; + + /* Write value to MMD Address 2h, Register 8h */ + /* RX_CLK Pad Skew [4:0] = -0.9ns (0x0) */ + /* Default is 0b01111, or 15. 15 * 60 ps = 900 ps. 0.90 ns is + * 900 ps. 900 - 900 is 0 ps. + */ + rxc-skew-ps = <0>; + /* GTX_CLK Pad Skew [9:5] = +0.96ns (0x3E) */ + /* Default is 0b01111, or 15. 15 * 60 ps = 900 ps. 0.96 ns is + * 960 ps. 900 + 960 is 1860 ps. + */ + txc-skew-ps = <1860>; + }; + + phy1: phy@1 { + compatible = "micrel,KSZ9031","ethernet-phy-ieee802.3-c22"; + device_type = "ethernet-phy"; + reg = <0x1>; + /* Interrupt on GPIO25, shared with phy0. */ + interrupts = <25 8 /* IRQ_TYPE_LEVEL_LOW */>; + interrupt-parent = <&gpio>; + + /* RX_DV Pad Skew [7:4] = +0.30ns (0xC0) */ + /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 + * ps. 420 + 300 is 720 ps. + */ + rxdv-skew-ps = <720>; + + /* TX_EN Pad Skew [3:0] = -0.30ns (0x02) */ + /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 + * ps. 420 - 300 is 120 ps. + */ + txen-skew-ps = <120>; + + /* RXD 0-3 Pad Skew = +0.30ns (0xC) */ + /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 + * ps. 420 + 300 is 720 ps. + */ + rxd0-skew-ps = <720>; + rxd1-skew-ps = <720>; + rxd2-skew-ps = <720>; + rxd3-skew-ps = <720>; + + /* TXD 0-3 Pad Skew = -0.30ns (0x2) */ + /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 + * ps. 420 - 300 is 120 ps. + */ + txd0-skew-ps = <120>; + txd1-skew-ps = <120>; + txd2-skew-ps = <120>; + txd3-skew-ps = <120>; + + /* Write value to MMD Address 2h, Register 8h */ + /* RX_CLK Pad Skew [4:0] = -0.9ns (0x0) */ + /* Default is 0b01111, or 15. 15 * 60 ps = 900 ps. 0.90 ns is + * 900 ps. 900 - 900 is 0 ps. + */ + rxc-skew-ps = <0>; + /* GTX_CLK Pad Skew [9:5] = +0.96ns (0x3E) */ + /* Default is 0b01111, or 15. 15 * 60 ps = 900 ps. 0.96 ns is + * 960 ps. 900 + 960 is 1860 ps. + */ + txc-skew-ps = <1860>; + }; +}; + +&gem1 { + status = "okay"; + clocks = <&clkc 31>, <&clkc 14>, <&clkc 17>; + clock-names = "pclk", "hclk", "tx_clk"; + phy-handle = <&phy1>; + phy-mode = "rgmii-id"; + cdns,no_mdio_bus; + emio-speed-gpios = <0>, + <&gpio 55 0>; +}; + +&sdhci1 { + status = "okay"; + force-sd-standard; +}; + +&ni_uart0 { + status = "okay"; + transceiver = "RS-232"; +}; + +&ni_uart1 { + status = "okay"; + transceiver = "RS-232"; +}; + +&ni_uart2 { + status = "okay"; + transceiver = "RS-232"; +}; + +&ni_uart3 { + status = "okay"; + transceiver = "RS-232"; +}; + +&ni_uart4 { + status = "okay"; + transceiver = "RS-232"; +}; + +&ni_uart5 { + status = "okay"; + transceiver = "RS-485"; +}; + +&ni_uart6 { + status = "okay"; + transceiver = "RS-485"; +}; + +&can0 { + status = "okay"; +}; + +&can1 { + status = "okay"; +}; + +&usb0 { + status = "okay"; + dr_mode = "host"; +}; + +&usb1 { + status = "okay"; + dr_mode = "peripheral"; +}; + +&clkc { + /* Enable fclk1 for serial. */ + fclk-enable = <0x2>; +}; diff --git a/arch/arm/boot/dts/xilinx/ni-7885.dts b/arch/arm/boot/dts/xilinx/ni-7885.dts new file mode 100644 index 0000000000000..661dc24a23baf --- /dev/null +++ b/arch/arm/boot/dts/xilinx/ni-7885.dts @@ -0,0 +1,52 @@ +/dts-v1/; +/include/ "ni-zynq.dtsi" + +/ { + model = "NI ELVIS RIO CM"; + compatible = "ni,zynq", "xlnx,zynq-7000"; + + amba@0 { + i2c0: i2c@e0004000 { + nicpld@40 { + watchdogs { + boot-watchdog { + interrupt-parent = <&gpio>; + interrupts = <24 2 /* IRQ_TYPE_EDGE_FALLING */>; + }; + }; + + leds { + status-1 { + label = "nilrt:status:yellow"; + max-brightness = <0xFFFF>; + }; + }; + }; + }; + }; +}; + +&ni_uart0 { + status = "okay"; + transceiver = "RS-232"; +}; + +&ni_uart1 { + status = "okay"; + transceiver = "RS-232"; +}; + +&usb0 { + status = "okay"; + dr_mode = "host"; +}; + +&usb1 { + status = "okay"; + dr_mode = "peripheral"; +}; + +&clkc { + /* Enable fclk1 for serial. */ + fclk-enable = <0x2>; +}; diff --git a/arch/arm/boot/dts/xilinx/ni-7931.dts b/arch/arm/boot/dts/xilinx/ni-7931.dts new file mode 100644 index 0000000000000..6b1c1d8f57e59 --- /dev/null +++ b/arch/arm/boot/dts/xilinx/ni-7931.dts @@ -0,0 +1,8 @@ +/dts-v1/; +/include/ "ni-793x.dtsi" + +/* NIDEVCODE 77B1 */ + +/ { + model = "NI-7931"; +}; diff --git a/arch/arm/boot/dts/xilinx/ni-7932.dts b/arch/arm/boot/dts/xilinx/ni-7932.dts new file mode 100644 index 0000000000000..3010feed71f70 --- /dev/null +++ b/arch/arm/boot/dts/xilinx/ni-7932.dts @@ -0,0 +1,8 @@ +/dts-v1/; +/include/ "ni-793x.dtsi" + +/* NIDEVCODE 77B2 */ + +/ { + model = "NI-7932"; +}; diff --git a/arch/arm/boot/dts/xilinx/ni-7935.dts b/arch/arm/boot/dts/xilinx/ni-7935.dts new file mode 100644 index 0000000000000..00fb196b3d52a --- /dev/null +++ b/arch/arm/boot/dts/xilinx/ni-7935.dts @@ -0,0 +1,8 @@ +/dts-v1/; +/include/ "ni-793x.dtsi" + +/* NIDEVCODE 77AC */ + +/ { + model = "NI-7935"; +}; diff --git a/arch/arm/boot/dts/xilinx/ni-793C.dts b/arch/arm/boot/dts/xilinx/ni-793C.dts new file mode 100644 index 0000000000000..a2255627d113d --- /dev/null +++ b/arch/arm/boot/dts/xilinx/ni-793C.dts @@ -0,0 +1,155 @@ +/dts-v1/; +/include/ "ni-zynq.dtsi" + +/ { + model = "NI ELVIS III"; + compatible = "ni,zynq", "xlnx,zynq-7000"; + + amba@0 { + i2c0: i2c@e0004000 { + nicpld@40 { + watchdogs { + boot-watchdog { + interrupt-parent = <&gpio>; + interrupts = <1 2 /* IRQ_TYPE_EDGE_FALLING */>; + }; + }; + + leds { + status-0 { + label = "nilrt:status:yellow"; + max-brightness = <0xFFFF>; + }; + eth0-0 { + label = "nilrt:eth0:green"; + linux,default-trigger = + "e000b000.ethernet-ffffffff:00:100Mbps"; + }; + eth0-1 { + label = "nilrt:eth0:yellow"; + linux,default-trigger = + "e000b000.ethernet-ffffffff:00:1Gbps"; + }; + wifi-0 { + label = "nilrt:wifi:primary"; + }; + wifi-1 { + label = "nilrt:wifi:secondary"; + }; + }; + }; + + oleddriver@3C { + compatible = "sinowealth,sh1107"; + reg = <0x3C>; + + oledmodule { + compatible = "truly,oel9m1027"; + }; + }; + }; + }; +}; + +&gem0 { + status = "okay"; + clocks = <&clkc 30>, <&clkc 13>, <&clkc 15>; + clock-names = "pclk", "hclk", "tx_clk"; + phy-handle = <&phy0>; + phy-mode = "rgmii-id"; + emio-speed-gpios = <0>, + <&gpio 54 0>; + + #address-cells = <0x1>; + #size-cells = <0x0>; + + phy0: phy@0 { + compatible = "micrel,KSZ9031","ethernet-phy-ieee802.3-c22"; + device_type = "ethernet-phy"; + reg = <0x0>; + /* Interrupt on GPIO25, shared with phy1. */ + interrupts = <25 8 /* IRQ_TYPE_LEVEL_LOW */>; + interrupt-parent = <&gpio>; + + /* RX_DV Pad Skew [7:4] = +0.30ns (0xC0) */ + /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 + * ps. 420 + 300 is 720 ps. + */ + rxdv-skew-ps = <720>; + + /* TX_EN Pad Skew [3:0] = -0.30ns (0x02) */ + /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 + * ps. 420 - 300 is 120 ps. + */ + txen-skew-ps = <120>; + + /* RXD 0-3 Pad Skew = +0.30ns (0xC) */ + /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 + * ps. 420 + 300 is 720 ps. + */ + rxd0-skew-ps = <720>; + rxd1-skew-ps = <720>; + rxd2-skew-ps = <720>; + rxd3-skew-ps = <720>; + + /* TXD 0-3 Pad Skew = -0.30ns (0x2) */ + /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 + * ps. 420 - 300 is 120 ps. + */ + txd0-skew-ps = <120>; + txd1-skew-ps = <120>; + txd2-skew-ps = <120>; + txd3-skew-ps = <120>; + + /* Write value to MMD Address 2h, Register 8h */ + /* RX_CLK Pad Skew [4:0] = -0.9ns (0x0) */ + /* Default is 0b01111, or 15. 15 * 60 ps = 900 ps. 0.90 ns is + * 900 ps. 900 - 900 is 0 ps. + */ + rxc-skew-ps = <0>; + /* GTX_CLK Pad Skew [9:5] = +0.96ns (0x3E) */ + /* Default is 0b01111, or 15. 15 * 60 ps = 900 ps. 0.96 ns is + * 960 ps. 900 + 960 is 1860 ps. + */ + txc-skew-ps = <1860>; + }; +}; + +&sdhci0 { + status = "okay"; + non-removable = <1>; + + wlan0: wlan@0 { + compatible = "atheros,ath6kl"; + status = "okay"; + atheros,board-id = ""; + atheros,region-code = ""; + }; +}; + +&ni_uart0 { + status = "okay"; + transceiver = "RS-232"; + emio-con-dio-multiplex-gpios = <0>, + <&gpio 56 0>; +}; + +&ni_uart1 { + status = "okay"; + transceiver = "RS-232"; +}; + +&usb0 { + status = "okay"; + dr_mode = "host"; +}; + +&usb1 { + status = "okay"; + dr_mode = "peripheral"; +}; + +&clkc { + /* Enable fclk1 for serial. */ + fclk-enable = <0x2>; +}; diff --git a/arch/arm/boot/dts/xilinx/ni-793x.dtsi b/arch/arm/boot/dts/xilinx/ni-793x.dtsi new file mode 100644 index 0000000000000..2317bdb927553 --- /dev/null +++ b/arch/arm/boot/dts/xilinx/ni-793x.dtsi @@ -0,0 +1,101 @@ +/include/ "ni-zynq.dtsi" + +/ { + compatible = "ni,zynq", "xlnx,zynq-7000"; + + amba@0 { + + leds-ni793x@4020F000 { + compatible = "ni,led-793x"; + reg = <0x4020F000 4>; + user1 { + label = "nilrt:user1:green"; + }; + }; + + i2c0: i2c@e0004000 { + nicpld@40 { + watchdogs { + boot-watchdog { + interrupt-parent = <&gpio>; + interrupts = <15 2 /* IRQ_TYPE_EDGE_FALLING */>; + }; + }; + + leds { + status-0 { + label = "nilrt:status:yellow"; + max-brightness = <0xFFFF>; + }; + eth0-0 { + label = "nilrt:eth0:green"; + linux,default-trigger = + "e000b000.ethernet-ffffffff:00:100Mbps"; + }; + eth0-1 { + label = "nilrt:eth0:yellow"; + linux,default-trigger = + "e000b000.ethernet-ffffffff:00:1Gbps"; + }; + }; + }; + + ds3231_rtc@68 { + status = "okay"; + }; + }; + }; +}; + +&gem0 { + status = "okay"; + + /* No fpga_clk specified because we want our FPGA clock + * (fclk0) to always be 125 MHz. The bootloader sets + * fclk0 to 125 MHz and we just leave it like that. + */ + + phy-handle = <&phy0>; + phy-mode = "rgmii-id"; + #address-cells = <0x1>; + #size-cells = <0x0>; + + emio-speed-gpios = <0>, + <&gpio 54 0>; + + phy0: phy@0 { + compatible = "micrel,KSZ9031","ethernet-phy-ieee802.3-c22"; + device_type = "ethernet-phy"; + reg = <0x0>; + /* Interrupt on GPIO1. */ + interrupts = <1 8 /* IRQ_TYPE_LEVEL_LOW */>; + interrupt-parent = <&gpio>; + + /* Set RX_CLK Pad Skew [4:0] to 0b00000. */ + rxc-skew-ps = <0>; + }; +}; + +&sdhci0 { + status = "okay"; +}; + +&ni_uart0 { + status = "okay"; + transceiver = "RS-232"; +}; + +&usb0 { + status = "okay"; + dr_mode = "peripheral"; +}; + +&usb1 { + status = "okay"; + dr_mode = "host"; +}; + +&clkc { + /* Enable fclk0 for eth0 and eth1, fclk1 for serial. */ + fclk-enable = <0x3>; +}; diff --git a/arch/arm/boot/dts/xilinx/ni-7AAE.dts b/arch/arm/boot/dts/xilinx/ni-7AAE.dts new file mode 100644 index 0000000000000..b01fb7f7b45c2 --- /dev/null +++ b/arch/arm/boot/dts/xilinx/ni-7AAE.dts @@ -0,0 +1,205 @@ +/dts-v1/; +/include/ "ni-zynq.dtsi" + +/ { + model = "NI roboRIO 2.0"; + compatible = "ni,zynq", "xlnx,zynq-7000", "ni,artemis"; + + aliases { + spi0 = &spi0; + spi1 = &spi1; + }; + + leds { + compatible = "gpio-leds"; + wlan1 { + /* green */ + label = "nilrt:wifi:primary"; + gpios = <&gpio 55 0>; + }; + + wlan2 { + /* red */ + label = "nilrt:wifi:secondary"; + gpios = <&gpio 56 0>; + }; + }; + + amba@0 { + adc: adc@f8007100 { + xlnx,channels { + #address-cells = <1>; + #size-cells = <0>; + /* Channel 0 maps to VPVN */ + channel@0 { + reg = <0>; + }; + /* Channel 1 maps to VAUX0 */ + channel@1 { + reg = <1>; + }; + /* Channel 2 maps to VAUX1 */ + channel@2 { + reg = <2>; + }; + /* Channel 3 maps to VAUX2 */ + channel@3 { + reg = <3>; + }; + /* Channel 4 maps to VAUX3 */ + channel@4 { + reg = <4>; + }; + /* Channel 5 maps to VAUX4 */ + channel@5 { + reg = <5>; + }; + /* Channel 9 maps to VAUX8 */ + channel@9 { + reg = <9>; + }; + /* Channel 10 maps to VAUX9 */ + channel@10 { + reg = <10>; + }; + /* Channel 11 maps to VAUX10 */ + channel@11 { + reg = <11>; + }; + /* Channel 12 maps to VAUX11 */ + channel@12 { + reg = <12>; + }; + }; + }; + + smcc@e000e000 { + nand@e1000000 { + status = "disabled"; + }; + }; + + i2c0: i2c@e0004000 { + nicpld@40 { + watchdogs { + boot-watchdog { + interrupt-parent = <&gpio>; + interrupts = <24 2 /* IRQ_TYPE_EDGE_FALLING */>; + }; + }; + + leds { + status-1 { + label = "nilrt:status:yellow"; + max-brightness = <0xFFFF>; + }; + }; + }; + }; + + i2c1: i2c@e0005000 { + status = "okay"; + }; + + i2c2: i2c@81000000 { + status = "okay"; + }; + + spi0: spi@e0006000 { + status = "okay"; + num-cs = <7>; + is-decoded-cs = <1>; + speed-hz = <200000000>; + + spidev@0 { + compatible = "spidev"; + spi-max-frequency = <2000000>; + reg = <0>; + }; + spidev@1 { + compatible = "spidev"; + spi-max-frequency = <2000000>; + reg = <1>; + }; + spidev@2 { + compatible = "spidev"; + spi-max-frequency = <2000000>; + reg = <2>; + }; + spidev@3 { + compatible = "spidev"; + spi-max-frequency = <2000000>; + reg = <3>; + }; + }; + + spi1: spi@e0007000 { + status = "okay"; + num-cs = <3>; + is-decoded-cs = <0>; + speed-hz = <200000000>; + + spidev@0 { + compatible = "spidev"; + spi-max-frequency = <2000000>; + reg = <0>; + }; + }; + }; +}; + +&gem0 { + status = "okay"; + phy-handle = <&phy0>; + phy-mode = "rgmii-id"; + emio-speed-gpios = <&gpio 54 0>, + <0>; + #address-cells = <0x1>; + #size-cells = <0x0>; + + phy0: phy@0 { + compatible = "smsc,lan8720","ethernet-phy-ieee802.3-c22"; + device_type = "ethernet-phy"; + reg = <0x0>; + /* Interrupt pin is connected from PL pin to FPGA IRQ 3 */ + interrupts = <0 32 4>; + smsc,disable-energy-detect; + }; +}; + +&sdhci1 { + status = "okay"; +}; + +&ni_uart0 { + status = "okay"; + transceiver = "RS-232"; +}; + +&ni_uart1 { + status = "okay"; + transceiver = "RS-232"; +}; + +&uart0 { + status = "okay"; +}; + +&can0 { + status = "okay"; +}; + +&usb0 { + status = "okay"; + dr_mode = "host"; +}; + +&usb1 { + status = "okay"; + dr_mode = "peripheral"; +}; + +&clkc { + /* Enable fclk1 for serial. */ + fclk-enable = <0x2>; +}; diff --git a/arch/arm/boot/dts/xilinx/ni-myrio.dtsi b/arch/arm/boot/dts/xilinx/ni-myrio.dtsi new file mode 100644 index 0000000000000..18ec8c1394c50 --- /dev/null +++ b/arch/arm/boot/dts/xilinx/ni-myrio.dtsi @@ -0,0 +1,87 @@ +/include/ "ni-zynq.dtsi" + +/ { + compatible = "ni,zynq", "xlnx,zynq-7000"; + + amba@0 { + i2c0: i2c@e0004000 { + nicpld@40 { + watchdogs { + boot-watchdog { + interrupt-parent = <&gpio>; + interrupts = <24 2 /* IRQ_TYPE_EDGE_FALLING */>; + }; + }; + + switches { + wifi-switch { + interrupt-parent = <&gpio>; + interrupts = <25 2 /* IRQ_TYPE_EDGE_FALLING */>; + }; + }; + + leds { + status-1 { + label = "nilrt:status:yellow"; + max-brightness = <0xFFFF>; + }; + wifi-0 { + label = "nilrt:wifi:primary"; + }; + wifi-1 { + label = "nilrt:wifi:secondary"; + }; + }; + }; + }; + }; +}; + +&sdhci0 { + status = "okay"; + + /* We must force the SDHCI into test mode, so that it + * always pretends to have a card present. This is to + * work-around a hardware bug where TiWi WiFi does not + * have its CD line connected correctly. + */ + xlnx,fails-without-test-cd; + + non-removable = <1>; + + #address-cells = <1>; + #size-cells = <0>; + + wl12xx: wl12xx@0 { + compatible = "ti,wl1271"; + reg = <2>; + interrupt-parent = <&gpio>; + interrupts = <15 0x4>; + ref-clock-frequency = <38400000>; + }; +}; + +&ni_uart0 { + status = "okay"; + transceiver = "RS-232"; +}; + +&ni_uart1 { + status = "okay"; + transceiver = "RS-232"; +}; + +&usb0 { + status = "okay"; + dr_mode = "host"; +}; + +&usb1 { + status = "okay"; + dr_mode = "peripheral"; +}; + +&clkc { + /* Enable fclk1 for serial. */ + fclk-enable = <0x2>; +}; diff --git a/arch/arm/boot/dts/xilinx/ni-solbetter.dtsi b/arch/arm/boot/dts/xilinx/ni-solbetter.dtsi new file mode 100644 index 0000000000000..2e6bb345da74b --- /dev/null +++ b/arch/arm/boot/dts/xilinx/ni-solbetter.dtsi @@ -0,0 +1,199 @@ +/include/ "ni-zynq.dtsi" + +/ { + compatible = "ni,zynq", "xlnx,zynq-7000"; + + amba@0 { + i2c0: i2c@e0004000 { + nicpld@40 { + watchdogs { + boot-watchdog { + interrupt-parent = <&gpio>; + interrupts = <25 2 /* IRQ_TYPE_EDGE_FALLING */>; + }; + }; + + leds { + user1-0 { + label = "nilrt:user1:green"; + }; + status-0 { + label = "nilrt:status:yellow"; + max-brightness = <0xFFFF>; + }; + eth0-0 { + label = "nilrt:eth0:green"; + linux,default-trigger = + "e000b000.ethernet-ffffffff:00:100Mbps"; + }; + eth0-1 { + label = "nilrt:eth0:yellow"; + linux,default-trigger = + "e000b000.ethernet-ffffffff:00:1Gbps"; + }; + eth1-0 { + label = "nilrt:eth1:green"; + linux,default-trigger = + "e000b000.ethernet-ffffffff:01:100Mbps"; + }; + eth1-1 { + label = "nilrt:eth1:yellow"; + linux,default-trigger = + "e000b000.ethernet-ffffffff:01:1Gbps"; + }; + }; + }; + + ds3231_rtc@68 { + status = "okay"; + }; + }; + }; +}; + +&gem0 { + status = "okay"; + clocks = <&clkc 30>, <&clkc 13>, <&clkc 15>; + clock-names = "pclk", "hclk", "tx_clk"; + phy-handle = <&phy0>; + phy-mode = "rgmii-id"; + + emio-speed-gpios = <0>, + <&gpio 54 0>; + + #address-cells = <0x1>; + #size-cells = <0x0>; + + phy0: phy@0 { + compatible = "micrel,KSZ9031","ethernet-phy-ieee802.3-c22"; + device_type = "ethernet-phy"; + reg = <0x0>; + /* Interrupt on GPIO1. */ + interrupts = <1 8 /* IRQ_TYPE_LEVEL_LOW */>; + interrupt-parent = <&gpio>; + + /* RX_DV Pad Skew [7:4] = +0.30ns (0xC0) */ + /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 + * ps. 420 + 300 is 720 ps. + */ + rxdv-skew-ps = <720>; + + /* TX_EN Pad Skew [3:0] = -0.30ns (0x02) */ + /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 + * ps. 420 - 300 is 120 ps. + */ + txen-skew-ps = <120>; + + /* RXD 0-3 Pad Skew = +0.30ns (0xC) */ + /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 + * ps. 420 + 300 is 720 ps. + */ + rxd0-skew-ps = <720>; + rxd1-skew-ps = <720>; + rxd2-skew-ps = <720>; + rxd3-skew-ps = <720>; + + /* TXD 0-3 Pad Skew = -0.30ns (0x2) */ + /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 + * ps. 420 - 300 is 120 ps. + */ + txd0-skew-ps = <120>; + txd1-skew-ps = <120>; + txd2-skew-ps = <120>; + txd3-skew-ps = <120>; + + /* Write value to MMD Address 2h, Register 8h */ + /* RX_CLK Pad Skew [4:0] = -0.9ns (0x0) */ + /* Default is 0b01111, or 15. 15 * 60 ps = 900 ps. 0.90 ns is + * 900 ps. 900 - 900 is 0 ps. + */ + rxc-skew-ps = <0>; + /* GTX_CLK Pad Skew [9:5] = +0.96ns (0x3E) */ + /* Default is 0b01111, or 15. 15 * 60 ps = 900 ps. 0.96 ns is + * 960 ps. 900 + 960 is 1860 ps. + */ + txc-skew-ps = <1860>; + }; + + phy1: phy@1 { + compatible = "micrel,KSZ9031","ethernet-phy-ieee802.3-c22"; + device_type = "ethernet-phy"; + reg = <0x1>; + /* Interrupt on GPIO1, shared with phy0. */ + interrupts = <1 8 /* IRQ_TYPE_LEVEL_LOW */>; + interrupt-parent = <&gpio>; + + /* RX_DV Pad Skew [7:4] = +0.30ns (0xC0) */ + /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 + * ps. 420 + 300 is 720 ps. + */ + rxdv-skew-ps = <720>; + + /* TX_EN Pad Skew [3:0] = -0.30ns (0x02) */ + /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 + * ps. 420 - 300 is 120 ps. + */ + txen-skew-ps = <120>; + + /* RXD 0-3 Pad Skew = +0.30ns (0xC) */ + /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 + * ps. 420 + 300 is 720 ps. + */ + rxd0-skew-ps = <720>; + rxd1-skew-ps = <720>; + rxd2-skew-ps = <720>; + rxd3-skew-ps = <720>; + + /* TXD 0-3 Pad Skew = -0.30ns (0x2) */ + /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 + * ps. 420 - 300 is 120 ps. + */ + txd0-skew-ps = <120>; + txd1-skew-ps = <120>; + txd2-skew-ps = <120>; + txd3-skew-ps = <120>; + + /* Write value to MMD Address 2h, Register 8h */ + /* RX_CLK Pad Skew [4:0] = -0.9ns (0x0) */ + /* Default is 0b01111, or 15. 15 * 60 ps = 900 ps. 0.90 ns is + * 900 ps. 900 - 900 is 0 ps. + */ + rxc-skew-ps = <0>; + /* GTX_CLK Pad Skew [9:5] = +0.96ns (0x3E) */ + /* Default is 0b01111, or 15. 15 * 60 ps = 900 ps. 0.96 ns is + * 960 ps. 900 + 960 is 1860 ps. + */ + txc-skew-ps = <1860>; + }; +}; + +&gem1 { + status = "okay"; + clocks = <&clkc 31>, <&clkc 14>, <&clkc 17>; + clock-names = "pclk", "hclk", "tx_clk"; + phy-handle = <&phy1>; + phy-mode = "rgmii-id"; + cdns,no_mdio_bus; + emio-speed-gpios = <0>, + <&gpio 55 0>; +}; + +&ni_uart0 { + status = "okay"; + transceiver = "RS-232"; +}; + +&usb0 { + status = "okay"; + dr_mode = "host"; +}; + +&usb1 { + status = "okay"; + dr_mode = "peripheral"; +}; + +&clkc { + /* Enable fclk1 for serial. */ + fclk-enable = <0x2>; +}; diff --git a/arch/arm/boot/dts/xilinx/ni-solenetexp.dtsi b/arch/arm/boot/dts/xilinx/ni-solenetexp.dtsi new file mode 100644 index 0000000000000..c81f7abb05376 --- /dev/null +++ b/arch/arm/boot/dts/xilinx/ni-solenetexp.dtsi @@ -0,0 +1,108 @@ +/include/ "ni-zynq.dtsi" + +/ { + compatible = "ni,zynq", "xlnx,zynq-7000"; + + amba@0 { + i2c0: i2c@e0004000 { + nicpld@40 { + watchdogs { + boot-watchdog { + interrupt-parent = <&gpio>; + interrupts = <25 2 /* IRQ_TYPE_EDGE_FALLING */>; + }; + }; + + leds { + status-0 { + label = "nilrt:status:yellow"; + max-brightness = <0xFFFF>; + }; + eth0-0 { + label = "nilrt:eth0:green"; + linux,default-trigger = + "e000b000.ethernet-ffffffff:00:100Mbps"; + }; + eth0-1 { + label = "nilrt:eth0:yellow"; + linux,default-trigger = + "e000b000.ethernet-ffffffff:00:1Gbps"; + }; + }; + }; + + ds3231_rtc@68 { + status = "okay"; + }; + }; + }; +}; + +&gem0 { + status = "okay"; + clocks = <&clkc 30>, <&clkc 13>, <&clkc 15>; + clock-names = "pclk", "hclk", "tx_clk"; + phy-handle = <&phy0>; + phy-mode = "rgmii-id"; + emio-speed-gpios = <0>, + <&gpio 54 0>; + + #address-cells = <0x1>; + #size-cells = <0x0>; + + phy0: phy@0 { + compatible = "micrel,KSZ9031","ethernet-phy-ieee802.3-c22"; + device_type = "ethernet-phy"; + reg = <0x0>; + /* Interrupt on GPIO1. */ + interrupts = <1 8 /* IRQ_TYPE_LEVEL_LOW */>; + interrupt-parent = <&gpio>; + + /* RX_DV Pad Skew [7:4] = +0.30ns (0xC0) */ + /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 + * ps. 420 + 300 is 720 ps. + */ + rxdv-skew-ps = <720>; + + /* TX_EN Pad Skew [3:0] = -0.30ns (0x02) */ + /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 + * ps. 420 - 300 is 120 ps. + */ + txen-skew-ps = <120>; + + /* RXD 0-3 Pad Skew = +0.30ns (0xC) */ + /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 + * ps. 420 + 300 is 720 ps. + */ + rxd0-skew-ps = <720>; + rxd1-skew-ps = <720>; + rxd2-skew-ps = <720>; + rxd3-skew-ps = <720>; + + /* TXD 0-3 Pad Skew = -0.30ns (0x2) */ + /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 + * ps. 420 - 300 is 120 ps. + */ + txd0-skew-ps = <120>; + txd1-skew-ps = <120>; + txd2-skew-ps = <120>; + txd3-skew-ps = <120>; + + /* Write value to MMD Address 2h, Register 8h */ + /* RX_CLK Pad Skew [4:0] = -0.9ns (0x0) */ + /* Default is 0b01111, or 15. 15 * 60 ps = 900 ps. 0.90 ns is + * 900 ps. 900 - 900 is 0 ps. + */ + rxc-skew-ps = <0>; + /* GTX_CLK Pad Skew [9:5] = +0.96ns (0x3E) */ + /* Default is 0b01111, or 15. 15 * 60 ps = 900 ps. 0.96 ns is + * 960 ps. 900 + 960 is 1860 ps. + */ + txc-skew-ps = <1860>; + }; +}; + +&usb1 { + status = "okay"; + dr_mode = "peripheral"; +}; diff --git a/arch/arm/boot/dts/xilinx/ni-solgood.dtsi b/arch/arm/boot/dts/xilinx/ni-solgood.dtsi new file mode 100644 index 0000000000000..d65b51a80aac4 --- /dev/null +++ b/arch/arm/boot/dts/xilinx/ni-solgood.dtsi @@ -0,0 +1,126 @@ +/include/ "ni-zynq.dtsi" + +/ { + compatible = "ni,zynq", "xlnx,zynq-7000"; + + amba@0 { + i2c0: i2c@e0004000 { + nicpld@40 { + watchdogs { + boot-watchdog { + interrupt-parent = <&gpio>; + interrupts = <25 2 /* IRQ_TYPE_EDGE_FALLING */>; + }; + }; + + leds { + user1-0 { + label = "nilrt:user1:green"; + }; + status-0 { + label = "nilrt:status:yellow"; + max-brightness = <0xFFFF>; + }; + eth0-0 { + label = "nilrt:eth0:green"; + linux,default-trigger = + "e000b000.ethernet-ffffffff:00:100Mbps"; + }; + eth0-1 { + label = "nilrt:eth0:yellow"; + linux,default-trigger = + "e000b000.ethernet-ffffffff:00:1Gbps"; + }; + }; + }; + + ds3231_rtc@68 { + status = "okay"; + }; + }; + }; +}; + +&gem0 { + status = "okay"; + clocks = <&clkc 30>, <&clkc 13>, <&clkc 15>; + clock-names = "pclk", "hclk", "tx_clk"; + phy-handle = <&phy0>; + phy-mode = "rgmii-id"; + emio-speed-gpios = <0>, + <&gpio 54 0>; + + #address-cells = <0x1>; + #size-cells = <0x0>; + + phy0: phy@0 { + compatible = "micrel,KSZ9031","ethernet-phy-ieee802.3-c22"; + device_type = "ethernet-phy"; + reg = <0x0>; + /* Interrupt on GPIO1. */ + interrupts = <1 8 /* IRQ_TYPE_LEVEL_LOW */>; + interrupt-parent = <&gpio>; + + /* RX_DV Pad Skew [7:4] = +0.30ns (0xC0) */ + /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 + * ps. 420 + 300 is 720 ps. + */ + rxdv-skew-ps = <720>; + + /* TX_EN Pad Skew [3:0] = -0.30ns (0x02) */ + /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 + * ps. 420 - 300 is 120 ps. + */ + txen-skew-ps = <120>; + + /* RXD 0-3 Pad Skew = +0.30ns (0xC) */ + /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 + * ps. 420 + 300 is 720 ps. + */ + rxd0-skew-ps = <720>; + rxd1-skew-ps = <720>; + rxd2-skew-ps = <720>; + rxd3-skew-ps = <720>; + + /* TXD 0-3 Pad Skew = -0.30ns (0x2) */ + /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 + * ps. 420 - 300 is 120 ps. + */ + txd0-skew-ps = <120>; + txd1-skew-ps = <120>; + txd2-skew-ps = <120>; + txd3-skew-ps = <120>; + + /* Write value to MMD Address 2h, Register 8h */ + /* RX_CLK Pad Skew [4:0] = -0.9ns (0x0) */ + /* Default is 0b01111, or 15. 15 * 60 ps = 900 ps. 0.90 ns is + * 900 ps. 900 - 900 is 0 ps. + */ + rxc-skew-ps = <0>; + /* GTX_CLK Pad Skew [9:5] = +0.96ns (0x3E) */ + /* Default is 0b01111, or 15. 15 * 60 ps = 900 ps. 0.96 ns is + * 960 ps. 900 + 960 is 1860 ps. + */ + txc-skew-ps = <1860>; + }; +}; + +&ni_uart0 { + status = "okay"; + transceiver = "RS-232"; +}; + +&usb0 { + status = "okay"; + dr_mode = "host"; +}; + +&usb1 { + status = "okay"; + dr_mode = "peripheral"; +}; + +&clkc { + /* Enable fclk1 for serial. */ + fclk-enable = <0x2>; +}; From 66f6d8e03305c27697a86ad5d5b594fb65794a6e Mon Sep 17 00:00:00 2001 From: Chaitanya Vadrevu Date: Tue, 21 Jul 2026 18:10:58 -0500 Subject: [PATCH 69/83] ARM: dts: ni: Remove unused dts These have been superceded by ni-.dts. Signed-off-by: Chaitanya Vadrevu --- arch/arm/boot/dts/xilinx/Makefile | 3 - arch/arm/boot/dts/xilinx/ni-7931.dts | 8 - arch/arm/boot/dts/xilinx/ni-7932.dts | 8 - arch/arm/boot/dts/xilinx/ni-7935.dts | 8 - arch/arm/boot/dts/xilinx/ni-793x.dts | 106 --------- arch/arm/boot/dts/xilinx/ni-dosequis.dts | 136 ------------ arch/arm/boot/dts/xilinx/ni-myrio.dts | 93 -------- arch/arm/boot/dts/xilinx/ni-roborio.dts | 191 ---------------- arch/arm/boot/dts/xilinx/ni-sbrio-9607.dts | 233 ------------------- arch/arm/boot/dts/xilinx/ni-sbrio-9627.dts | 247 --------------------- arch/arm/boot/dts/xilinx/ni-sbrio-9637.dts | 137 ------------ arch/arm/boot/dts/xilinx/ni-solbetter.dts | 191 ---------------- arch/arm/boot/dts/xilinx/ni-solenetexp.dts | 106 --------- arch/arm/boot/dts/xilinx/ni-solgood.dts | 124 ----------- arch/arm/boot/dts/xilinx/ni-tecate.dts | 153 ------------- 15 files changed, 1744 deletions(-) delete mode 100644 arch/arm/boot/dts/xilinx/ni-7931.dts delete mode 100644 arch/arm/boot/dts/xilinx/ni-7932.dts delete mode 100644 arch/arm/boot/dts/xilinx/ni-7935.dts delete mode 100644 arch/arm/boot/dts/xilinx/ni-793x.dts delete mode 100644 arch/arm/boot/dts/xilinx/ni-dosequis.dts delete mode 100644 arch/arm/boot/dts/xilinx/ni-myrio.dts delete mode 100644 arch/arm/boot/dts/xilinx/ni-roborio.dts delete mode 100644 arch/arm/boot/dts/xilinx/ni-sbrio-9607.dts delete mode 100644 arch/arm/boot/dts/xilinx/ni-sbrio-9627.dts delete mode 100644 arch/arm/boot/dts/xilinx/ni-sbrio-9637.dts delete mode 100644 arch/arm/boot/dts/xilinx/ni-solbetter.dts delete mode 100644 arch/arm/boot/dts/xilinx/ni-solenetexp.dts delete mode 100644 arch/arm/boot/dts/xilinx/ni-solgood.dts delete mode 100644 arch/arm/boot/dts/xilinx/ni-tecate.dts diff --git a/arch/arm/boot/dts/xilinx/Makefile b/arch/arm/boot/dts/xilinx/Makefile index be4b160debac0..f44bc06d62858 100644 --- a/arch/arm/boot/dts/xilinx/Makefile +++ b/arch/arm/boot/dts/xilinx/Makefile @@ -15,9 +15,6 @@ dtb-$(CONFIG_ARCH_ZYNQ) += \ zynq-zturn-v5.dtb \ zynq-zybo.dtb \ zynq-zybo-z7.dtb \ - ni-7931.dtb \ - ni-7932.dtb \ - ni-7935.dtb \ ni-762F.dtb \ ni-76D3.dtb \ ni-76D6.dtb \ diff --git a/arch/arm/boot/dts/xilinx/ni-7931.dts b/arch/arm/boot/dts/xilinx/ni-7931.dts deleted file mode 100644 index 6b1c1d8f57e59..0000000000000 --- a/arch/arm/boot/dts/xilinx/ni-7931.dts +++ /dev/null @@ -1,8 +0,0 @@ -/dts-v1/; -/include/ "ni-793x.dtsi" - -/* NIDEVCODE 77B1 */ - -/ { - model = "NI-7931"; -}; diff --git a/arch/arm/boot/dts/xilinx/ni-7932.dts b/arch/arm/boot/dts/xilinx/ni-7932.dts deleted file mode 100644 index 3010feed71f70..0000000000000 --- a/arch/arm/boot/dts/xilinx/ni-7932.dts +++ /dev/null @@ -1,8 +0,0 @@ -/dts-v1/; -/include/ "ni-793x.dtsi" - -/* NIDEVCODE 77B2 */ - -/ { - model = "NI-7932"; -}; diff --git a/arch/arm/boot/dts/xilinx/ni-7935.dts b/arch/arm/boot/dts/xilinx/ni-7935.dts deleted file mode 100644 index 00fb196b3d52a..0000000000000 --- a/arch/arm/boot/dts/xilinx/ni-7935.dts +++ /dev/null @@ -1,8 +0,0 @@ -/dts-v1/; -/include/ "ni-793x.dtsi" - -/* NIDEVCODE 77AC */ - -/ { - model = "NI-7935"; -}; diff --git a/arch/arm/boot/dts/xilinx/ni-793x.dts b/arch/arm/boot/dts/xilinx/ni-793x.dts deleted file mode 100644 index 74e373ccad154..0000000000000 --- a/arch/arm/boot/dts/xilinx/ni-793x.dts +++ /dev/null @@ -1,106 +0,0 @@ -/dts-v1/; -/include/ "ni-zynq.dtsi" - -/* NIDEVCODE 77AC */ -/* NIDEVCODE 77B2 */ -/* NIDEVCODE 77B1 */ - -/ { - model = "NI-793x"; - compatible = "ni,zynq", "xlnx,zynq-7000"; - - amba@0 { - - leds-ni793x@4020F000 { - compatible = "ni,led-793x"; - reg = <0x4020F000 4>; - user1 { - label = "nilrt:user1:green"; - }; - }; - - i2c0: i2c@e0004000 { - nicpld@40 { - watchdogs { - boot-watchdog { - interrupt-parent = <&gpio>; - interrupts = <15 2 /* IRQ_TYPE_EDGE_FALLING */>; - }; - }; - - leds { - status-0 { - label = "nilrt:status:yellow"; - max-brightness = <0xFFFF>; - }; - eth0-0 { - label = "nilrt:eth0:green"; - linux,default-trigger = - "e000b000.etherne:00:100Mb"; - }; - eth0-1 { - label = "nilrt:eth0:yellow"; - linux,default-trigger = - "e000b000.etherne:00:Gb"; - }; - }; - }; - - ds3231_rtc@68 { - status = "okay"; - }; - }; - }; -}; - -&gem0 { - status = "okay"; - - /* No fpga_clk specified because we want our FPGA clock - * (fclk0) to always be 125 MHz. The bootloader sets - * fclk0 to 125 MHz and we just leave it like that. */ - - phy-handle = <&phy0>; - phy-mode = "rgmii-id"; - #address-cells = <0x1>; - #size-cells = <0x0>; - - emio-speed-gpios = <0>, - <&gpio 54 0>; - - phy0: phy@0 { - compatible = "micrel,KSZ9031"; - device_type = "ethernet-phy"; - reg = <0x0>; - /* Interrupt on GPIO1. */ - interrupts = <1 8 /* IRQ_TYPE_LEVEL_LOW */>; - interrupt-parent = <&gpio>; - - /* Set RX_CLK Pad Skew [4:0] to 0b00000. */ - rxc-skew-ps = <0>; - }; -}; - -&sdhci0 { - status = "okay"; -}; - -&ni_uart0 { - status = "okay"; - transceiver = "RS-232"; -}; - -&usb0 { - status = "okay"; - dr_mode = "peripheral"; -}; - -&usb1 { - status = "okay"; - dr_mode = "host"; -}; - -&clkc { - /* Enable fclk0 for eth0 and eth1, fclk1 for serial. */ - fclk-enable = <0x3>; -}; diff --git a/arch/arm/boot/dts/xilinx/ni-dosequis.dts b/arch/arm/boot/dts/xilinx/ni-dosequis.dts deleted file mode 100644 index ea43df8ff569a..0000000000000 --- a/arch/arm/boot/dts/xilinx/ni-dosequis.dts +++ /dev/null @@ -1,136 +0,0 @@ -/dts-v1/; -/include/ "ni-zynq.dtsi" - -/* NIDEVCODE 76D6 */ - -/ { - model = "NI Dos Equis"; - compatible = "ni,zynq", "xlnx,zynq-7000"; - - amba@0 { - i2c0: i2c@e0004000 { - nicpld@40 { - watchdogs { - boot-watchdog { - interrupt-parent = <&gpio>; - interrupts = <46 2 /* IRQ_TYPE_EDGE_FALLING */>; - }; - }; - - leds { - user1-0 { - label = "nilrt:user1:green"; - }; - user1-1 { - label = "nilrt:user1:yellow"; - }; - status-0 { - label = "nilrt:status:red"; - }; - status-1 { - label = "nilrt:status:yellow"; - max-brightness = <0xFFFF>; - }; - wifi-0 { - label = "nilrt:wifi:primary"; - }; - wifi-1 { - label = "nilrt:wifi:secondary"; - }; - eth0-0 { - label = "nilrt:eth0:green"; - linux,default-trigger = - "e000b000.etherne:00:100Mb"; - }; - eth0-1 { - label = "nilrt:eth0:yellow"; - linux,default-trigger = - "e000b000.etherne:00:Gb"; - }; - eth1-0 { - label = "nilrt:eth1:green"; - linux,default-trigger = - "e000b000.etherne:01:100Mb"; - }; - eth1-1 { - label = "nilrt:eth1:yellow"; - linux,default-trigger = - "e000b000.etherne:01:Gb"; - }; - }; - }; - - ds3231_rtc@68 { - status = "okay"; - }; - }; - }; -}; - -&gem0 { - status = "okay"; - phy-handle = <&phy0>; - phy-mode = "rgmii-id"; - #address-cells = <0x1>; - #size-cells = <0x0>; - - phy0: phy@0 { - compatible = "marvell,88e1512"; - device_type = "ethernet-phy"; - reg = <0x0>; - /* Interrupt on GPIO1, shared with phy1. */ - interrupts = <1 8 /* IRQ_TYPE_LEVEL_LOW */>; - interrupt-parent = <&gpio>; - /* Page 3, Register 16, LED[2:0] Function - Control Register */ - leds = <0x1881>; - }; - - phy1: phy@1 { - compatible = "marvell,88e1512"; - device_type = "ethernet-phy"; - reg = <0x1>; - /* Interrupt on GPIO1, shared with phy0. */ - interrupts = <1 8 /* IRQ_TYPE_LEVEL_LOW */>; - interrupt-parent = <&gpio>; - /* Page 3, Register 16, LED[2:0] Function - Control Register */ - leds = <0x1881>; - }; -}; - -&gem1 { - status = "okay"; - clocks = <&clkc 31>, <&clkc 14>, <&clkc 15>; - clock-names = "pclk", "hclk", "tx_clk"; - phy-handle = <&phy1>; - phy-mode = "rgmii-id"; - cdns,no_mdio_bus; - emio-speed-gpios = <0>, - <&gpio 54 0>; -}; - -&ni_uart0 { - status = "okay"; - transceiver = "RS-232"; -}; - -&ni_uart1 { - status = "okay"; - transceiver = "RS-232"; -}; - -&ni_uart2 { - status = "okay"; - transceiver = "RS-485"; -}; - -&usb0 { - status = "okay"; - dr_mode = "host"; -}; - -&clkc { - /* Enable fclk1 for serial. */ - fclk-enable = <0x2>; -}; diff --git a/arch/arm/boot/dts/xilinx/ni-myrio.dts b/arch/arm/boot/dts/xilinx/ni-myrio.dts deleted file mode 100644 index cd944323a6cda..0000000000000 --- a/arch/arm/boot/dts/xilinx/ni-myrio.dts +++ /dev/null @@ -1,93 +0,0 @@ -/dts-v1/; -/include/ "ni-zynq.dtsi" - -/* NIDEVCODE 762F */ - -/ { - model = "NI myRIO"; - compatible = "ni,zynq", "xlnx,zynq-7000"; - - amba@0 { - i2c0: i2c@e0004000 { - nicpld@40 { - watchdogs { - boot-watchdog { - interrupt-parent = <&gpio>; - interrupts = <24 2 /* IRQ_TYPE_EDGE_FALLING */>; - }; - }; - - switches { - wifi-switch { - interrupt-parent = <&gpio>; - interrupts = <25 2 /* IRQ_TYPE_EDGE_FALLING */>; - }; - }; - - leds { - status-1 { - label = "nilrt:status:yellow"; - max-brightness = <0xFFFF>; - }; - wifi-0 { - label = "nilrt:wifi:primary"; - }; - wifi-1 { - label = "nilrt:wifi:secondary"; - }; - }; - }; - }; - }; -}; - -&sdhci0 { - status = "okay"; - - /* We must force the SDHCI into test mode, so that it - * always pretends to have a card present. This is to - * work-around a hardware bug where TiWi WiFi does not - * have its CD line connected correctly. */ - force-sd-cd-test-mode = <1>; - - non-removable = <1>; - - wl12xx: wl12xx@0 { - compatible = "ti,wilink6"; - interrupt-parent = <&gpio>; - interrupts = <15 0x4>; - clocks = <&refclock>; - clock-names = "refclock"; - - refclock: refclock { - compatible = "ti,wilink-clock"; - #clock-cells = <0>; - clock-frequency = <38400000>; - }; - }; -}; - -&ni_uart0 { - status = "okay"; - transceiver = "RS-232"; -}; - -&ni_uart1 { - status = "okay"; - transceiver = "RS-232"; -}; - -&usb0 { - status = "okay"; - dr_mode = "host"; -}; - -&usb1 { - status = "okay"; - dr_mode = "peripheral"; -}; - -&clkc { - /* Enable fclk1 for serial. */ - fclk-enable = <0x2>; -}; diff --git a/arch/arm/boot/dts/xilinx/ni-roborio.dts b/arch/arm/boot/dts/xilinx/ni-roborio.dts deleted file mode 100644 index d41d9ba1f3bbe..0000000000000 --- a/arch/arm/boot/dts/xilinx/ni-roborio.dts +++ /dev/null @@ -1,191 +0,0 @@ -/dts-v1/; -/include/ "ni-zynq.dtsi" - -/* NIDEVCODE 76F2 */ - -/ { - model = "NI roboRIO"; - compatible = "ni,zynq", "xlnx,zynq-7000"; - - aliases { - spi0 = &spi0; - spi1 = &spi1; - }; - - amba@0 { - adc: adc@f8007100 { - xlnx,channels { - #address-cells = <1>; - #size-cells = <0>; - /* Channel 0 maps to VPVN */ - channel@0 { - reg = <0>; - xlnx,extend-name = "vin_v"; - }; - /* Channel 1 maps to VAUX0 */ - channel@1 { - reg = <1>; - xlnx,extend-name = "vin_c"; - }; - /* Channel 2 maps to VAUX1 */ - channel@2 { - reg = <2>; - xlnx,extend-name = "user5v_v"; - }; - /* Channel 3 maps to VAUX2 */ - channel@3 { - reg = <3>; - xlnx,extend-name = "user5v_c"; - }; - /* Channel 4 maps to VAUX3 */ - channel@4 { - reg = <4>; - xlnx,extend-name = "user3v3_v"; - }; - /* Channel 5 maps to VAUX4 */ - channel@5 { - reg = <5>; - xlnx,extend-name = "user3v3_c"; - }; - /* Channel 9 maps to VAUX8 */ - channel@9 { - reg = <9>; - xlnx,extend-name = "user6v_c"; - }; - /* Channel 10 maps to VAUX9 */ - channel@10 { - reg = <10>; - xlnx,extend-name = "bist_ao_v"; - }; - /* Channel 11 maps to VAUX10 */ - channel@11 { - reg = <11>; - xlnx,extend-name = "bist_dio_v"; - }; - /* Channel 12 maps to VAUX11 */ - channel@12 { - reg = <12>; - xlnx,extend-name = "user6v_v"; - }; - }; - }; - - i2c0: i2c@e0004000 { - nicpld@40 { - watchdogs { - boot-watchdog { - interrupt-parent = <&gpio>; - interrupts = <24 2 /* IRQ_TYPE_EDGE_FALLING */>; - }; - }; - - leds { - status-1 { - label = "nilrt:status:yellow"; - max-brightness = <0xFFFF>; - }; - }; - }; - }; - - i2c1: i2c@e0005000 { - status = "okay"; - }; - - i2c2: i2c@81000000 { - status = "okay"; - }; - - spi0: spi@e0006000 { - status = "okay"; - num-cs = <7>; - is-decoded-cs = <1>; - speed-hz = <200000000>; - - spidev@0 { - compatible = "spidev"; - spi-max-frequency = <2000000>; - reg = <0>; - }; - spidev@1 { - compatible = "spidev"; - spi-max-frequency = <2000000>; - reg = <1>; - }; - spidev@2 { - compatible = "spidev"; - spi-max-frequency = <2000000>; - reg = <2>; - }; - spidev@3 { - compatible = "spidev"; - spi-max-frequency = <2000000>; - reg = <3>; - }; - }; - - spi1: spi@e0007000 { - status = "okay"; - num-cs = <3>; - is-decoded-cs = <0>; - speed-hz = <200000000>; - - spidev@0 { - compatible = "spidev"; - spi-max-frequency = <2000000>; - reg = <0>; - }; - }; - }; -}; - -&gem0 { - status = "okay"; - phy-handle = <&phy0>; - phy-mode = "rgmii-id"; - emio-speed-gpios = <&gpio 54 0>, - <0>; - #address-cells = <0x1>; - #size-cells = <0x0>; - - phy0: phy@0 { - compatible = "smsc,lan8720"; - device_type = "ethernet-phy"; - reg = <0x0>; - /* Interrupt pin is connected from PL pin to FPGA IRQ 3 */ - interrupts = <0 32 4>; - }; -}; - -&ni_uart0 { - status = "okay"; - transceiver = "RS-232"; -}; - -&ni_uart1 { - status = "okay"; - transceiver = "RS-232"; -}; - -&uart0 { - status = "okay"; -}; - -&can0 { - status = "okay"; -}; - -&usb0 { - status = "okay"; - dr_mode = "host"; -}; - -&usb1 { - status = "okay"; - dr_mode = "peripheral"; -}; - -&clkc { - /* Enable fclk1 for serial. */ - fclk-enable = <0x2>; -}; diff --git a/arch/arm/boot/dts/xilinx/ni-sbrio-9607.dts b/arch/arm/boot/dts/xilinx/ni-sbrio-9607.dts deleted file mode 100644 index e582fca748bf3..0000000000000 --- a/arch/arm/boot/dts/xilinx/ni-sbrio-9607.dts +++ /dev/null @@ -1,233 +0,0 @@ -/dts-v1/; -/include/ "ni-zynq.dtsi" - -/* NIDEVCODE 77D6 */ - -/ { - model = "NI sbRIO-9607"; - compatible = "ni,zynq", "xlnx,zynq-7000"; - - amba@0 { - i2c0: i2c@e0004000 { - nicpld@40 { - watchdogs { - boot-watchdog { - interrupt-parent = <&gpio>; - interrupts = <1 2 /* IRQ_TYPE_EDGE_FALLING */>; - }; - }; - - leds { - user1-0 { - label = "nilrt:user1:green"; - }; - status-0 { - label = "nilrt:status:yellow"; - max-brightness = <0xFFFF>; - }; - eth0-0 { - label = "nilrt:eth0:green"; - linux,default-trigger = - "e000b000.etherne:00:100Mb"; - }; - eth0-1 { - label = "nilrt:eth0:yellow"; - linux,default-trigger = - "e000b000.etherne:00:Gb"; - }; - eth1-0 { - label = "nilrt:eth1:green"; - linux,default-trigger = - "e000b000.etherne:01:100Mb"; - }; - eth1-1 { - label = "nilrt:eth1:yellow"; - linux,default-trigger = - "e000b000.etherne:01:Gb"; - }; - }; - }; - - ds3231_rtc@68 { - status = "okay"; - }; - }; - }; -}; - -&gem0 { - status = "okay"; - clocks = <&clkc 30>, <&clkc 13>, <&clkc 15>; - clock-names = "pclk", "hclk", "tx_clk"; - phy-handle = <&phy0>; - phy-mode = "rgmii-id"; - emio-speed-gpios = <0>, - <&gpio 54 0>; - - #address-cells = <0x1>; - #size-cells = <0x0>; - - phy0: phy@0 { - compatible = "micrel,KSZ9031"; - device_type = "ethernet-phy"; - reg = <0x0>; - /* Interrupt on GPIO25, shared with phy1. */ - interrupts = <25 8 /* IRQ_TYPE_LEVEL_LOW */>; - interrupt-parent = <&gpio>; - - /* RX_DV Pad Skew [7:4] = +0.30ns (0xC0) */ - /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 - * ps. 420 + 300 is 720 ps. */ - rxdv-skew-ps = <720>; - - /* TX_EN Pad Skew [3:0] = -0.30ns (0x02) */ - /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 - * ps. 420 - 300 is 120 ps. */ - txen-skew-ps = <120>; - - /* RXD 0-3 Pad Skew = +0.30ns (0xC) */ - /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 - * ps. 420 + 300 is 720 ps. */ - rxd0-skew-ps = <720>; - rxd1-skew-ps = <720>; - rxd2-skew-ps = <720>; - rxd3-skew-ps = <720>; - - /* TXD 0-3 Pad Skew = -0.30ns (0x2) */ - /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 - * ps. 420 - 300 is 120 ps. */ - txd0-skew-ps = <120>; - txd1-skew-ps = <120>; - txd2-skew-ps = <120>; - txd3-skew-ps = <120>; - - /* Write value to MMD Address 2h, Register 8h */ - /* RX_CLK Pad Skew [4:0] = -0.9ns (0x0) */ - /* Default is 0b01111, or 15. 15 * 60 ps = 900 ps. 0.90 ns is - * 900 ps. 900 - 900 is 0 ps. */ - rxc-skew-ps = <0>; - /* GTX_CLK Pad Skew [9:5] = +0.96ns (0x3E) */ - /* Default is 0b01111, or 15. 15 * 60 ps = 900 ps. 0.96 ns is - * 960 ps. 900 + 960 is 1860 ps. */ - txc-skew-ps = <1860>; - }; - - phy1: phy@1 { - compatible = "micrel,KSZ9031"; - device_type = "ethernet-phy"; - reg = <0x1>; - /* Interrupt on GPIO25, shared with phy0. */ - interrupts = <25 8 /* IRQ_TYPE_LEVEL_LOW */>; - interrupt-parent = <&gpio>; - - /* RX_DV Pad Skew [7:4] = +0.30ns (0xC0) */ - /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 - * ps. 420 + 300 is 720 ps. */ - rxdv-skew-ps = <720>; - - /* TX_EN Pad Skew [3:0] = -0.30ns (0x02) */ - /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 - * ps. 420 - 300 is 120 ps. */ - txen-skew-ps = <120>; - - /* RXD 0-3 Pad Skew = +0.30ns (0xC) */ - /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 - * ps. 420 + 300 is 720 ps. */ - rxd0-skew-ps = <720>; - rxd1-skew-ps = <720>; - rxd2-skew-ps = <720>; - rxd3-skew-ps = <720>; - - /* TXD 0-3 Pad Skew = -0.30ns (0x2) */ - /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 - * ps. 420 - 300 is 120 ps. */ - txd0-skew-ps = <120>; - txd1-skew-ps = <120>; - txd2-skew-ps = <120>; - txd3-skew-ps = <120>; - - /* Write value to MMD Address 2h, Register 8h */ - /* RX_CLK Pad Skew [4:0] = -0.9ns (0x0) */ - /* Default is 0b01111, or 15. 15 * 60 ps = 900 ps. 0.90 ns is - * 900 ps. 900 - 900 is 0 ps. */ - rxc-skew-ps = <0>; - /* GTX_CLK Pad Skew [9:5] = +0.96ns (0x3E) */ - /* Default is 0b01111, or 15. 15 * 60 ps = 900 ps. 0.96 ns is - * 960 ps. 900 + 960 is 1860 ps. */ - txc-skew-ps = <1860>; - }; -}; - -&gem1 { - status = "okay"; - clocks = <&clkc 31>, <&clkc 14>, <&clkc 17>; - clock-names = "pclk", "hclk", "tx_clk"; - phy-handle = <&phy1>; - phy-mode = "rgmii-id"; - cdns,no_mdio_bus; - emio-speed-gpios = <0>, - <&gpio 55 0>; -}; - -&sdhci1 { - status = "okay"; - force-sd-standard; -}; - -&ni_uart0 { - status = "okay"; - transceiver = "RS-232"; -}; - -&ni_uart1 { - status = "okay"; - transceiver = "RS-232"; -}; - -&ni_uart2 { - status = "okay"; - transceiver = "RS-232"; -}; - -&ni_uart3 { - status = "okay"; - transceiver = "RS-232"; -}; - -&ni_uart4 { - status = "okay"; - transceiver = "RS-232"; -}; - -&ni_uart5 { - status = "okay"; - transceiver = "RS-485"; -}; - -&ni_uart6 { - status = "okay"; - transceiver = "RS-485"; -}; - -&can0 { - status = "okay"; -}; - -&can1 { - status = "okay"; -}; - -&usb0 { - status = "okay"; - dr_mode = "host"; -}; - -&usb1 { - status = "okay"; - dr_mode = "peripheral"; -}; - -&clkc { - /* Enable fclk1 for serial. */ - fclk-enable = <0x2>; -}; diff --git a/arch/arm/boot/dts/xilinx/ni-sbrio-9627.dts b/arch/arm/boot/dts/xilinx/ni-sbrio-9627.dts deleted file mode 100644 index 435a6169e0604..0000000000000 --- a/arch/arm/boot/dts/xilinx/ni-sbrio-9627.dts +++ /dev/null @@ -1,247 +0,0 @@ -/dts-v1/; -/include/ "ni-zynq.dtsi" - -/* NIDEVCODE 77D5 */ - -/ { - model = "NI sbRIO-9627"; - compatible = "ni,zynq", "xlnx,zynq-7000"; - - amba@0 { - i2c0: i2c@e0004000 { - nicpld@40 { - watchdogs { - boot-watchdog { - interrupt-parent = <&gpio>; - interrupts = <1 2 /* IRQ_TYPE_EDGE_FALLING */>; - }; - }; - - leds { - user1-0 { - label = "nilrt:user1:green"; - }; - status-0 { - label = "nilrt:status:yellow"; - max-brightness = <0xFFFF>; - }; - eth0-0 { - label = "nilrt:eth0:green"; - linux,default-trigger = - "e000b000.etherne:00:100Mb"; - }; - eth0-1 { - label = "nilrt:eth0:yellow"; - linux,default-trigger = - "e000b000.etherne:00:Gb"; - }; - eth1-0 { - label = "nilrt:eth1:green"; - linux,default-trigger = - "e000b000.etherne:01:100Mb"; - }; - eth1-1 { - label = "nilrt:eth1:yellow"; - linux,default-trigger = - "e000b000.etherne:01:Gb"; - }; - }; - }; - - ds3231_rtc@68 { - status = "okay"; - }; - }; - }; -}; - -&gem0 { - status = "okay"; - clocks = <&clkc 30>, <&clkc 13>, <&clkc 15>; - clock-names = "pclk", "hclk", "tx_clk"; - phy-handle = <&phy0>; - phy-mode = "rgmii-id"; - emio-speed-gpios = <0>, - <&gpio 54 0>; - - #address-cells = <0x1>; - #size-cells = <0x0>; - - phy0: phy@0 { - compatible = "micrel,KSZ9031"; - device_type = "ethernet-phy"; - reg = <0x0>; - /* Interrupt on GPIO25, shared with phy1. */ - interrupts = <25 8 /* IRQ_TYPE_LEVEL_LOW */>; - interrupt-parent = <&gpio>; - - /* RX_DV Pad Skew [7:4] = +0.30ns (0xC0) */ - /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 - * ps. 420 + 300 is 720 ps. */ - rxdv-skew-ps = <720>; - - /* TX_EN Pad Skew [3:0] = -0.30ns (0x02) */ - /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 - * ps. 420 - 300 is 120 ps. */ - txen-skew-ps = <120>; - - /* RXD 0-3 Pad Skew = +0.30ns (0xC) */ - /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 - * ps. 420 + 300 is 720 ps. */ - rxd0-skew-ps = <720>; - rxd1-skew-ps = <720>; - rxd2-skew-ps = <720>; - rxd3-skew-ps = <720>; - - /* TXD 0-3 Pad Skew = -0.30ns (0x2) */ - /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 - * ps. 420 - 300 is 120 ps. */ - txd0-skew-ps = <120>; - txd1-skew-ps = <120>; - txd2-skew-ps = <120>; - txd3-skew-ps = <120>; - - /* Write value to MMD Address 2h, Register 8h */ - /* RX_CLK Pad Skew [4:0] = -0.9ns (0x0) */ - /* Default is 0b01111, or 15. 15 * 60 ps = 900 ps. 0.90 ns is - * 900 ps. 900 - 900 is 0 ps. */ - rxc-skew-ps = <0>; - /* GTX_CLK Pad Skew [9:5] = +0.96ns (0x3E) */ - /* Default is 0b01111, or 15. 15 * 60 ps = 900 ps. 0.96 ns is - * 960 ps. 900 + 960 is 1860 ps. */ - txc-skew-ps = <1860>; - }; - - phy1: phy@1 { - compatible = "micrel,KSZ9031"; - device_type = "ethernet-phy"; - reg = <0x1>; - /* Interrupt on GPIO25, shared with phy0. */ - interrupts = <25 8 /* IRQ_TYPE_LEVEL_LOW */>; - interrupt-parent = <&gpio>; - - /* RX_DV Pad Skew [7:4] = +0.30ns (0xC0) */ - /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 - * ps. 420 + 300 is 720 ps. */ - rxdv-skew-ps = <720>; - - /* TX_EN Pad Skew [3:0] = -0.30ns (0x02) */ - /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 - * ps. 420 - 300 is 120 ps. */ - txen-skew-ps = <120>; - - /* RXD 0-3 Pad Skew = +0.30ns (0xC) */ - /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 - * ps. 420 + 300 is 720 ps. */ - rxd0-skew-ps = <720>; - rxd1-skew-ps = <720>; - rxd2-skew-ps = <720>; - rxd3-skew-ps = <720>; - - /* TXD 0-3 Pad Skew = -0.30ns (0x2) */ - /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 - * ps. 420 - 300 is 120 ps. */ - txd0-skew-ps = <120>; - txd1-skew-ps = <120>; - txd2-skew-ps = <120>; - txd3-skew-ps = <120>; - - /* Write value to MMD Address 2h, Register 8h */ - /* RX_CLK Pad Skew [4:0] = -0.9ns (0x0) */ - /* Default is 0b01111, or 15. 15 * 60 ps = 900 ps. 0.90 ns is - * 900 ps. 900 - 900 is 0 ps. */ - rxc-skew-ps = <0>; - /* GTX_CLK Pad Skew [9:5] = +0.96ns (0x3E) */ - /* Default is 0b01111, or 15. 15 * 60 ps = 900 ps. 0.96 ns is - * 960 ps. 900 + 960 is 1860 ps. */ - txc-skew-ps = <1860>; - }; -}; - -&gem1 { - status = "okay"; - clocks = <&clkc 31>, <&clkc 14>, <&clkc 17>; - clock-names = "pclk", "hclk", "tx_clk"; - phy-handle = <&phy1>; - phy-mode = "rgmii-id"; - cdns,no_mdio_bus; - emio-speed-gpios = <0>, - <&gpio 55 0>; -}; - -&sdhci0 { - status = "okay"; -}; - -&sdhci1 { - status = "okay"; - force-sd-standard; -}; - -&ni_uart0 { - status = "okay"; - transceiver = "RS-232"; -}; - -&ni_uart1 { - status = "okay"; - transceiver = "RS-232"; -}; - -&ni_uart2 { - status = "okay"; - transceiver = "RS-485"; -}; - -&ni_uart3 { - status = "okay"; - transceiver = "RS-232"; -}; - -&ni_uart4 { - status = "okay"; - transceiver = "RS-232"; -}; - -&ni_uart5 { - status = "okay"; - transceiver = "RS-232"; -}; - -&ni_uart6 { - status = "okay"; - transceiver = "RS-232"; -}; - -&ni_uart7 { - status = "okay"; - transceiver = "RS-485"; -}; - -&ni_uart8 { - status = "okay"; - transceiver = "RS-485"; -}; - -&can0 { - status = "okay"; -}; - -&can1 { - status = "okay"; -}; - -&usb0 { - status = "okay"; - dr_mode = "host"; -}; - -&usb1 { - status = "okay"; - dr_mode = "peripheral"; -}; - -&clkc { - /* Enable fclk1 for serial. */ - fclk-enable = <0x2>; -}; diff --git a/arch/arm/boot/dts/xilinx/ni-sbrio-9637.dts b/arch/arm/boot/dts/xilinx/ni-sbrio-9637.dts deleted file mode 100644 index 7626db67b8073..0000000000000 --- a/arch/arm/boot/dts/xilinx/ni-sbrio-9637.dts +++ /dev/null @@ -1,137 +0,0 @@ -/dts-v1/; -/include/ "ni-zynq.dtsi" - -/* NIDEVCODE 77D4 */ - -/ { - model = "NI sbRIO-9637"; - compatible = "ni,zynq", "xlnx,zynq-7000"; - - amba@0 { - i2c0: i2c@e0004000 { - nicpld@40 { - watchdogs { - boot-watchdog { - interrupt-parent = <&gpio>; - interrupts = <1 2 /* IRQ_TYPE_EDGE_FALLING */>; - }; - }; - - leds { - user1-0 { - label = "nilrt:user1:green"; - }; - status-0 { - label = "nilrt:status:yellow"; - max-brightness = <0xFFFF>; - }; - eth0-0 { - label = "nilrt:eth0:green"; - linux,default-trigger = - "e000b000.etherne:00:100Mb"; - }; - eth0-1 { - label = "nilrt:eth0:yellow"; - linux,default-trigger = - "e000b000.etherne:00:Gb"; - }; - }; - }; - - ds3231_rtc@68 { - status = "okay"; - }; - }; - }; -}; - -&gem0 { - status = "okay"; - clocks = <&clkc 30>, <&clkc 13>, <&clkc 15>; - clock-names = "pclk", "hclk", "tx_clk"; - phy-handle = <&phy0>; - phy-mode = "rgmii-id"; - emio-speed-gpios = <0>, - <&gpio 54 0>; - - #address-cells = <0x1>; - #size-cells = <0x0>; - - phy0: phy@0 { - compatible = "micrel,KSZ9031"; - device_type = "ethernet-phy"; - reg = <0x0>; - /* Interrupt on GPIO25. */ - interrupts = <25 8 /* IRQ_TYPE_LEVEL_LOW */>; - interrupt-parent = <&gpio>; - - /* RX_DV Pad Skew [7:4] = +0.30ns (0xC0) */ - /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 - * ps. 420 + 300 is 720 ps. */ - rxdv-skew-ps = <720>; - - /* TX_EN Pad Skew [3:0] = -0.30ns (0x02) */ - /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 - * ps. 420 - 300 is 120 ps. */ - txen-skew-ps = <120>; - - /* RXD 0-3 Pad Skew = +0.30ns (0xC) */ - /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 - * ps. 420 + 300 is 720 ps. */ - rxd0-skew-ps = <720>; - rxd1-skew-ps = <720>; - rxd2-skew-ps = <720>; - rxd3-skew-ps = <720>; - - /* TXD 0-3 Pad Skew = -0.30ns (0x2) */ - /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 - * ps. 420 - 300 is 120 ps. */ - txd0-skew-ps = <120>; - txd1-skew-ps = <120>; - txd2-skew-ps = <120>; - txd3-skew-ps = <120>; - - /* Write value to MMD Address 2h, Register 8h */ - /* RX_CLK Pad Skew [4:0] = -0.9ns (0x0) */ - /* Default is 0b01111, or 15. 15 * 60 ps = 900 ps. 0.90 ns is - * 900 ps. 900 - 900 is 0 ps. */ - rxc-skew-ps = <0>; - /* GTX_CLK Pad Skew [9:5] = +0.96ns (0x3E) */ - /* Default is 0b01111, or 15. 15 * 60 ps = 900 ps. 0.96 ns is - * 960 ps. 900 + 960 is 1860 ps. */ - txc-skew-ps = <1860>; - }; -}; - -&sdhci0 { - status = "okay"; -}; - -&ni_uart0 { - status = "okay"; - transceiver = "RS-232"; -}; - -&ni_uart1 { - status = "okay"; - transceiver = "RS-232"; -}; - -&ni_uart2 { - status = "okay"; - transceiver = "RS-485"; -}; - -&can0 { - status = "okay"; -}; - -&usb0 { - status = "okay"; - dr_mode = "host"; -}; - -&clkc { - /* Enable fclk1 for serial. */ - fclk-enable = <0x2>; -}; diff --git a/arch/arm/boot/dts/xilinx/ni-solbetter.dts b/arch/arm/boot/dts/xilinx/ni-solbetter.dts deleted file mode 100644 index b8315f0fe7506..0000000000000 --- a/arch/arm/boot/dts/xilinx/ni-solbetter.dts +++ /dev/null @@ -1,191 +0,0 @@ -/dts-v1/; -/include/ "ni-zynq.dtsi" - -/* NIDEVCODE 7744 */ - -/ { - model = "NI Sol"; - compatible = "ni,zynq", "xlnx,zynq-7000"; - - amba@0 { - i2c0: i2c@e0004000 { - nicpld@40 { - watchdogs { - boot-watchdog { - interrupt-parent = <&gpio>; - interrupts = <25 2 /* IRQ_TYPE_EDGE_FALLING */>; - }; - }; - - leds { - user1-0 { - label = "nilrt:user1:green"; - }; - status-0 { - label = "nilrt:status:yellow"; - max-brightness = <0xFFFF>; - }; - eth0-0 { - label = "nilrt:eth0:green"; - linux,default-trigger = - "e000b000.etherne:00:100Mb"; - }; - eth0-1 { - label = "nilrt:eth0:yellow"; - linux,default-trigger = - "e000b000.etherne:00:Gb"; - }; - eth1-0 { - label = "nilrt:eth1:green"; - linux,default-trigger = - "e000b000.etherne:01:100Mb"; - }; - eth1-1 { - label = "nilrt:eth1:yellow"; - linux,default-trigger = - "e000b000.etherne:01:Gb"; - }; - }; - }; - - ds3231_rtc@68 { - status = "okay"; - }; - }; - }; -}; - -&gem0 { - status = "okay"; - clocks = <&clkc 30>, <&clkc 13>, <&clkc 15>; - clock-names = "pclk", "hclk", "tx_clk"; - phy-handle = <&phy0>; - phy-mode = "rgmii-id"; - - emio-speed-gpios = <0>, - <&gpio 54 0>; - - #address-cells = <0x1>; - #size-cells = <0x0>; - - phy0: phy@0 { - compatible = "micrel,KSZ9031"; - device_type = "ethernet-phy"; - reg = <0x0>; - /* Interrupt on GPIO1. */ - interrupts = <1 8 /* IRQ_TYPE_LEVEL_LOW */>; - interrupt-parent = <&gpio>; - - /* RX_DV Pad Skew [7:4] = +0.30ns (0xC0) */ - /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 - * ps. 420 + 300 is 720 ps. */ - rxdv-skew-ps = <720>; - - /* TX_EN Pad Skew [3:0] = -0.30ns (0x02) */ - /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 - * ps. 420 - 300 is 120 ps. */ - txen-skew-ps = <120>; - - /* RXD 0-3 Pad Skew = +0.30ns (0xC) */ - /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 - * ps. 420 + 300 is 720 ps. */ - rxd0-skew-ps = <720>; - rxd1-skew-ps = <720>; - rxd2-skew-ps = <720>; - rxd3-skew-ps = <720>; - - /* TXD 0-3 Pad Skew = -0.30ns (0x2) */ - /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 - * ps. 420 - 300 is 120 ps. */ - txd0-skew-ps = <120>; - txd1-skew-ps = <120>; - txd2-skew-ps = <120>; - txd3-skew-ps = <120>; - - /* Write value to MMD Address 2h, Register 8h */ - /* RX_CLK Pad Skew [4:0] = -0.9ns (0x0) */ - /* Default is 0b01111, or 15. 15 * 60 ps = 900 ps. 0.90 ns is - * 900 ps. 900 - 900 is 0 ps. */ - rxc-skew-ps = <0>; - /* GTX_CLK Pad Skew [9:5] = +0.96ns (0x3E) */ - /* Default is 0b01111, or 15. 15 * 60 ps = 900 ps. 0.96 ns is - * 960 ps. 900 + 960 is 1860 ps. */ - txc-skew-ps = <1860>; - }; - - phy1: phy@1 { - compatible = "micrel,KSZ9031"; - device_type = "ethernet-phy"; - reg = <0x1>; - /* Interrupt on GPIO1, shared with phy0. */ - interrupts = <1 8 /* IRQ_TYPE_LEVEL_LOW */>; - interrupt-parent = <&gpio>; - - /* RX_DV Pad Skew [7:4] = +0.30ns (0xC0) */ - /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 - * ps. 420 + 300 is 720 ps. */ - rxdv-skew-ps = <720>; - - /* TX_EN Pad Skew [3:0] = -0.30ns (0x02) */ - /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 - * ps. 420 - 300 is 120 ps. */ - txen-skew-ps = <120>; - - /* RXD 0-3 Pad Skew = +0.30ns (0xC) */ - /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 - * ps. 420 + 300 is 720 ps. */ - rxd0-skew-ps = <720>; - rxd1-skew-ps = <720>; - rxd2-skew-ps = <720>; - rxd3-skew-ps = <720>; - - /* TXD 0-3 Pad Skew = -0.30ns (0x2) */ - /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 - * ps. 420 - 300 is 120 ps. */ - txd0-skew-ps = <120>; - txd1-skew-ps = <120>; - txd2-skew-ps = <120>; - txd3-skew-ps = <120>; - - /* Write value to MMD Address 2h, Register 8h */ - /* RX_CLK Pad Skew [4:0] = -0.9ns (0x0) */ - /* Default is 0b01111, or 15. 15 * 60 ps = 900 ps. 0.90 ns is - * 900 ps. 900 - 900 is 0 ps. */ - rxc-skew-ps = <0>; - /* GTX_CLK Pad Skew [9:5] = +0.96ns (0x3E) */ - /* Default is 0b01111, or 15. 15 * 60 ps = 900 ps. 0.96 ns is - * 960 ps. 900 + 960 is 1860 ps. */ - txc-skew-ps = <1860>; - }; -}; - -&gem1 { - status = "okay"; - clocks = <&clkc 31>, <&clkc 14>, <&clkc 17>; - clock-names = "pclk", "hclk", "tx_clk"; - phy-handle = <&phy1>; - phy-mode = "rgmii-id"; - cdns,no_mdio_bus; - emio-speed-gpios = <0>, - <&gpio 55 0>; -}; - -&ni_uart0 { - status = "okay"; - transceiver = "RS-232"; -}; - -&usb0 { - status = "okay"; - dr_mode = "host"; -}; - -&usb1 { - status = "okay"; - dr_mode = "peripheral"; -}; - -&clkc { - /* Enable fclk1 for serial. */ - fclk-enable = <0x2>; -}; diff --git a/arch/arm/boot/dts/xilinx/ni-solenetexp.dts b/arch/arm/boot/dts/xilinx/ni-solenetexp.dts deleted file mode 100644 index a495ca23e8861..0000000000000 --- a/arch/arm/boot/dts/xilinx/ni-solenetexp.dts +++ /dev/null @@ -1,106 +0,0 @@ -/dts-v1/; -/include/ "ni-zynq.dtsi" - -/* NIDEVCODE 774E */ - -/ { - model = "NI Sol"; - compatible = "ni,zynq", "xlnx,zynq-7000"; - - amba@0 { - i2c0: i2c@e0004000 { - nicpld@40 { - watchdogs { - boot-watchdog { - interrupt-parent = <&gpio>; - interrupts = <25 2 /* IRQ_TYPE_EDGE_FALLING */>; - }; - }; - - leds { - status-0 { - label = "nilrt:status:yellow"; - max-brightness = <0xFFFF>; - }; - eth0-0 { - label = "nilrt:eth0:green"; - linux,default-trigger = - "e000b000.etherne:00:100Mb"; - }; - eth0-1 { - label = "nilrt:eth0:yellow"; - linux,default-trigger = - "e000b000.etherne:00:Gb"; - }; - }; - }; - - ds3231_rtc@68 { - status = "okay"; - }; - }; - }; -}; - -&gem0 { - status = "okay"; - clocks = <&clkc 30>, <&clkc 13>, <&clkc 15>; - clock-names = "pclk", "hclk", "tx_clk"; - phy-handle = <&phy0>; - phy-mode = "rgmii-id"; - emio-speed-gpios = <0>, - <&gpio 54 0>; - - #address-cells = <0x1>; - #size-cells = <0x0>; - - phy0: phy@0 { - compatible = "micrel,KSZ9031"; - device_type = "ethernet-phy"; - reg = <0x0>; - /* Interrupt on GPIO1. */ - interrupts = <1 8 /* IRQ_TYPE_LEVEL_LOW */>; - interrupt-parent = <&gpio>; - - /* RX_DV Pad Skew [7:4] = +0.30ns (0xC0) */ - /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 - * ps. 420 + 300 is 720 ps. */ - rxdv-skew-ps = <720>; - - /* TX_EN Pad Skew [3:0] = -0.30ns (0x02) */ - /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 - * ps. 420 - 300 is 120 ps. */ - txen-skew-ps = <120>; - - /* RXD 0-3 Pad Skew = +0.30ns (0xC) */ - /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 - * ps. 420 + 300 is 720 ps. */ - rxd0-skew-ps = <720>; - rxd1-skew-ps = <720>; - rxd2-skew-ps = <720>; - rxd3-skew-ps = <720>; - - /* TXD 0-3 Pad Skew = -0.30ns (0x2) */ - /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 - * ps. 420 - 300 is 120 ps. */ - txd0-skew-ps = <120>; - txd1-skew-ps = <120>; - txd2-skew-ps = <120>; - txd3-skew-ps = <120>; - - /* Write value to MMD Address 2h, Register 8h */ - /* RX_CLK Pad Skew [4:0] = -0.9ns (0x0) */ - /* Default is 0b01111, or 15. 15 * 60 ps = 900 ps. 0.90 ns is - * 900 ps. 900 - 900 is 0 ps. */ - rxc-skew-ps = <0>; - /* GTX_CLK Pad Skew [9:5] = +0.96ns (0x3E) */ - /* Default is 0b01111, or 15. 15 * 60 ps = 900 ps. 0.96 ns is - * 960 ps. 900 + 960 is 1860 ps. */ - txc-skew-ps = <1860>; - }; -}; - -&usb1 { - status = "okay"; - dr_mode = "peripheral"; -}; diff --git a/arch/arm/boot/dts/xilinx/ni-solgood.dts b/arch/arm/boot/dts/xilinx/ni-solgood.dts deleted file mode 100644 index 4b25334247076..0000000000000 --- a/arch/arm/boot/dts/xilinx/ni-solgood.dts +++ /dev/null @@ -1,124 +0,0 @@ -/dts-v1/; -/include/ "ni-zynq.dtsi" - -/* NIDEVCODE 7743 */ - -/ { - model = "NI Sol"; - compatible = "ni,zynq", "xlnx,zynq-7000"; - - amba@0 { - i2c0: i2c@e0004000 { - nicpld@40 { - watchdogs { - boot-watchdog { - interrupt-parent = <&gpio>; - interrupts = <25 2 /* IRQ_TYPE_EDGE_FALLING */>; - }; - }; - - leds { - user1-0 { - label = "nilrt:user1:green"; - }; - status-0 { - label = "nilrt:status:yellow"; - max-brightness = <0xFFFF>; - }; - eth0-0 { - label = "nilrt:eth0:green"; - linux,default-trigger = - "e000b000.etherne:00:100Mb"; - }; - eth0-1 { - label = "nilrt:eth0:yellow"; - linux,default-trigger = - "e000b000.etherne:00:Gb"; - }; - }; - }; - - ds3231_rtc@68 { - status = "okay"; - }; - }; - }; -}; - -&gem0 { - status = "okay"; - clocks = <&clkc 30>, <&clkc 13>, <&clkc 15>; - clock-names = "pclk", "hclk", "tx_clk"; - phy-handle = <&phy0>; - phy-mode = "rgmii-id"; - emio-speed-gpios = <0>, - <&gpio 54 0>; - - #address-cells = <0x1>; - #size-cells = <0x0>; - - phy0: phy@0 { - compatible = "micrel,KSZ9031"; - device_type = "ethernet-phy"; - reg = <0x0>; - /* Interrupt on GPIO1. */ - interrupts = <1 8 /* IRQ_TYPE_LEVEL_LOW */>; - interrupt-parent = <&gpio>; - - /* RX_DV Pad Skew [7:4] = +0.30ns (0xC0) */ - /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 - * ps. 420 + 300 is 720 ps. */ - rxdv-skew-ps = <720>; - - /* TX_EN Pad Skew [3:0] = -0.30ns (0x02) */ - /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 - * ps. 420 - 300 is 120 ps. */ - txen-skew-ps = <120>; - - /* RXD 0-3 Pad Skew = +0.30ns (0xC) */ - /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 - * ps. 420 + 300 is 720 ps. */ - rxd0-skew-ps = <720>; - rxd1-skew-ps = <720>; - rxd2-skew-ps = <720>; - rxd3-skew-ps = <720>; - - /* TXD 0-3 Pad Skew = -0.30ns (0x2) */ - /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 - * ps. 420 - 300 is 120 ps. */ - txd0-skew-ps = <120>; - txd1-skew-ps = <120>; - txd2-skew-ps = <120>; - txd3-skew-ps = <120>; - - /* Write value to MMD Address 2h, Register 8h */ - /* RX_CLK Pad Skew [4:0] = -0.9ns (0x0) */ - /* Default is 0b01111, or 15. 15 * 60 ps = 900 ps. 0.90 ns is - * 900 ps. 900 - 900 is 0 ps. */ - rxc-skew-ps = <0>; - /* GTX_CLK Pad Skew [9:5] = +0.96ns (0x3E) */ - /* Default is 0b01111, or 15. 15 * 60 ps = 900 ps. 0.96 ns is - * 960 ps. 900 + 960 is 1860 ps. */ - txc-skew-ps = <1860>; - }; -}; - -&ni_uart0 { - status = "okay"; - transceiver = "RS-232"; -}; - -&usb0 { - status = "okay"; - dr_mode = "host"; -}; - -&usb1 { - status = "okay"; - dr_mode = "peripheral"; -}; - -&clkc { - /* Enable fclk1 for serial. */ - fclk-enable = <0x2>; -}; diff --git a/arch/arm/boot/dts/xilinx/ni-tecate.dts b/arch/arm/boot/dts/xilinx/ni-tecate.dts deleted file mode 100644 index 15124e4b12cad..0000000000000 --- a/arch/arm/boot/dts/xilinx/ni-tecate.dts +++ /dev/null @@ -1,153 +0,0 @@ -/dts-v1/; -/include/ "ni-zynq.dtsi" - -/* NIDEVCODE 775E */ - -/ { - model = "NI Tecate"; - compatible = "ni,zynq", "xlnx,zynq-7000"; - - amba@0 { - i2c0: i2c@e0004000 { - nicpld@40 { - watchdogs { - boot-watchdog { - interrupt-parent = <&gpio>; - interrupts = <15 2 /* IRQ_TYPE_EDGE_FALLING */>; - }; - }; - - leds { - status-0 { - label = "nilrt:status:yellow"; - max-brightness = <0xFFFF>; - }; - eth0-0 { - label = "nilrt:eth0:green"; - linux,default-trigger = - "e000b000.etherne:00:100Mb"; - }; - eth0-1 { - label = "nilrt:eth0:yellow"; - linux,default-trigger = - "e000b000.etherne:00:Gb"; - }; - }; - }; - - ds3231_rtc@68 { - status = "okay"; - }; - }; - }; -}; - -&gem0 { - status = "okay"; - - /* No fpga_clk specified because we want our FPGA clock - * (fclk0) to always be 125 MHz. The bootloader sets - * fclk0 to 125 MHz and we just leave it like that. */ - - phy-handle = <&phy0>; - phy-mode = "rgmii-id"; - #address-cells = <0x1>; - #size-cells = <0x0>; - - emio-speed-gpios = <0>, - <&gpio 54 0>; - - phy0: phy@0 { - compatible = "micrel,KSZ9031"; - device_type = "ethernet-phy"; - reg = <0x0>; - /* Interrupt on GPIO1. */ - interrupts = <1 8 /* IRQ_TYPE_LEVEL_LOW */>; - interrupt-parent = <&gpio>; - - /* Set RX_CLK Pad Skew [4:0] to 0b00000. */ - rxc-skew-ps = <0>; - }; -}; - -&gem1 { - status = "okay"; - - /* No fpga_clk specified because we want our FPGA clock (fclk0) to - * always be 125 MHz. The bootloader sets fclk0 to 125 MHz and we just - * leave it like that. */ - - phy-handle = <&phy1>; - phy-mode = "rgmii-id"; - #address-cells = <0x1>; - #size-cells = <0x0>; - - emio-speed-gpios = <&gpio 56 0>, - <&gpio 55 0>; - - phy1: phy@1 { - compatible = "micrel,KSZ9031"; - device_type = "ethernet-phy"; - reg = <0x1>; - /* Interrupt on GPIO57. */ - interrupts = <57 8 /* IRQ_TYPE_LEVEL_LOW */>; - interrupt-parent = <&gpio>; - }; -}; - -&sdhci0 { - status = "okay"; -}; - -&ni_uart0 { - status = "okay"; - transceiver = "RS-232"; -}; - -&ni_uart1 { - status = "okay"; - transceiver = "RS-232"; -}; - -&ni_uart2 { - status = "okay"; - transceiver = "RS-232"; -}; - -&ni_uart3 { - status = "okay"; - transceiver = "RS-232"; -}; - -&ni_uart4 { - status = "okay"; - transceiver = "RS-485"; -}; - -&ni_uart5 { - status = "okay"; - transceiver = "RS-485"; -}; - -&can0 { - status = "okay"; -}; - -&can1 { - status = "okay"; -}; - -&usb0 { - status = "okay"; - dr_mode = "peripheral"; -}; - -&usb1 { - status = "okay"; - dr_mode = "host"; -}; - -&clkc { - /* Enable fclk0 for eth0 and eth1, fclk1 for serial. */ - fclk-enable = <0x3>; -}; From b75c7121c55595ed40d444e5464c19e437f18d8d Mon Sep 17 00:00:00 2001 From: Chaitanya Vadrevu Date: Tue, 21 Jul 2026 18:33:26 -0500 Subject: [PATCH 70/83] ARM: dts: ni: Adapt boards to the current Zynq hierarchy The NI device trees were copied from the 4.14 kernel and still reopen SoC nodes using their old names and hierarchy. The current Zynq device tree defines these nodes with labels and uses gpio0 for the GPIO controller. Convert the NI board files to extend the existing amba, I2C, SPI, and ADC nodes through label references. Update GPIO references from gpio to gpio0 and move the myRIO I2C and SPI configuration to the corresponding labeled nodes. This allows the NI Zynq device trees to compile against the current zynq-7000.dtsi. Signed-off-by: Chaitanya Vadrevu --- arch/arm/boot/dts/xilinx/ni-76D6.dts | 15 ++- arch/arm/boot/dts/xilinx/ni-76F2.dts | 106 +++++++++--------- arch/arm/boot/dts/xilinx/ni-775E.dts | 18 ++- arch/arm/boot/dts/xilinx/ni-77D4.dts | 12 +- arch/arm/boot/dts/xilinx/ni-77D5.dts | 16 ++- arch/arm/boot/dts/xilinx/ni-77D6.dts | 16 ++- arch/arm/boot/dts/xilinx/ni-7885.dts | 8 +- arch/arm/boot/dts/xilinx/ni-793C.dts | 14 +-- arch/arm/boot/dts/xilinx/ni-793x.dtsi | 27 +++-- arch/arm/boot/dts/xilinx/ni-7AAE.dts | 116 ++++++++++---------- arch/arm/boot/dts/xilinx/ni-myrio.dtsi | 12 +- arch/arm/boot/dts/xilinx/ni-solbetter.dtsi | 16 ++- arch/arm/boot/dts/xilinx/ni-solenetexp.dtsi | 12 +- arch/arm/boot/dts/xilinx/ni-solgood.dtsi | 12 +- 14 files changed, 187 insertions(+), 213 deletions(-) diff --git a/arch/arm/boot/dts/xilinx/ni-76D6.dts b/arch/arm/boot/dts/xilinx/ni-76D6.dts index 22fd6b41cd3e4..1b4f69deff8ac 100644 --- a/arch/arm/boot/dts/xilinx/ni-76D6.dts +++ b/arch/arm/boot/dts/xilinx/ni-76D6.dts @@ -4,13 +4,14 @@ / { model = "NI cRIO-9068"; compatible = "ni,zynq", "xlnx,zynq-7000"; +}; + - amba@0 { - i2c0: i2c@e0004000 { +&i2c0 { nicpld@40 { watchdogs { boot-watchdog { - interrupt-parent = <&gpio>; + interrupt-parent = <&gpio0>; interrupts = <46 2 /* IRQ_TYPE_EDGE_FALLING */>; }; }; @@ -55,8 +56,6 @@ ds3231_rtc@68 { status = "okay"; }; - }; - }; }; &gem0 { @@ -72,7 +71,7 @@ reg = <0x0>; /* Interrupt on GPIO1, shared with phy1. */ interrupts = <1 8 /* IRQ_TYPE_LEVEL_LOW */>; - interrupt-parent = <&gpio>; + interrupt-parent = <&gpio0>; /* marvell,reg-init = * @@ -89,7 +88,7 @@ reg = <0x1>; /* Interrupt on GPIO1, shared with phy0. */ interrupts = <1 8 /* IRQ_TYPE_LEVEL_LOW */>; - interrupt-parent = <&gpio>; + interrupt-parent = <&gpio0>; /* marvell,reg-init = * @@ -109,7 +108,7 @@ phy-mode = "rgmii-id"; cdns,no_mdio_bus; emio-speed-gpios = <0>, - <&gpio 54 0>; + <&gpio0 54 0>; }; &ni_uart0 { diff --git a/arch/arm/boot/dts/xilinx/ni-76F2.dts b/arch/arm/boot/dts/xilinx/ni-76F2.dts index ef161a68d0f68..f7b640041f1f6 100644 --- a/arch/arm/boot/dts/xilinx/ni-76F2.dts +++ b/arch/arm/boot/dts/xilinx/ni-76F2.dts @@ -15,18 +15,18 @@ wlan1 { /* green */ label = "nilrt:wifi:primary"; - gpios = <&gpio 55 0>; + gpios = <&gpio0 55 0>; }; wlan2 { /* red */ label = "nilrt:wifi:secondary"; - gpios = <&gpio 56 0>; + gpios = <&gpio0 56 0>; }; }; +}; - amba@0 { - adc: adc@f8007100 { +&adc { xlnx,channels { #address-cells = <1>; #size-cells = <0>; @@ -71,13 +71,13 @@ reg = <12>; }; }; - }; +}; - i2c0: i2c@e0004000 { +&i2c0 { nicpld@40 { watchdogs { boot-watchdog { - interrupt-parent = <&gpio>; + interrupt-parent = <&gpio0>; interrupts = <24 2 /* IRQ_TYPE_EDGE_FALLING */>; }; }; @@ -89,56 +89,54 @@ }; }; }; - }; - - i2c1: i2c@e0005000 { - status = "okay"; - }; - - i2c2: i2c@81000000 { - status = "okay"; - }; +}; - spi0: spi@e0006000 { - status = "okay"; - num-cs = <7>; - is-decoded-cs = <1>; - speed-hz = <200000000>; +&i2c1 { + status = "okay"; +}; - spidev@0 { - compatible = "spidev"; - spi-max-frequency = <2000000>; - reg = <0>; - }; - spidev@1 { - compatible = "spidev"; - spi-max-frequency = <2000000>; - reg = <1>; - }; - spidev@2 { - compatible = "spidev"; - spi-max-frequency = <2000000>; - reg = <2>; - }; - spidev@3 { - compatible = "spidev"; - spi-max-frequency = <2000000>; - reg = <3>; - }; - }; +&i2c2 { + status = "okay"; +}; - spi1: spi@e0007000 { - status = "okay"; - num-cs = <3>; - is-decoded-cs = <0>; - speed-hz = <200000000>; +&spi0 { + status = "okay"; + num-cs = <7>; + is-decoded-cs = <1>; + speed-hz = <200000000>; + + spidev@0 { + compatible = "spidev"; + spi-max-frequency = <2000000>; + reg = <0>; + }; + spidev@1 { + compatible = "spidev"; + spi-max-frequency = <2000000>; + reg = <1>; + }; + spidev@2 { + compatible = "spidev"; + spi-max-frequency = <2000000>; + reg = <2>; + }; + spidev@3 { + compatible = "spidev"; + spi-max-frequency = <2000000>; + reg = <3>; + }; +}; - spidev@0 { - compatible = "spidev"; - spi-max-frequency = <2000000>; - reg = <0>; - }; - }; +&spi1 { + status = "okay"; + num-cs = <3>; + is-decoded-cs = <0>; + speed-hz = <200000000>; + + spidev@0 { + compatible = "spidev"; + spi-max-frequency = <2000000>; + reg = <0>; }; }; @@ -146,7 +144,7 @@ status = "okay"; phy-handle = <&phy0>; phy-mode = "rgmii-id"; - emio-speed-gpios = <&gpio 54 0>, + emio-speed-gpios = <&gpio0 54 0>, <0>; #address-cells = <0x1>; #size-cells = <0x0>; diff --git a/arch/arm/boot/dts/xilinx/ni-775E.dts b/arch/arm/boot/dts/xilinx/ni-775E.dts index ed3f9c6e53953..b5dc0d2db518f 100644 --- a/arch/arm/boot/dts/xilinx/ni-775E.dts +++ b/arch/arm/boot/dts/xilinx/ni-775E.dts @@ -4,13 +4,13 @@ / { model = "NI sbRIO-9651"; compatible = "ni,zynq", "xlnx,zynq-7000"; +}; - amba@0 { - i2c0: i2c@e0004000 { +&i2c0 { nicpld@40 { watchdogs { boot-watchdog { - interrupt-parent = <&gpio>; + interrupt-parent = <&gpio0>; interrupts = <15 2 /* IRQ_TYPE_EDGE_FALLING */>; }; }; @@ -36,8 +36,6 @@ ds3231_rtc@68 { status = "okay"; }; - }; - }; }; &gem0 { @@ -54,7 +52,7 @@ #size-cells = <0x0>; emio-speed-gpios = <0>, - <&gpio 54 0>; + <&gpio0 54 0>; phy0: phy@0 { compatible = "micrel,KSZ9031","ethernet-phy-ieee802.3-c22"; @@ -62,7 +60,7 @@ reg = <0x0>; /* Interrupt on GPIO1. */ interrupts = <1 8 /* IRQ_TYPE_LEVEL_LOW */>; - interrupt-parent = <&gpio>; + interrupt-parent = <&gpio0>; /* Set RX_CLK Pad Skew [4:0] to 0b00000. */ rxc-skew-ps = <0>; @@ -82,8 +80,8 @@ #address-cells = <0x1>; #size-cells = <0x0>; - emio-speed-gpios = <&gpio 56 0>, - <&gpio 55 0>; + emio-speed-gpios = <&gpio0 56 0>, + <&gpio0 55 0>; phy1: phy@1 { compatible = "micrel,KSZ9031","ethernet-phy-ieee802.3-c22"; @@ -91,7 +89,7 @@ reg = <0x1>; /* Interrupt on GPIO57. */ interrupts = <57 8 /* IRQ_TYPE_LEVEL_LOW */>; - interrupt-parent = <&gpio>; + interrupt-parent = <&gpio0>; }; }; diff --git a/arch/arm/boot/dts/xilinx/ni-77D4.dts b/arch/arm/boot/dts/xilinx/ni-77D4.dts index 571e48d34449f..4c9e32788fa29 100644 --- a/arch/arm/boot/dts/xilinx/ni-77D4.dts +++ b/arch/arm/boot/dts/xilinx/ni-77D4.dts @@ -4,13 +4,13 @@ / { model = "NI sbRIO-9637"; compatible = "ni,zynq", "xlnx,zynq-7000"; +}; - amba@0 { - i2c0: i2c@e0004000 { +&i2c0 { nicpld@40 { watchdogs { boot-watchdog { - interrupt-parent = <&gpio>; + interrupt-parent = <&gpio0>; interrupts = <1 2 /* IRQ_TYPE_EDGE_FALLING */>; }; }; @@ -39,8 +39,6 @@ ds3231_rtc@68 { status = "okay"; }; - }; - }; }; &gem0 { @@ -50,7 +48,7 @@ phy-handle = <&phy0>; phy-mode = "rgmii-id"; emio-speed-gpios = <0>, - <&gpio 54 0>; + <&gpio0 54 0>; #address-cells = <0x1>; #size-cells = <0x0>; @@ -61,7 +59,7 @@ reg = <0x0>; /* Interrupt on GPIO25. */ interrupts = <25 8 /* IRQ_TYPE_LEVEL_LOW */>; - interrupt-parent = <&gpio>; + interrupt-parent = <&gpio0>; /* RX_DV Pad Skew [7:4] = +0.30ns (0xC0) */ /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 diff --git a/arch/arm/boot/dts/xilinx/ni-77D5.dts b/arch/arm/boot/dts/xilinx/ni-77D5.dts index 0e983d48037b8..9ac70682c992a 100644 --- a/arch/arm/boot/dts/xilinx/ni-77D5.dts +++ b/arch/arm/boot/dts/xilinx/ni-77D5.dts @@ -4,13 +4,13 @@ / { model = "NI sbRIO-9627"; compatible = "ni,zynq", "xlnx,zynq-7000"; +}; - amba@0 { - i2c0: i2c@e0004000 { +&i2c0 { nicpld@40 { watchdogs { boot-watchdog { - interrupt-parent = <&gpio>; + interrupt-parent = <&gpio0>; interrupts = <1 2 /* IRQ_TYPE_EDGE_FALLING */>; }; }; @@ -49,8 +49,6 @@ ds3231_rtc@68 { status = "okay"; }; - }; - }; }; &gem0 { @@ -60,7 +58,7 @@ phy-handle = <&phy0>; phy-mode = "rgmii-id"; emio-speed-gpios = <0>, - <&gpio 54 0>; + <&gpio0 54 0>; #address-cells = <0x1>; #size-cells = <0x0>; @@ -71,7 +69,7 @@ reg = <0x0>; /* Interrupt on GPIO25, shared with phy1. */ interrupts = <25 8 /* IRQ_TYPE_LEVEL_LOW */>; - interrupt-parent = <&gpio>; + interrupt-parent = <&gpio0>; /* RX_DV Pad Skew [7:4] = +0.30ns (0xC0) */ /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 @@ -122,7 +120,7 @@ reg = <0x1>; /* Interrupt on GPIO25, shared with phy0. */ interrupts = <25 8 /* IRQ_TYPE_LEVEL_LOW */>; - interrupt-parent = <&gpio>; + interrupt-parent = <&gpio0>; /* RX_DV Pad Skew [7:4] = +0.30ns (0xC0) */ /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 @@ -176,7 +174,7 @@ phy-mode = "rgmii-id"; cdns,no_mdio_bus; emio-speed-gpios = <0>, - <&gpio 55 0>; + <&gpio0 55 0>; }; &sdhci0 { diff --git a/arch/arm/boot/dts/xilinx/ni-77D6.dts b/arch/arm/boot/dts/xilinx/ni-77D6.dts index c344069dec3c0..1f9ba5e003eb5 100644 --- a/arch/arm/boot/dts/xilinx/ni-77D6.dts +++ b/arch/arm/boot/dts/xilinx/ni-77D6.dts @@ -4,13 +4,13 @@ / { model = "NI sbRIO-9607"; compatible = "ni,zynq", "xlnx,zynq-7000"; +}; - amba@0 { - i2c0: i2c@e0004000 { +&i2c0 { nicpld@40 { watchdogs { boot-watchdog { - interrupt-parent = <&gpio>; + interrupt-parent = <&gpio0>; interrupts = <1 2 /* IRQ_TYPE_EDGE_FALLING */>; }; }; @@ -49,8 +49,6 @@ ds3231_rtc@68 { status = "okay"; }; - }; - }; }; &gem0 { @@ -60,7 +58,7 @@ phy-handle = <&phy0>; phy-mode = "rgmii-id"; emio-speed-gpios = <0>, - <&gpio 54 0>; + <&gpio0 54 0>; #address-cells = <0x1>; #size-cells = <0x0>; @@ -71,7 +69,7 @@ reg = <0x0>; /* Interrupt on GPIO25, shared with phy1. */ interrupts = <25 8 /* IRQ_TYPE_LEVEL_LOW */>; - interrupt-parent = <&gpio>; + interrupt-parent = <&gpio0>; /* RX_DV Pad Skew [7:4] = +0.30ns (0xC0) */ /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 @@ -122,7 +120,7 @@ reg = <0x1>; /* Interrupt on GPIO25, shared with phy0. */ interrupts = <25 8 /* IRQ_TYPE_LEVEL_LOW */>; - interrupt-parent = <&gpio>; + interrupt-parent = <&gpio0>; /* RX_DV Pad Skew [7:4] = +0.30ns (0xC0) */ /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 @@ -176,7 +174,7 @@ phy-mode = "rgmii-id"; cdns,no_mdio_bus; emio-speed-gpios = <0>, - <&gpio 55 0>; + <&gpio0 55 0>; }; &sdhci1 { diff --git a/arch/arm/boot/dts/xilinx/ni-7885.dts b/arch/arm/boot/dts/xilinx/ni-7885.dts index 661dc24a23baf..5a5450c9c2513 100644 --- a/arch/arm/boot/dts/xilinx/ni-7885.dts +++ b/arch/arm/boot/dts/xilinx/ni-7885.dts @@ -4,13 +4,13 @@ / { model = "NI ELVIS RIO CM"; compatible = "ni,zynq", "xlnx,zynq-7000"; +}; - amba@0 { - i2c0: i2c@e0004000 { +&i2c0 { nicpld@40 { watchdogs { boot-watchdog { - interrupt-parent = <&gpio>; + interrupt-parent = <&gpio0>; interrupts = <24 2 /* IRQ_TYPE_EDGE_FALLING */>; }; }; @@ -22,8 +22,6 @@ }; }; }; - }; - }; }; &ni_uart0 { diff --git a/arch/arm/boot/dts/xilinx/ni-793C.dts b/arch/arm/boot/dts/xilinx/ni-793C.dts index a2255627d113d..cf6e8d3671622 100644 --- a/arch/arm/boot/dts/xilinx/ni-793C.dts +++ b/arch/arm/boot/dts/xilinx/ni-793C.dts @@ -4,13 +4,13 @@ / { model = "NI ELVIS III"; compatible = "ni,zynq", "xlnx,zynq-7000"; +}; - amba@0 { - i2c0: i2c@e0004000 { +&i2c0 { nicpld@40 { watchdogs { boot-watchdog { - interrupt-parent = <&gpio>; + interrupt-parent = <&gpio0>; interrupts = <1 2 /* IRQ_TYPE_EDGE_FALLING */>; }; }; @@ -47,8 +47,6 @@ compatible = "truly,oel9m1027"; }; }; - }; - }; }; &gem0 { @@ -58,7 +56,7 @@ phy-handle = <&phy0>; phy-mode = "rgmii-id"; emio-speed-gpios = <0>, - <&gpio 54 0>; + <&gpio0 54 0>; #address-cells = <0x1>; #size-cells = <0x0>; @@ -69,7 +67,7 @@ reg = <0x0>; /* Interrupt on GPIO25, shared with phy1. */ interrupts = <25 8 /* IRQ_TYPE_LEVEL_LOW */>; - interrupt-parent = <&gpio>; + interrupt-parent = <&gpio0>; /* RX_DV Pad Skew [7:4] = +0.30ns (0xC0) */ /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 @@ -131,7 +129,7 @@ status = "okay"; transceiver = "RS-232"; emio-con-dio-multiplex-gpios = <0>, - <&gpio 56 0>; + <&gpio0 56 0>; }; &ni_uart1 { diff --git a/arch/arm/boot/dts/xilinx/ni-793x.dtsi b/arch/arm/boot/dts/xilinx/ni-793x.dtsi index 2317bdb927553..e293300c0a5b7 100644 --- a/arch/arm/boot/dts/xilinx/ni-793x.dtsi +++ b/arch/arm/boot/dts/xilinx/ni-793x.dtsi @@ -2,22 +2,23 @@ / { compatible = "ni,zynq", "xlnx,zynq-7000"; +}; - amba@0 { - - leds-ni793x@4020F000 { - compatible = "ni,led-793x"; - reg = <0x4020F000 4>; - user1 { - label = "nilrt:user1:green"; - }; +&amba { + leds-ni793x@4020F000 { + compatible = "ni,led-793x"; + reg = <0x4020F000 4>; + user1 { + label = "nilrt:user1:green"; }; + }; +}; - i2c0: i2c@e0004000 { +&i2c0 { nicpld@40 { watchdogs { boot-watchdog { - interrupt-parent = <&gpio>; + interrupt-parent = <&gpio0>; interrupts = <15 2 /* IRQ_TYPE_EDGE_FALLING */>; }; }; @@ -43,8 +44,6 @@ ds3231_rtc@68 { status = "okay"; }; - }; - }; }; &gem0 { @@ -61,7 +60,7 @@ #size-cells = <0x0>; emio-speed-gpios = <0>, - <&gpio 54 0>; + <&gpio0 54 0>; phy0: phy@0 { compatible = "micrel,KSZ9031","ethernet-phy-ieee802.3-c22"; @@ -69,7 +68,7 @@ reg = <0x0>; /* Interrupt on GPIO1. */ interrupts = <1 8 /* IRQ_TYPE_LEVEL_LOW */>; - interrupt-parent = <&gpio>; + interrupt-parent = <&gpio0>; /* Set RX_CLK Pad Skew [4:0] to 0b00000. */ rxc-skew-ps = <0>; diff --git a/arch/arm/boot/dts/xilinx/ni-7AAE.dts b/arch/arm/boot/dts/xilinx/ni-7AAE.dts index b01fb7f7b45c2..16c9ef28b38eb 100644 --- a/arch/arm/boot/dts/xilinx/ni-7AAE.dts +++ b/arch/arm/boot/dts/xilinx/ni-7AAE.dts @@ -15,18 +15,18 @@ wlan1 { /* green */ label = "nilrt:wifi:primary"; - gpios = <&gpio 55 0>; + gpios = <&gpio0 55 0>; }; wlan2 { /* red */ label = "nilrt:wifi:secondary"; - gpios = <&gpio 56 0>; + gpios = <&gpio0 56 0>; }; }; +}; - amba@0 { - adc: adc@f8007100 { +&adc { xlnx,channels { #address-cells = <1>; #size-cells = <0>; @@ -71,19 +71,19 @@ reg = <12>; }; }; - }; +}; - smcc@e000e000 { - nand@e1000000 { - status = "disabled"; - }; - }; +&smcc { + nand@e1000000 { + status = "disabled"; + }; +}; - i2c0: i2c@e0004000 { +&i2c0 { nicpld@40 { watchdogs { boot-watchdog { - interrupt-parent = <&gpio>; + interrupt-parent = <&gpio0>; interrupts = <24 2 /* IRQ_TYPE_EDGE_FALLING */>; }; }; @@ -95,56 +95,54 @@ }; }; }; - }; - - i2c1: i2c@e0005000 { - status = "okay"; - }; - - i2c2: i2c@81000000 { - status = "okay"; - }; +}; - spi0: spi@e0006000 { - status = "okay"; - num-cs = <7>; - is-decoded-cs = <1>; - speed-hz = <200000000>; +&i2c1 { + status = "okay"; +}; - spidev@0 { - compatible = "spidev"; - spi-max-frequency = <2000000>; - reg = <0>; - }; - spidev@1 { - compatible = "spidev"; - spi-max-frequency = <2000000>; - reg = <1>; - }; - spidev@2 { - compatible = "spidev"; - spi-max-frequency = <2000000>; - reg = <2>; - }; - spidev@3 { - compatible = "spidev"; - spi-max-frequency = <2000000>; - reg = <3>; - }; - }; +&i2c2 { + status = "okay"; +}; - spi1: spi@e0007000 { - status = "okay"; - num-cs = <3>; - is-decoded-cs = <0>; - speed-hz = <200000000>; +&spi0 { + status = "okay"; + num-cs = <7>; + is-decoded-cs = <1>; + speed-hz = <200000000>; + + spidev@0 { + compatible = "spidev"; + spi-max-frequency = <2000000>; + reg = <0>; + }; + spidev@1 { + compatible = "spidev"; + spi-max-frequency = <2000000>; + reg = <1>; + }; + spidev@2 { + compatible = "spidev"; + spi-max-frequency = <2000000>; + reg = <2>; + }; + spidev@3 { + compatible = "spidev"; + spi-max-frequency = <2000000>; + reg = <3>; + }; +}; - spidev@0 { - compatible = "spidev"; - spi-max-frequency = <2000000>; - reg = <0>; - }; - }; +&spi1 { + status = "okay"; + num-cs = <3>; + is-decoded-cs = <0>; + speed-hz = <200000000>; + + spidev@0 { + compatible = "spidev"; + spi-max-frequency = <2000000>; + reg = <0>; }; }; @@ -152,7 +150,7 @@ status = "okay"; phy-handle = <&phy0>; phy-mode = "rgmii-id"; - emio-speed-gpios = <&gpio 54 0>, + emio-speed-gpios = <&gpio0 54 0>, <0>; #address-cells = <0x1>; #size-cells = <0x0>; diff --git a/arch/arm/boot/dts/xilinx/ni-myrio.dtsi b/arch/arm/boot/dts/xilinx/ni-myrio.dtsi index 18ec8c1394c50..5194a062545f1 100644 --- a/arch/arm/boot/dts/xilinx/ni-myrio.dtsi +++ b/arch/arm/boot/dts/xilinx/ni-myrio.dtsi @@ -2,20 +2,20 @@ / { compatible = "ni,zynq", "xlnx,zynq-7000"; +}; - amba@0 { - i2c0: i2c@e0004000 { +&i2c0 { nicpld@40 { watchdogs { boot-watchdog { - interrupt-parent = <&gpio>; + interrupt-parent = <&gpio0>; interrupts = <24 2 /* IRQ_TYPE_EDGE_FALLING */>; }; }; switches { wifi-switch { - interrupt-parent = <&gpio>; + interrupt-parent = <&gpio0>; interrupts = <25 2 /* IRQ_TYPE_EDGE_FALLING */>; }; }; @@ -33,8 +33,6 @@ }; }; }; - }; - }; }; &sdhci0 { @@ -55,7 +53,7 @@ wl12xx: wl12xx@0 { compatible = "ti,wl1271"; reg = <2>; - interrupt-parent = <&gpio>; + interrupt-parent = <&gpio0>; interrupts = <15 0x4>; ref-clock-frequency = <38400000>; }; diff --git a/arch/arm/boot/dts/xilinx/ni-solbetter.dtsi b/arch/arm/boot/dts/xilinx/ni-solbetter.dtsi index 2e6bb345da74b..a1801ff93774c 100644 --- a/arch/arm/boot/dts/xilinx/ni-solbetter.dtsi +++ b/arch/arm/boot/dts/xilinx/ni-solbetter.dtsi @@ -2,13 +2,13 @@ / { compatible = "ni,zynq", "xlnx,zynq-7000"; +}; - amba@0 { - i2c0: i2c@e0004000 { +&i2c0 { nicpld@40 { watchdogs { boot-watchdog { - interrupt-parent = <&gpio>; + interrupt-parent = <&gpio0>; interrupts = <25 2 /* IRQ_TYPE_EDGE_FALLING */>; }; }; @@ -47,8 +47,6 @@ ds3231_rtc@68 { status = "okay"; }; - }; - }; }; &gem0 { @@ -59,7 +57,7 @@ phy-mode = "rgmii-id"; emio-speed-gpios = <0>, - <&gpio 54 0>; + <&gpio0 54 0>; #address-cells = <0x1>; #size-cells = <0x0>; @@ -70,7 +68,7 @@ reg = <0x0>; /* Interrupt on GPIO1. */ interrupts = <1 8 /* IRQ_TYPE_LEVEL_LOW */>; - interrupt-parent = <&gpio>; + interrupt-parent = <&gpio0>; /* RX_DV Pad Skew [7:4] = +0.30ns (0xC0) */ /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 @@ -121,7 +119,7 @@ reg = <0x1>; /* Interrupt on GPIO1, shared with phy0. */ interrupts = <1 8 /* IRQ_TYPE_LEVEL_LOW */>; - interrupt-parent = <&gpio>; + interrupt-parent = <&gpio0>; /* RX_DV Pad Skew [7:4] = +0.30ns (0xC0) */ /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 @@ -175,7 +173,7 @@ phy-mode = "rgmii-id"; cdns,no_mdio_bus; emio-speed-gpios = <0>, - <&gpio 55 0>; + <&gpio0 55 0>; }; &ni_uart0 { diff --git a/arch/arm/boot/dts/xilinx/ni-solenetexp.dtsi b/arch/arm/boot/dts/xilinx/ni-solenetexp.dtsi index c81f7abb05376..b027ea61c9db6 100644 --- a/arch/arm/boot/dts/xilinx/ni-solenetexp.dtsi +++ b/arch/arm/boot/dts/xilinx/ni-solenetexp.dtsi @@ -2,13 +2,13 @@ / { compatible = "ni,zynq", "xlnx,zynq-7000"; +}; - amba@0 { - i2c0: i2c@e0004000 { +&i2c0 { nicpld@40 { watchdogs { boot-watchdog { - interrupt-parent = <&gpio>; + interrupt-parent = <&gpio0>; interrupts = <25 2 /* IRQ_TYPE_EDGE_FALLING */>; }; }; @@ -34,8 +34,6 @@ ds3231_rtc@68 { status = "okay"; }; - }; - }; }; &gem0 { @@ -45,7 +43,7 @@ phy-handle = <&phy0>; phy-mode = "rgmii-id"; emio-speed-gpios = <0>, - <&gpio 54 0>; + <&gpio0 54 0>; #address-cells = <0x1>; #size-cells = <0x0>; @@ -56,7 +54,7 @@ reg = <0x0>; /* Interrupt on GPIO1. */ interrupts = <1 8 /* IRQ_TYPE_LEVEL_LOW */>; - interrupt-parent = <&gpio>; + interrupt-parent = <&gpio0>; /* RX_DV Pad Skew [7:4] = +0.30ns (0xC0) */ /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 diff --git a/arch/arm/boot/dts/xilinx/ni-solgood.dtsi b/arch/arm/boot/dts/xilinx/ni-solgood.dtsi index d65b51a80aac4..c826eb54b8840 100644 --- a/arch/arm/boot/dts/xilinx/ni-solgood.dtsi +++ b/arch/arm/boot/dts/xilinx/ni-solgood.dtsi @@ -2,13 +2,13 @@ / { compatible = "ni,zynq", "xlnx,zynq-7000"; +}; - amba@0 { - i2c0: i2c@e0004000 { +&i2c0 { nicpld@40 { watchdogs { boot-watchdog { - interrupt-parent = <&gpio>; + interrupt-parent = <&gpio0>; interrupts = <25 2 /* IRQ_TYPE_EDGE_FALLING */>; }; }; @@ -37,8 +37,6 @@ ds3231_rtc@68 { status = "okay"; }; - }; - }; }; &gem0 { @@ -48,7 +46,7 @@ phy-handle = <&phy0>; phy-mode = "rgmii-id"; emio-speed-gpios = <0>, - <&gpio 54 0>; + <&gpio0 54 0>; #address-cells = <0x1>; #size-cells = <0x0>; @@ -59,7 +57,7 @@ reg = <0x0>; /* Interrupt on GPIO1. */ interrupts = <1 8 /* IRQ_TYPE_LEVEL_LOW */>; - interrupt-parent = <&gpio>; + interrupt-parent = <&gpio0>; /* RX_DV Pad Skew [7:4] = +0.30ns (0xC0) */ /* Default is 0b0111, or 7. 7 * 60 ps = 420 ps. 0.30 ns is 300 From 9de7d266227cca935c8a4bd12f36d8f5e860a851 Mon Sep 17 00:00:00 2001 From: Chaitanya Vadrevu Date: Fri, 17 Jul 2026 19:12:34 -0500 Subject: [PATCH 71/83] dts: ni: Define NAND child address format Set the address and size cells on the NAND controller so the nand@0 reg property is parsed correctly. Signed-off-by: Chaitanya Vadrevu --- arch/arm/boot/dts/xilinx/ni-zynq.dtsi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/boot/dts/xilinx/ni-zynq.dtsi b/arch/arm/boot/dts/xilinx/ni-zynq.dtsi index d694aedc9c5d6..0f31351765ad8 100644 --- a/arch/arm/boot/dts/xilinx/ni-zynq.dtsi +++ b/arch/arm/boot/dts/xilinx/ni-zynq.dtsi @@ -156,6 +156,8 @@ &nfc0 { status = "okay"; + #address-cells = <1>; + #size-cells = <0>; nand@0 { reg = <0>; From 80c2a1e17a41945112325a3d7214be74696cce79 Mon Sep 17 00:00:00 2001 From: Chaitanya Vadrevu Date: Tue, 21 Jul 2026 15:22:03 -0500 Subject: [PATCH 72/83] dts: ni: Disable inaccessible CoreSight devices The CoreSight blocks are not accessible on NI Zynq targets. Reading their AMBA identification registers hangs the SoC before any driver binds. Disable the nodes to allow the system to boot. Signed-off-by: Chaitanya Vadrevu --- arch/arm/boot/dts/xilinx/ni-zynq.dtsi | 31 +++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/arch/arm/boot/dts/xilinx/ni-zynq.dtsi b/arch/arm/boot/dts/xilinx/ni-zynq.dtsi index 0f31351765ad8..f8a4850c093e1 100644 --- a/arch/arm/boot/dts/xilinx/ni-zynq.dtsi +++ b/arch/arm/boot/dts/xilinx/ni-zynq.dtsi @@ -172,3 +172,34 @@ arm,dynamic-clock-gating = <0>; arm,standby-mode = <0>; }; + +/* + * The CoreSight debug/trace macrocells are not accessible on NI Zynq-based + * targets: reading their AMBA peripheral-ID registers (done unconditionally + * by the kernel as soon as the device is created, before any driver binds) + * hangs the SoC indefinitely. Disable them so of_platform_populate() never + * touches them. + */ +&{/replicator} { + status = "disabled"; +}; + +&{/axi/etb@f8801000} { + status = "disabled"; +}; + +&{/axi/tpiu@f8803000} { + status = "disabled"; +}; + +&{/axi/funnel@f8804000} { + status = "disabled"; +}; + +&{/axi/ptm@f889c000} { + status = "disabled"; +}; + +&{/axi/ptm@f889d000} { + status = "disabled"; +}; From e6df6df82c11ae539fd592cb5b68a679df730506 Mon Sep 17 00:00:00 2001 From: Chaitanya Vadrevu Date: Fri, 17 Jul 2026 19:39:34 -0500 Subject: [PATCH 73/83] net: macb: Replace removed PHY interrupt helpers phy_start_interrupts, phy_stop_interrupts have been removed in newer kernel. Replace them with phy_request_interrupt, phy_free_interrupt. Signed-off-by: Chaitanya Vadrevu --- drivers/net/ethernet/cadence/macb_main.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c index 475defef6ecf0..5824f9bbbcf8c 100644 --- a/drivers/net/ethernet/cadence/macb_main.c +++ b/drivers/net/ethernet/cadence/macb_main.c @@ -4478,7 +4478,8 @@ static int macb_fpga_notifier(struct notifier_block *nb, unsigned long val, void if (netif_running(bp->dev)) { dev_deactivate(bp->dev); macb_close(bp->dev); - phy_stop_interrupts(dev->phydev); + if (phy_interrupt_is_valid(dev->phydev)) + phy_free_interrupt(dev->phydev); phy_stop_machine_nolink(dev->phydev); } @@ -4501,7 +4502,8 @@ static int macb_fpga_notifier(struct notifier_block *nb, unsigned long val, void /* If the interface has been opened. */ if (netif_running(bp->dev)) { phy_start_machine(dev->phydev); - phy_start_interrupts(dev->phydev); + if (phy_interrupt_is_valid(dev->phydev)) + phy_request_interrupt(dev->phydev); macb_open(bp->dev); dev_activate(bp->dev); } From 9cb2e8d92726bdbd70a0c5e46433fa3607f59ec8 Mon Sep 17 00:00:00 2001 From: Chaitanya Vadrevu Date: Tue, 21 Jul 2026 14:40:51 -0500 Subject: [PATCH 74/83] misc: nizynqcpld: Update I2C driver callbacks Drop the unused device ID argument from probe and change remove to return void, matching the current I2C driver callback signatures. Signed-off-by: Chaitanya Vadrevu --- drivers/misc/nizynqcpld.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/misc/nizynqcpld.c b/drivers/misc/nizynqcpld.c index 5db065365893e..ce990ac4a6c76 100644 --- a/drivers/misc/nizynqcpld.c +++ b/drivers/misc/nizynqcpld.c @@ -1559,8 +1559,7 @@ static void myrio_wifi_sw_uninit(struct nizynqcpld *cpld) } } -static int nizynqcpld_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int nizynqcpld_probe(struct i2c_client *client) { struct nizynqcpld_desc *desc; struct nizynqcpld *cpld; @@ -1713,7 +1712,7 @@ static int nizynqcpld_probe(struct i2c_client *client, return err; } -static int nizynqcpld_remove(struct i2c_client *client) +static void nizynqcpld_remove(struct i2c_client *client) { struct nizynqcpld *cpld = i2c_get_clientdata(client); struct nizynqcpld_desc *desc = cpld->desc; @@ -1732,7 +1731,6 @@ static int nizynqcpld_remove(struct i2c_client *client) myrio_wifi_sw_uninit(cpld); kfree(cpld); - return 0; } static const struct of_device_id nizynqcpld_dt_ids[] = { From e40d2b6bdecb658acf49d33e563e65483e3339da Mon Sep 17 00:00:00 2001 From: Chaitanya Vadrevu Date: Tue, 21 Jul 2026 15:34:48 -0500 Subject: [PATCH 75/83] serial: 8250_ni: Map MMIO registers before probe-time access UPF_IOREMAP defers mapping the register resource until the serial port is started. The NI 16550 driver accesses registers during probe to determine FIFO sizes and configure the PMR, before the port has been started. Map the MMIO resource with devm_ioremap() during probe and assign the result to port->membase so these early register accesses use a valid mapping. Signed-off-by: Chaitanya Vadrevu --- drivers/tty/serial/8250/8250_ni.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/8250/8250_ni.c b/drivers/tty/serial/8250/8250_ni.c index b77dbcbdef303..e9975dfb93d3c 100644 --- a/drivers/tty/serial/8250/8250_ni.c +++ b/drivers/tty/serial/8250/8250_ni.c @@ -243,7 +243,19 @@ static int ni16550_get_regs(struct platform_device *pdev, port->iotype = UPIO_MEM; port->mapbase = regs->start; port->mapsize = resource_size(regs); - port->flags |= UPF_IOREMAP; + + /* + * Map the registers here (rather than relying on the generic + * UPF_IOREMAP deferred-mapping mechanism, which only ioremaps + * when the port is started) because this driver reads + * hardware registers (FIFO sizes, PMR, etc.) directly during + * probe(), before the port is ever started. + */ + port->membase = devm_ioremap(&pdev->dev, regs->start, + resource_size(regs)); + if (!port->membase) + return dev_err_probe(&pdev->dev, -ENOMEM, + "cannot map registers\n"); return 0; default: From 438fd8c1ee48a931aa4c355022a0bdb692f4c186 Mon Sep 17 00:00:00 2001 From: Chaitanya Vadrevu Date: Mon, 27 Jul 2026 18:33:29 -0500 Subject: [PATCH 76/83] nati_zynq_defconfig: Refresh for Linux 6.18 Port remaining defconfig changes from 4.14 kernel. Refresh it against Linux 6.18 while retaining the features required by NI Zynq targets. Enable PREEMPT_RT, RCU callback offloading, NI platform drivers, and the networking, USB, storage, filesystem options, etc. Regenerate the defconfig to account for current symbols and dependencies. Signed-off-by: Chaitanya Vadrevu --- arch/arm/configs/nati_zynq_defconfig | 122 ++++++++++++++++++++------- 1 file changed, 91 insertions(+), 31 deletions(-) diff --git a/arch/arm/configs/nati_zynq_defconfig b/arch/arm/configs/nati_zynq_defconfig index 9f1004d03889a..3069b2a86e77b 100644 --- a/arch/arm/configs/nati_zynq_defconfig +++ b/arch/arm/configs/nati_zynq_defconfig @@ -1,7 +1,14 @@ CONFIG_LOCALVERSION="-ni" CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y CONFIG_AUDIT=y CONFIG_HIGH_RES_TIMERS=y +CONFIG_BPF_JIT=y +CONFIG_PREEMPT_RT=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +CONFIG_RCU_EXPERT=y +CONFIG_RCU_NOCB_CPU=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 @@ -10,8 +17,9 @@ CONFIG_CPUSETS=y CONFIG_CGROUP_CPUACCT=y CONFIG_BLK_DEV_INITRD=y CONFIG_CC_OPTIMIZE_FOR_SIZE=y -CONFIG_SYSFS_SYSCALL=y +CONFIG_EXPERT=y CONFIG_PERF_EVENTS=y +CONFIG_ARCH_VEXPRESS=y CONFIG_ARCH_ZYNQ=y CONFIG_ARM_ERRATA_754322=y CONFIG_ARM_ERRATA_764369=y @@ -24,14 +32,14 @@ CONFIG_NEON=y # CONFIG_SUSPEND is not set CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y -CONFIG_MODULE_FORCE_UNLOAD=y CONFIG_MODVERSIONS=y -# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +# CONFIG_COMPAT_BRK is not set # CONFIG_COMPACTION is not set -CONFIG_CMA=y CONFIG_NET=y CONFIG_PACKET=y CONFIG_UNIX=y +CONFIG_XFRM_USER=m +CONFIG_NET_KEY=m CONFIG_INET=y CONFIG_IP_MULTICAST=y CONFIG_IP_ADVANCED_ROUTER=y @@ -53,9 +61,11 @@ CONFIG_IP_PIMSM_V2=y CONFIG_INET_AH=m CONFIG_INET_ESP=m CONFIG_INET_IPCOMP=m +CONFIG_IPV6=m CONFIG_INET6_AH=m CONFIG_INET6_ESP=m CONFIG_INET6_IPCOMP=m +CONFIG_IPV6_MULTIPLE_TABLES=y CONFIG_NETFILTER=y CONFIG_NF_CONNTRACK=m CONFIG_NF_CONNTRACK_EVENTS=y @@ -74,6 +84,8 @@ CONFIG_NF_CT_NETLINK=m CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m CONFIG_NETFILTER_XT_TARGET_CONNMARK=m CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m +CONFIG_NETFILTER_XT_TARGET_LED=m +CONFIG_NETFILTER_XT_TARGET_LOG=m CONFIG_NETFILTER_XT_TARGET_MARK=m CONFIG_NETFILTER_XT_TARGET_NFLOG=m CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m @@ -107,19 +119,16 @@ CONFIG_NETFILTER_XT_MATCH_QUOTA=m CONFIG_NETFILTER_XT_MATCH_RATEEST=m CONFIG_NETFILTER_XT_MATCH_REALM=m CONFIG_NETFILTER_XT_MATCH_RECENT=m -CONFIG_NETFILTER_XT_MATCH_SCTP=m CONFIG_NETFILTER_XT_MATCH_STATE=m CONFIG_NETFILTER_XT_MATCH_STATISTIC=m CONFIG_NETFILTER_XT_MATCH_STRING=m CONFIG_NETFILTER_XT_MATCH_TCPMSS=m CONFIG_NETFILTER_XT_MATCH_TIME=m CONFIG_NETFILTER_XT_MATCH_U32=m -CONFIG_NF_REJECT_IPV4=m CONFIG_IP_NF_IPTABLES=m CONFIG_IP_NF_MATCH_AH=m CONFIG_IP_NF_MATCH_ECN=m CONFIG_IP_NF_MATCH_TTL=m -CONFIG_NF_REJECT_IPV6=m CONFIG_IP6_NF_IPTABLES=m CONFIG_IP6_NF_MATCH_AH=m CONFIG_IP6_NF_MATCH_EUI64=m @@ -129,6 +138,8 @@ CONFIG_IP6_NF_MATCH_HL=m CONFIG_IP6_NF_MATCH_IPV6HEADER=m CONFIG_IP6_NF_MATCH_MH=m CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP_SCTP=m +CONFIG_SCTP_DEFAULT_COOKIE_HMAC_NONE=y CONFIG_L2TP=m CONFIG_L2TP_V3=y CONFIG_L2TP_IP=m @@ -136,6 +147,7 @@ CONFIG_L2TP_ETH=m CONFIG_BRIDGE=m CONFIG_VLAN_8021Q=m CONFIG_NET_SCHED=y +CONFIG_NET_SCH_NETEM=m CONFIG_CAN=y CONFIG_BT=m CONFIG_BT_HCIBTUSB=m @@ -149,6 +161,7 @@ CONFIG_DEVTMPFS_MOUNT=y CONFIG_CONNECTOR=y CONFIG_MTD=y CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_RESERVE_END=524288 CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_AMDSTD=y @@ -161,15 +174,20 @@ CONFIG_MTD_UBI_GLUEBI=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=16384 +CONFIG_FPGA_PERIPHERAL=y +CONFIG_NIZYNQ_CPLD=y CONFIG_SRAM=y CONFIG_EEPROM_AT24=y CONFIG_EEPROM_AT25=y -CONFIG_EEPROM_93CX6=m CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_SG=y # CONFIG_BLK_DEV_BSG is not set +CONFIG_MD=y +CONFIG_BLK_DEV_DM=m +CONFIG_DM_CRYPT=m CONFIG_NETDEVICES=y +CONFIG_BONDING=m CONFIG_TUN=y CONFIG_MACB=y # CONFIG_NET_VENDOR_CIRRUS is not set @@ -182,10 +200,11 @@ CONFIG_MACB=y # CONFIG_NET_VENDOR_QUALCOMM is not set # CONFIG_NET_VENDOR_SAMSUNG is not set # CONFIG_NET_VENDOR_SEEQ is not set -# CONFIG_NET_VENDOR_SMSC is not set +CONFIG_SMSC911X=m # CONFIG_NET_VENDOR_STMICRO is not set # CONFIG_NET_VENDOR_WIZNET is not set # CONFIG_NET_VENDOR_XILINX is not set +CONFIG_LED_TRIGGER_PHY=y CONFIG_MARVELL_PHY=y CONFIG_MICREL_PHY=y CONFIG_SMSC_PHY=y @@ -197,6 +216,10 @@ CONFIG_PPP_DEFLATE=m CONFIG_PPP_ASYNC=m CONFIG_PPP_SYNC_TTY=m CONFIG_USB_NET_DRIVERS=m +CONFIG_USB_CATC=m +CONFIG_USB_KAWETH=m +CONFIG_USB_PEGASUS=m +CONFIG_USB_RTL8150=m CONFIG_USB_RTL8152=m CONFIG_USB_USBNET=m CONFIG_USB_NET_CDC_EEM=m @@ -205,7 +228,18 @@ CONFIG_USB_NET_SMSC95XX=m CONFIG_USB_NET_PLUSB=m CONFIG_USB_NET_RNDIS_HOST=m CONFIG_USB_IPHETH=m +CONFIG_USB_SIERRA_NET=m +CONFIG_USB_VL600=m +CONFIG_USB_NET_CH9200=m CONFIG_ATH9K=m +CONFIG_CARL9170=m +CONFIG_ATH6KL=m +CONFIG_ATH6KL_SDIO=m +CONFIG_ATH6KL_USB=m +CONFIG_ATH6KL_SILEX_FIRMWARE=y +CONFIG_AR5523=m +CONFIG_AT76C50X_USB=m +CONFIG_MT7601U=m CONFIG_RT2X00=m CONFIG_RT2500USB=m CONFIG_RT73USB=m @@ -213,81 +247,112 @@ CONFIG_RT2800USB=m CONFIG_RT2800USB_RT53XX=y CONFIG_RT2800USB_RT55XX=y CONFIG_RT2800USB_UNKNOWN=y +CONFIG_RTL8187=m CONFIG_RTL8192CU=m CONFIG_WL12XX=m CONFIG_WLCORE_SDIO=m +CONFIG_ZD1211RW=m CONFIG_INPUT_SPARSEKMAP=y CONFIG_INPUT_EVDEV=y +# CONFIG_LEGACY_PTYS is not set CONFIG_SERIAL_8250=y # CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_NR_UARTS=9 +CONFIG_SERIAL_8250_NI=y CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_SERIAL_AMBA_PL011=y +CONFIG_SERIAL_AMBA_PL011_CONSOLE=y CONFIG_SERIAL_XILINX_PS_UART=y CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y # CONFIG_HW_RANDOM is not set +CONFIG_I2C=y CONFIG_I2C_CHARDEV=y CONFIG_I2C_CADENCE=y CONFIG_I2C_XILINX=y CONFIG_SPI=y CONFIG_SPI_CADENCE=y CONFIG_SPI_SPIDEV=y -CONFIG_GPIOLIB=y +CONFIG_GPIO_SYSFS=y CONFIG_GPIO_ZYNQ=y CONFIG_MEDIA_SUPPORT=y -CONFIG_MEDIA_CAMERA_SUPPORT=y CONFIG_MEDIA_USB_SUPPORT=y CONFIG_USB_VIDEO_CLASS=m +CONFIG_AUXDISPLAY=y +CONFIG_SH1107=m +CONFIG_OEL9M1027=m CONFIG_FB=y -CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_HIDRAW=y CONFIG_HID_MICROSOFT=m CONFIG_USB_HID=m +CONFIG_USB_HIDDEV=y CONFIG_USB=y CONFIG_USB_DYNAMIC_MINORS=y CONFIG_USB_EHCI_HCD=y -CONFIG_USB_ACM=m CONFIG_USB_STORAGE=m -CONFIG_USB_CHIPIDEA=y +CONFIG_USB_CHIPIDEA=m CONFIG_USB_CHIPIDEA_UDC=y CONFIG_USB_CHIPIDEA_HOST=y -CONFIG_USB_SERIAL=m +CONFIG_USB_SERIAL=y +CONFIG_USB_SERIAL_CONSOLE=y +CONFIG_USB_SERIAL_CH341=m +CONFIG_USB_SERIAL_WHITEHEAT=m CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m CONFIG_USB_SERIAL_CP210X=m CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_MOS7720=m +CONFIG_USB_SERIAL_MOS7840=m CONFIG_USB_SERIAL_PL2303=m -CONFIG_NOP_USB_XCEIV=y +CONFIG_USB_SERIAL_QUALCOMM=m +CONFIG_USB_SERIAL_SIERRAWIRELESS=m +CONFIG_NOP_USB_XCEIV=m CONFIG_USB_ULPI=y -CONFIG_USB_GADGET=y -CONFIG_USB_ETH=y +CONFIG_USB_GADGET=m +CONFIG_USB_CONFIGFS=m +CONFIG_USB_CONFIGFS_EEM=y +CONFIG_USB_CONFIGFS_MASS_STORAGE=y +CONFIG_USB_ETH=m # CONFIG_USB_ETH_RNDIS is not set CONFIG_USB_ETH_EEM=y CONFIG_MMC=y +CONFIG_MMC_ARMMMCI=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_PLTFM=y CONFIG_MMC_SDHCI_OF_ARASAN=y +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y +CONFIG_LEDS_GPIO=y +CONFIG_LEDS_NI793X=y CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_PCF8563=y CONFIG_RTC_DRV_DS3232=y CONFIG_DMADEVICES=y CONFIG_PL330_DMA=y CONFIG_COMMON_CLK_SI570=y -CONFIG_ARM_GT_INITIAL_PRESCALER_VAL=2 CONFIG_MEMORY=y CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y CONFIG_EXT2_FS_SECURITY=y CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y # CONFIG_DNOTIFY is not set +CONFIG_FUSE_FS=m CONFIG_MSDOS_FS=y CONFIG_VFAT_FS=y +CONFIG_NTFS_FS=m CONFIG_TMPFS=y CONFIG_TMPFS_POSIX_ACL=y +CONFIG_CONFIGFS_FS=y CONFIG_UBIFS_FS=y CONFIG_SQUASHFS=m CONFIG_SQUASHFS_XATTR=y -CONFIG_NFS_FS=y -CONFIG_ROOT_NFS=y +CONFIG_NFS_FS=m +CONFIG_NFS_V4=m +CONFIG_NFS_V4_1=y CONFIG_CIFS=y +CONFIG_CIFS_XATTR=y +CONFIG_CIFS_POSIX=y CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ASCII=y CONFIG_NLS_ISO8859_1=y @@ -297,17 +362,12 @@ CONFIG_SECURITY_SELINUX=y CONFIG_SECURITY_SELINUX_BOOTPARAM=y # CONFIG_INTEGRITY is not set CONFIG_DEFAULT_SECURITY_DAC=y -CONFIG_CRYPTO_NULL=y -CONFIG_CRYPTO_HMAC=y -CONFIG_CRYPTO_MD5=y -CONFIG_CRYPTO_SHA256=y -CONFIG_CRYPTO_SHA512=y -CONFIG_CRYPTO_CRC32C=y -CONFIG_FONTS=y -CONFIG_FONT_8x8=y -CONFIG_FONT_8x16=y +CONFIG_CRYPTO_PCRYPT=m +CONFIG_CRYPTO_XTS=m +CONFIG_CRYPTO_USER_API_SKCIPHER=m CONFIG_PRINTK_TIME=y CONFIG_DYNAMIC_DEBUG=y -CONFIG_FRAME_WARN=1024 CONFIG_MAGIC_SYSRQ=y +CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x0 +CONFIG_PANIC_TIMEOUT=30 CONFIG_RCU_CPU_STALL_TIMEOUT=60 From 671e9b8dfd68e1aacd37c2137ed9cb4287fa1b66 Mon Sep 17 00:00:00 2001 From: Chaitanya Vadrevu Date: Tue, 21 Jul 2026 19:42:29 -0500 Subject: [PATCH 77/83] nati*defconfig: Enable CONFIG_RCU_NOCB_CPU_DEFAULT_ALL Port this change from commit [1] for nati_x86_64_defconfig. NILRT is currently booted with `rcu_nocbs=all` kernel parameter set. Enable CONFIG_RCU_NOCB_CPU_DEFAULT_ALL which will allow us to remove the boot option in the future. Note that it is still possible to override this option using rcu_nocbs or nohz_full boot parameters. [1]: 4d93b1f ("nati_x86_64_defconfig: enable CONFIG_RCU_NOCB_CPU_DEFAULT_ALL") Signed-off-by: Chaitanya Vadrevu --- arch/arm/configs/nati_bluefin_defconfig | 3 +++ arch/arm/configs/nati_slsc_defconfig | 3 +++ arch/arm/configs/nati_zynq_defconfig | 1 + 3 files changed, 7 insertions(+) diff --git a/arch/arm/configs/nati_bluefin_defconfig b/arch/arm/configs/nati_bluefin_defconfig index 5ab4320d36ebb..2c1b729536d27 100644 --- a/arch/arm/configs/nati_bluefin_defconfig +++ b/arch/arm/configs/nati_bluefin_defconfig @@ -2,6 +2,9 @@ CONFIG_LOCALVERSION="-ni" CONFIG_SYSVIPC=y CONFIG_AUDIT=y CONFIG_HIGH_RES_TIMERS=y +CONFIG_RCU_EXPERT=y +CONFIG_RCU_NOCB_CPU=y +CONFIG_RCU_NOCB_CPU_DEFAULT_ALL=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 diff --git a/arch/arm/configs/nati_slsc_defconfig b/arch/arm/configs/nati_slsc_defconfig index 34d474f347025..8e60aedd57b11 100644 --- a/arch/arm/configs/nati_slsc_defconfig +++ b/arch/arm/configs/nati_slsc_defconfig @@ -2,6 +2,9 @@ CONFIG_LOCALVERSION="-ni" CONFIG_SYSVIPC=y CONFIG_AUDIT=y CONFIG_HIGH_RES_TIMERS=y +CONFIG_RCU_EXPERT=y +CONFIG_RCU_NOCB_CPU=y +CONFIG_RCU_NOCB_CPU_DEFAULT_ALL=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 diff --git a/arch/arm/configs/nati_zynq_defconfig b/arch/arm/configs/nati_zynq_defconfig index 3069b2a86e77b..7b7d2fc83caa1 100644 --- a/arch/arm/configs/nati_zynq_defconfig +++ b/arch/arm/configs/nati_zynq_defconfig @@ -9,6 +9,7 @@ CONFIG_BSD_PROCESS_ACCT=y CONFIG_BSD_PROCESS_ACCT_V3=y CONFIG_RCU_EXPERT=y CONFIG_RCU_NOCB_CPU=y +CONFIG_RCU_NOCB_CPU_DEFAULT_ALL=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 From d055c7861b7e8d6d2323966474f5d568b69f99cf Mon Sep 17 00:00:00 2001 From: Chaitanya Vadrevu Date: Fri, 17 Jul 2026 20:31:49 -0500 Subject: [PATCH 78/83] ni-pkg: Add NI FIT image packaging target Ported from 4.14 and updated to work on 6.18 kernel. Signed-off-by: Chaitanya Vadrevu --- .gitignore | 5 ++ Makefile | 2 +- scripts/Makefile.package | 9 +++ scripts/package/buildnipkg | 148 +++++++++++++++++++++++++++++++++++++ 4 files changed, 163 insertions(+), 1 deletion(-) create mode 100644 scripts/package/buildnipkg diff --git a/.gitignore b/.gitignore index 86a1ba0d90353..64930994bd8ec 100644 --- a/.gitignore +++ b/.gitignore @@ -96,6 +96,11 @@ modules.order # /tar-install/ +# +# ni specific install directory +# +/ni-install/ + # # pacman files (make pacman-pkg) # diff --git a/Makefile b/Makefile index 7f5abef39fd38..36cc213411ffd 100644 --- a/Makefile +++ b/Makefile @@ -1592,7 +1592,7 @@ endif # CONFIG_MODULES CLEAN_FILES += vmlinux.symvers modules-only.symvers \ modules.builtin modules.builtin.modinfo modules.nsdeps \ modules.builtin.ranges vmlinux.o.map vmlinux.unstripped \ - compile_commands.json rust/test \ + compile_commands.json rust/test ni-install \ rust-project.json .vmlinux.objs .vmlinux.export.c \ .builtin-dtbs-list .builtin-dtbs.S diff --git a/scripts/Makefile.package b/scripts/Makefile.package index 74bcb9e7f7a45..332e15b8dc115 100644 --- a/scripts/Makefile.package +++ b/scripts/Makefile.package @@ -189,6 +189,14 @@ tar-pkg: linux-$(KERNELRELEASE)-$(ARCH).tar tar%-pkg: linux-$(KERNELRELEASE)-$(ARCH).tar.% FORCE @: +# ni-pkg - generate an NI Zynq FIT image for all device models +# --------------------------------------------------------------------------- + +PHONY += ni-pkg +ni-pkg: FORCE + +$(Q)$(MAKE) -f $(srctree)/Makefile Image modules dtbs + $(Q)$(CONFIG_SHELL) $(srctree)/scripts/package/buildnipkg + # perf-tar*-src-pkg - generate a source tarball with perf source # --------------------------------------------------------------------------- @@ -245,6 +253,7 @@ help: @echo ' tarbz2-pkg - Build the kernel as a bzip2 compressed tarball' @echo ' tarxz-pkg - Build the kernel as a xz compressed tarball' @echo ' tarzst-pkg - Build the kernel as a zstd compressed tarball' + @echo ' ni-pkg - Build the kernel and needed files for NI targets' @echo ' perf-tar-src-pkg - Build the perf source tarball with no compression' @echo ' perf-targz-src-pkg - Build the perf source tarball with gzip compression' @echo ' perf-tarbz2-src-pkg - Build the perf source tarball with bz2 compression' diff --git a/scripts/package/buildnipkg b/scripts/package/buildnipkg new file mode 100644 index 0000000000000..2999116012c80 --- /dev/null +++ b/scripts/package/buildnipkg @@ -0,0 +1,148 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0-only + +set -eu + +if [ "${ARCH:-}" != "arm" ]; then + echo "error: ni-pkg requires ARCH=arm" >&2 + exit 1 +fi + +mkimage="${MKIMAGE:-mkimage}" +if ! command -v "${mkimage}" >/dev/null 2>&1; then + echo "error: ${mkimage} is required to build the NI FIT image" >&2 + exit 1 +fi + +bootdir="${objtree}/ni-install/arm/boot" +kernel="${objtree}/arch/arm/boot/Image" +dtsdir="${objtree}/arch/arm/boot/dts/xilinx" + +rm -rf -- "${bootdir}" +mkdir -p -- "${bootdir}" + +cp -- "${kernel}" "${bootdir}/vmlinux" +gzip -f -9 "${bootdir}/vmlinux" + +cat > "${bootdir}/bootscript.txt" <<'EOF' + +if test ${DeviceCode} -eq 0x7AAE; then + setenv set_args 'setenv bootargs ${consoleparam} root=/dev/mmcblk0p3 rw ${usb_gadget_args} rcu_nocbs=all rootdelay=1 $othbootargs' +else + setenv set_args 'setenv bootargs ${consoleparam} $mtdparts ubi.mtd=boot-config ubi.mtd=root root=ubi1:rootfs rw rootfstype=ubifs kthreadd_pri=25 ksoftirqd_pri=8 irqthread_pri=15 ${usb_gadget_args} $othbootargs' +fi + +# cRIO-9068 doesn't have USB gadget, so skip it on that device +if test ${DeviceCode} != 0x76D6; then + usb_gadget_args="g_ether.idVendor=${USBVendorID} g_ether.idProduct=${USBProductID} g_ether.iProduct=\"${USBProduct} [${hostname}]\" g_ether.iSerialNumber=${serial#} g_ether.dev_addr=${usbgadgetethaddr} g_ether.bcdDevice=${USBDevice}" +fi + +if test -n \"$bootscriptenvrun\" ; then run bootscriptenvrun; fi + +silent_tmp=${silent} +setenv silent +echo "Booting LabVIEW RT (custom kernel)..." +setenv silent ${silent_tmp} + +run set_args +bootm ${loadaddr}#config_${DeviceCode} +EOF + +dtb_list="" +device_codes="" +for dtb_path in "${dtsdir}"/ni-*.dtb; do + [ -e "${dtb_path}" ] || continue + dtb_name=$(basename "${dtb_path}") + devcode=${dtb_name#ni-} + devcode=${devcode%.dtb} + cp -- "${dtb_path}" "${bootdir}/${dtb_name}" + dtb_list="${dtb_list} ${devcode}" + device_codes="${device_codes}0x${devcode} " +done + +if [ -z "${dtb_list}" ]; then + echo "error: no ni-*.dtb files found in ${dtsdir}" >&2 + exit 1 +fi + +timestamp=$(date +%F_%R) +cat > "${bootdir}/linux.its" <; + + images { + kernel@1 { + description = "Linux kernel"; + version = "populate-kernel-export-version"; + data = /incbin/("./vmlinux.gz"); + type = "kernel"; + arch = "arm"; + os = "linux"; + compression = "gzip"; + load = <0x00008000>; + entry = <0x00008000>; + hash@1 { + algo = "crc32"; + }; + }; +EOF + +for devcode in ${dtb_list}; do + cat >> "${bootdir}/linux.its" <> "${bootdir}/linux.its" <> "${bootdir}/linux.its" <> "${bootdir}/linux.its" < Date: Wed, 4 Nov 2015 15:54:13 -0600 Subject: [PATCH 79/83] net/phy: micrel: Add workaround for autoneg failure In addition to the issue in 'net/phy: micrel: Add workaround for bad autoneg', sometimes the micrel KSZ9031 can fail to negotiate at all. When this happens, the phy will show link partner advertisements but will not show the link coming up. To fix this, reset the PHY if it has been down with link partner advertisements for more than 20 seconds. Signed-off-by: Nathan Sullivan Signed-off-by: Brad Mouring Acked-by: Josh Cartwright Acked-by: Tony Liechty Natinst-ReviewBoard-ID: 118397 net/phy: micrel: Fix workaround for autoneg failure The KSZ9031 phy can fail silently during auto-negotiation. The existing workaround relied on the read_status function being called periodically, which only happened when the phy state machine polled. Now that the phy state machine relies only on interrupts the workaround is broken. Turning on KSZPHY_INTCS_LINK_PARTNER_ACK will cause read_status to be called during auto-negotiation. When read_status detects that auto-negotiation is on going a work queue is started to poll read_status until the link comes up or the timeout lapses. If the timeout lapses the phy is reset by calling init_hw and then config_intr. Fixes: 223f45286b9e ("net/phy: micrel: Add workaround for autoneg failure") Signed-off-by: Zach Brown Signed-off-by: Brad Mouring Acked-by: Kyle Roeschley Acked-by: Nathan Sullivan Natinst-ReviewBoard-ID: 197765 Natinst-CAR-ID: 632383 (bmouring: fix small conflict) [gratian: re-work for e6a423a81da0 ("net: phy: micrel: add device-type abstraction") to use the new common 'struct kszphy_priv'] Signed-off-by: Gratian Crisan [cvadrevu: Fixed trivial conflicts due to ece19502834d ("net: phy: micrel: 1588 support for LAN8814 phy"), 58389c00d49cf ("net: phy: micrel: ksz9031/ksz9131: add cabletest support")] [cvadrevu: Adapt to current phylib by using linkmode_empty() for lp_advertising and replacing the removed PHY_STATE_TIME with an explicit one-second polling interval.] Signed-off-by: Chaitanya Vadrevu --- drivers/net/phy/micrel.c | 52 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index e6f00aa9a9901..32e6f91636775 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c @@ -55,7 +55,8 @@ #define KSZPHY_INTCS_REMOTE_FAULT BIT(9) #define KSZPHY_INTCS_LINK_UP BIT(8) #define KSZPHY_INTCS_ALL (KSZPHY_INTCS_LINK_UP |\ - KSZPHY_INTCS_LINK_DOWN) + KSZPHY_INTCS_LINK_DOWN |\ + KSZPHY_INTCS_LINK_PARTNER_ACK) #define KSZPHY_INTCS_LINK_DOWN_STATUS BIT(2) #define KSZPHY_INTCS_LINK_UP_STATUS BIT(0) #define KSZPHY_INTCS_STATUS (KSZPHY_INTCS_LINK_DOWN_STATUS |\ @@ -378,6 +379,9 @@ static struct kszphy_hw_stat kszphy_hw_stats[] = { { "phy_idle_errors", 10, 8 }, }; +#define KSZ9031_AUTONEG_TIMEOUT msecs_to_jiffies(20000) +#define KSZ9031_AUTONEG_POLL_INTERVAL HZ + struct kszphy_type { u32 led_mode_reg; u16 interrupt_level_mask; @@ -442,10 +446,14 @@ struct kszphy_phy_stats { struct kszphy_priv { struct kszphy_ptp_priv ptp_priv; + struct phy_device *phydev; const struct kszphy_type *type; struct clk *clk; int led_mode; u16 vct_ctrl1000; + unsigned long autoneg_timeout_jiffies; + struct delayed_work poll_work; + bool timeout_set; bool rmii_ref_clk_sel; bool rmii_ref_clk_sel_val; bool clk_enable; @@ -1649,10 +1657,13 @@ static int ksz9031_get_features(struct phy_device *phydev) return 0; } +static void ksz9031_autoneg_poll(struct work_struct *work); + static int ksz9031_read_status(struct phy_device *phydev) { int err; int regval; + struct kszphy_priv *priv = phydev->priv; err = genphy_read_status(phydev); if (err) @@ -1670,6 +1681,35 @@ static int ksz9031_read_status(struct phy_device *phydev) return genphy_config_aneg(phydev); } + /* Sometimes the ksz9031 can fail autonegotiation silently. + * It will set the link partner advertising bits when this happens, + * but will not actually finish autonegotiation - so reset it. + */ + if (!linkmode_empty(phydev->lp_advertising) && !phydev->link) { + if (!priv->timeout_set) { + priv->autoneg_timeout_jiffies = + jiffies + KSZ9031_AUTONEG_TIMEOUT; + priv->timeout_set = true; + } + + if (time_is_before_jiffies(priv->autoneg_timeout_jiffies)) { + phy_init_hw(phydev); + phydev->link = 0; + priv->timeout_set = false; + if (phydev->drv->config_intr && + phy_interrupt_is_valid(phydev)) + phydev->drv->config_intr(phydev); + } else { + INIT_DELAYED_WORK(&priv->poll_work, + ksz9031_autoneg_poll); + queue_delayed_work(system_power_efficient_wq, + &priv->poll_work, + KSZ9031_AUTONEG_POLL_INTERVAL); + } + } else { + priv->timeout_set = false; + } + return 0; } @@ -1875,6 +1915,15 @@ static int ksz9x31_cable_test_get_status(struct phy_device *phydev, return ret; } +static void ksz9031_autoneg_poll(struct work_struct *work) +{ + struct delayed_work *dwork = to_delayed_work(work); + struct kszphy_priv *priv = container_of(dwork, struct kszphy_priv, + poll_work); + + ksz9031_read_status(priv->phydev); +} + static int ksz8873mll_config_aneg(struct phy_device *phydev) { return 0; @@ -2535,6 +2584,7 @@ static int kszphy_probe(struct phy_device *phydev) if (!priv) return -ENOMEM; + priv->phydev = phydev; phydev->priv = priv; priv->type = type; From 3fcd2eae782f74846a0689118becfdeecc3ab943 Mon Sep 17 00:00:00 2001 From: Nathan Sullivan Date: Tue, 28 Aug 2018 15:54:33 -0500 Subject: [PATCH 80/83] net/phy: micrel: Init workaround work in probe Do not re-initialize maybe active work in the function the work handler will call. fixes: 8f9d74e9624 ("net/phy: micrel: Fix workaround for autoneg failure") Signed-off-by: Nathan Sullivan --- drivers/net/phy/micrel.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index 32e6f91636775..a3a7e65050919 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c @@ -1700,8 +1700,6 @@ static int ksz9031_read_status(struct phy_device *phydev) phy_interrupt_is_valid(phydev)) phydev->drv->config_intr(phydev); } else { - INIT_DELAYED_WORK(&priv->poll_work, - ksz9031_autoneg_poll); queue_delayed_work(system_power_efficient_wq, &priv->poll_work, KSZ9031_AUTONEG_POLL_INTERVAL); @@ -2587,6 +2585,9 @@ static int kszphy_probe(struct phy_device *phydev) priv->phydev = phydev; phydev->priv = priv; + INIT_DELAYED_WORK(&priv->poll_work, + ksz9031_autoneg_poll); + priv->type = type; kszphy_parse_led_mode(phydev); From e20f204fb1eb8639f69c25ef05d7fd16292ad2b8 Mon Sep 17 00:00:00 2001 From: Jeff Westfahl Date: Fri, 31 Aug 2012 16:35:28 -0500 Subject: [PATCH 81/83] macb: Send link speed to the PL via GPIOs Added support for an EMIO GPIO for telling the GMII-RGMII conversion logic in the PL what the link speed is. This is necessary for 1Gb Ethernet to work on many NI targets. These changes also magically fix the secondary Ethernet speed LED. Signed-off-by: Jeff Westfahl Signed-off-by: Jaeden Amero Acked-by: Ben Shelton Acked-by: Gratian Crisan Natinst-ReviewBoard-ID: 84563 (joshc: updated to use gpiod_* APIs) (bm: update to gpiod_* APIs) Signed-off-by: Josh Cartwright [cvadrevu: Port link-speed GPIO handling to phylink callbacks, add the GPIO consumer include, and fix probe error-path cleanup] Signed-off-by: Chaitanya Vadrevu --- drivers/net/ethernet/cadence/macb.h | 4 ++ drivers/net/ethernet/cadence/macb_main.c | 64 ++++++++++++++++++++++++ 2 files changed, 68 insertions(+) diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h index 6c99417898860..2e3113b8b8a27 100644 --- a/drivers/net/ethernet/cadence/macb.h +++ b/drivers/net/ethernet/cadence/macb.h @@ -1283,6 +1283,8 @@ struct ethtool_rx_fs_list { unsigned int count; }; +struct gpio_desc; + struct macb { void __iomem *regs; bool native_io; @@ -1329,6 +1331,8 @@ struct macb { struct phylink_config phylink_config; struct phylink_pcs phylink_usx_pcs; struct phylink_pcs phylink_sgmii_pcs; + struct gpio_desc *gpiospeed_1000; + struct gpio_desc *gpiospeed_100; u32 caps; unsigned int dma_burst_length; diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c index 5824f9bbbcf8c..bb7f9e73ca2de 100644 --- a/drivers/net/ethernet/cadence/macb_main.c +++ b/drivers/net/ethernet/cadence/macb_main.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -711,6 +712,12 @@ static void macb_mac_link_down(struct phylink_config *config, unsigned int mode, macb_writel(bp, NCR, ctrl); netif_tx_stop_all_queues(ndev); + + /* The link is down, so indicate this by setting both + * speed GPIOs to 0. + */ + gpiod_set_value(bp->gpiospeed_1000, 0); + gpiod_set_value(bp->gpiospeed_100, 0); } /* Use juggling algorithm to left rotate tx ring and tx skb array */ @@ -868,6 +875,22 @@ static void macb_mac_link_up(struct phylink_config *config, macb_writel(bp, NCR, ctrl | MACB_BIT(RE) | MACB_BIT(TE)); netif_tx_wake_all_queues(ndev); + + /* Update the link speed indicator GPIOs. */ + switch (speed) { + case SPEED_1000: + gpiod_set_value(bp->gpiospeed_1000, 0); + gpiod_set_value(bp->gpiospeed_100, 1); + break; + case SPEED_100: + gpiod_set_value(bp->gpiospeed_1000, 1); + gpiod_set_value(bp->gpiospeed_100, 1); + break; + case SPEED_10: + gpiod_set_value(bp->gpiospeed_1000, 1); + gpiod_set_value(bp->gpiospeed_100, 0); + break; + } } static struct phylink_pcs *macb_mac_select_pcs(struct phylink_config *config, @@ -5802,6 +5825,47 @@ static int macb_probe(struct platform_device *pdev) netif_carrier_off(dev); + /* Look for a GPIO to indicate link speed to the PL as 10/100 (high) + * or 1000 (low). + */ + bp->gpiospeed_100 = devm_gpiod_get_index_optional(&pdev->dev, + "emio-speed", 0, + GPIOD_ASIS); + if (IS_ERR(bp->gpiospeed_100)) { + dev_err(&pdev->dev, + "Error retrieving handle to EMIO gpiospeed_100\n"); + err = PTR_ERR(bp->gpiospeed_100); + goto err_out_unregister_mdio; + } + + if (bp->gpiospeed_100) { + err = gpiod_direction_output(bp->gpiospeed_100, 0); + if (err) { + dev_err(&pdev->dev, + "Unable to set EMIO gpiospeed_100 as output\n"); + goto err_out_unregister_mdio; + } + } + + bp->gpiospeed_1000 = devm_gpiod_get_index_optional(&pdev->dev, + "emio-speed", 1, + GPIOD_ASIS); + if (IS_ERR(bp->gpiospeed_1000)) { + dev_err(&pdev->dev, + "Error retrieving handle to EMIO gpiospeed_1000\n"); + err = PTR_ERR(bp->gpiospeed_1000); + goto err_out_unregister_mdio; + } + + if (bp->gpiospeed_1000) { + err = gpiod_direction_output(bp->gpiospeed_1000, 0); + if (err) { + dev_err(&pdev->dev, + "Unable to set EMIO gpiospeed_1000 as output\n"); + goto err_out_unregister_mdio; + } + } + err = register_netdev(dev); if (err) { dev_err(&pdev->dev, "Cannot register net device, aborting.\n"); From 93958078f8519710ea8627e13d53e1d53a42c612 Mon Sep 17 00:00:00 2001 From: Chaitanya Vadrevu Date: Mon, 3 Aug 2026 09:32:50 -0500 Subject: [PATCH 82/83] github-actions: Add ARM checks Install the ARM cross-compiler and U-Boot tools, build and validate Zynq, Bluefin, and SLSC defconfigs. Use separate output directories for all platform builds to avoid artifact conflicts. Signed-off-by: Chaitanya Vadrevu --- .github/workflows/pr-checks.yml | 40 +++++++++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/.github/workflows/pr-checks.yml b/.github/workflows/pr-checks.yml index 0219fcd06e18a..a354fa80eef56 100644 --- a/.github/workflows/pr-checks.yml +++ b/.github/workflows/pr-checks.yml @@ -23,16 +23,48 @@ jobs: sudo apt install libelf-dev sudo apt install python3-ply sudo apt install python3-git + sudo apt install gcc-arm-linux-gnueabihf + sudo apt install u-boot-tools - name: "[TEST] Build nati_x86_64_defconfig" run: | - make nati_x86_64_defconfig - make -j8 bzImage modules + make O=build-x64 nati_x86_64_defconfig + make O=build-x64 -j8 bzImage modules - name: "[TEST] Does nati_x86_64_defconfig need update" run: | - make savedefconfig - diff defconfig arch/x86/configs/nati_x86_64_defconfig + make O=build-x64 savedefconfig + diff build-x64/defconfig arch/x86/configs/nati_x86_64_defconfig + + - name: "[TEST] Build nati_zynq_defconfig" + run: | + make O=build-zynq ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- nati_zynq_defconfig + make O=build-zynq ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j8 ni-pkg + + - name: "[TEST] Does nati_zynq_defconfig need update" + run: | + make O=build-zynq ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- savedefconfig + diff build-zynq/defconfig arch/arm/configs/nati_zynq_defconfig + + - name: "[TEST] Build nati_bluefin_defconfig" + run: | + make O=build-bluefin ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- nati_bluefin_defconfig + make O=build-bluefin ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j8 ni-pkg + + - name: "[TEST] Does nati_bluefin_defconfig need update" + run: | + make O=build-bluefin ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- savedefconfig + diff build-bluefin/defconfig arch/arm/configs/nati_bluefin_defconfig + + - name: "[TEST] Build nati_slsc_defconfig" + run: | + make O=build-slsc ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- nati_slsc_defconfig + make O=build-slsc ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j8 ni-pkg + + - name: "[TEST] Does nati_slsc_defconfig need update" + run: | + make O=build-slsc ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- savedefconfig + diff build-slsc/defconfig arch/arm/configs/nati_slsc_defconfig - name: "[TEST] Is rebase required" run: | From d2be60ba228cb977c1d13b6ef31747e9ff1bc8ca Mon Sep 17 00:00:00 2001 From: Chaitanya Vadrevu Date: Mon, 3 Aug 2026 14:56:00 -0500 Subject: [PATCH 83/83] nati*defconfig: Disable CONFIG_LOCALVERSION_AUTO Prevent git commit IDs from being appended to kernel release string. This is needed for some NI drivers to build. Signed-off-by: Chaitanya Vadrevu --- arch/arm/configs/nati_bluefin_defconfig | 1 + arch/arm/configs/nati_slsc_defconfig | 1 + arch/arm/configs/nati_zynq_defconfig | 1 + 3 files changed, 3 insertions(+) diff --git a/arch/arm/configs/nati_bluefin_defconfig b/arch/arm/configs/nati_bluefin_defconfig index 2c1b729536d27..5cb1e0e1b40d4 100644 --- a/arch/arm/configs/nati_bluefin_defconfig +++ b/arch/arm/configs/nati_bluefin_defconfig @@ -1,4 +1,5 @@ CONFIG_LOCALVERSION="-ni" +# CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_AUDIT=y CONFIG_HIGH_RES_TIMERS=y diff --git a/arch/arm/configs/nati_slsc_defconfig b/arch/arm/configs/nati_slsc_defconfig index 8e60aedd57b11..4546c323117d8 100644 --- a/arch/arm/configs/nati_slsc_defconfig +++ b/arch/arm/configs/nati_slsc_defconfig @@ -1,4 +1,5 @@ CONFIG_LOCALVERSION="-ni" +# CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_AUDIT=y CONFIG_HIGH_RES_TIMERS=y diff --git a/arch/arm/configs/nati_zynq_defconfig b/arch/arm/configs/nati_zynq_defconfig index 7b7d2fc83caa1..8b849b1760254 100644 --- a/arch/arm/configs/nati_zynq_defconfig +++ b/arch/arm/configs/nati_zynq_defconfig @@ -1,4 +1,5 @@ CONFIG_LOCALVERSION="-ni" +# CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y CONFIG_AUDIT=y