From 9b36ed0fdd7df7c02124dd41054360c91df593bc Mon Sep 17 00:00:00 2001 From: Chaitanya Vadrevu Date: Mon, 24 Feb 2025 11:01:09 -0600 Subject: [PATCH 001/100] github-actions: Add PR checks Add GitHub actions to do PR sanity checks. Signed-off-by: Chaitanya Vadrevu --- .github/workflows/pr-checks.yml | 46 +++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 .github/workflows/pr-checks.yml diff --git a/.github/workflows/pr-checks.yml b/.github/workflows/pr-checks.yml new file mode 100644 index 0000000000000..8df161810f928 --- /dev/null +++ b/.github/workflows/pr-checks.yml @@ -0,0 +1,46 @@ +name: PR Checks + +on: + pull_request: {} + workflow_dispatch: {} + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.sha }} + fetch-depth: 100 + + - name: Fetch base_ref + run: git -c protocol.version=2 fetch --no-tags --prune --no-recurse-submodules --depth=1 origin ${{ github.base_ref }} + + - name: Install build dependencies + run: | + sudo apt update + sudo apt install libelf-dev + + - name: "[TEST] Build nati_x86_64_defconfig" + run: | + make nati_x86_64_defconfig + make -j8 bzImage modules + + - name: "[TEST] Does nati_x86_64_defconfig need update" + run: | + make savedefconfig + diff defconfig arch/x86/configs/nati_x86_64_defconfig + + - name: "[TEST] Is rebase required" + run: | + common_ancestor=$(git merge-base HEAD origin/${{ github.base_ref }}) + base_ref_head=$(git log -1 --format=%H origin/${{ github.base_ref }}) + + [ $common_ancestor == $base_ref_head ] + + - name: "[TEST] Run checkpatch.pl" + run: | + common_ancestor=$(git merge-base HEAD origin/${{ github.base_ref }}) + git format-patch $common_ancestor + ./scripts/checkpatch.pl *patch From 460c81eb678af86a70f1e950873bc7c718029457 Mon Sep 17 00:00:00 2001 From: deooi Date: Tue, 14 Apr 2026 13:29:22 +0800 Subject: [PATCH 002/100] workflows: Add python3-ply and python3-git to pr-checks.yml We need this because pr checks are complaining about missing ply and git module. Signed-off-by: deooi --- .github/workflows/pr-checks.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/pr-checks.yml b/.github/workflows/pr-checks.yml index 8df161810f928..0219fcd06e18a 100644 --- a/.github/workflows/pr-checks.yml +++ b/.github/workflows/pr-checks.yml @@ -21,6 +21,8 @@ jobs: run: | sudo apt update sudo apt install libelf-dev + sudo apt install python3-ply + sudo apt install python3-git - name: "[TEST] Build nati_x86_64_defconfig" run: | From 6811ad2ecc5fa671b73bbc3419a9045d67ab1c36 Mon Sep 17 00:00:00 2001 From: Ben Shelton Date: Tue, 1 Apr 2014 11:31:31 -0500 Subject: [PATCH 003/100] shared: Adding mcopy syscall for x64 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 [bstreiff: update the number for this painful out-of-tree syscall] Signed-off-by: Brandon Streiff [gratian: update due to new syscall introduced by ecb8ac8b1f14 ("mm/madvise: introduce process_madvise() syscall: an external memory hinting AP")] Signed-off-by: Gratian Crisan [gratian: update syscall numbers to account for upstream additions; dropped arm bits] Signed-off-by: Gratian Crisan [gratian: bump syscall number to account for upstream process_mrelease addition] Signed-off-by: Gratian Crisan [gratian: bump syscall number to account for upstream 'futex_waitv' and 'set_mempolicy_home_node' additions] Signed-off-by: Gratian Crisan [mpeterse: bump syscall number to account for upstream 'cachestat', 'fchmodat2', and 'map_shadow_stack' additions] [mpeterse: remove comments in syscalls.h referring to the function's source file] Signed-off-by: Mike Petersen [cvadrevu: bump syscall number to account for upstream additions] Signed-off-by: Chaitanya Vadrevu [gratian: bump syscall number to account for upstream additions] Signed-off-by: Gratian Crisan --- arch/x86/entry/syscalls/syscall_64.tbl | 1 + include/linux/syscalls.h | 2 ++ include/uapi/asm-generic/unistd.h | 5 +++- kernel/ksysfs.c | 14 +++++++++++ mm/maccess.c | 32 ++++++++++++++++++++++++++ 5 files changed, 53 insertions(+), 1 deletion(-) diff --git a/arch/x86/entry/syscalls/syscall_64.tbl b/arch/x86/entry/syscalls/syscall_64.tbl index ced2a1deecd7c..008b7188e26b1 100644 --- a/arch/x86/entry/syscalls/syscall_64.tbl +++ b/arch/x86/entry/syscalls/syscall_64.tbl @@ -394,6 +394,7 @@ 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 # # Due to a historical design error, certain syscalls are numbered differently diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 66c06fcdfe19e..4d7bdae28f003 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -822,6 +822,8 @@ asmlinkage long sys_execve(const char __user *filename, const char __user *const __user *envp); asmlinkage long sys_fadvise64_64(int fd, loff_t offset, loff_t len, int advice); +asmlinkage long sys_mcopy(void * __user dest, void * __user src, size_t len); + /* CONFIG_MMU only */ asmlinkage long sys_swapon(const char __user *specialfile, int swap_flags); asmlinkage long sys_swapoff(const char __user *specialfile); diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h index 04e0077fb4c97..38e14a2b9453a 100644 --- a/include/uapi/asm-generic/unistd.h +++ b/include/uapi/asm-generic/unistd.h @@ -858,8 +858,11 @@ __SYSCALL(__NR_file_getattr, sys_file_getattr) #define __NR_file_setattr 469 __SYSCALL(__NR_file_setattr, sys_file_setattr) +#define __NR_mcopy 470 +__SYSCALL(__NR_mcopy, sys_mcopy) + #undef __NR_syscalls -#define __NR_syscalls 470 +#define __NR_syscalls 471 /* * 32 bit systems traditionally used different diff --git a/kernel/ksysfs.c b/kernel/ksysfs.c index 20ac8a5ac27d7..a93e9303f96d4 100644 --- a/kernel/ksysfs.c +++ b/kernel/ksysfs.c @@ -18,6 +18,7 @@ #include #include #include +#include #include /* rcu_expedited and rcu_normal */ @@ -205,6 +206,16 @@ static ssize_t fscaps_show(struct kobject *kobj, } KERNEL_ATTR_RO(fscaps); +#ifdef __NR_mcopy +static ssize_t ni_syscall_mcopy_show(struct kobject *kobj, + struct kobj_attribute *attr, + char *buf) +{ + return sprintf(buf, "%d\n", __NR_mcopy); +} +KERNEL_ATTR_RO(ni_syscall_mcopy); +#endif + #ifndef CONFIG_TINY_RCU int rcu_expedited; static ssize_t rcu_expedited_show(struct kobject *kobj, @@ -283,6 +294,9 @@ static struct attribute * kernel_attrs[] = { #endif #ifdef CONFIG_PREEMPT_RT &realtime_attr.attr, +#endif +#ifdef __NR_mcopy + &ni_syscall_mcopy_attr.attr, #endif NULL }; diff --git a/mm/maccess.c b/mm/maccess.c index 486559d688583..73319c3ec4681 100644 --- a/mm/maccess.c +++ b/mm/maccess.c @@ -5,6 +5,7 @@ #include #include #include +#include #include bool __weak copy_from_kernel_nofault_allowed(const void *unsafe_src, @@ -234,3 +235,34 @@ void __copy_overflow(int size, unsigned long count) WARN(1, "Buffer overflow detected (%d < %lu)!\n", size, count); } EXPORT_SYMBOL(__copy_overflow); + +/* + * Safely copy 'len' bytes from user space 'src' to user space 'dst'. + * 'len' must be less than or equal to 64. In particular, safely here + * means that if we are trying to copy memory that has been freed and + * unmapped we don't crash. + * + * Returns + * 0 copy completed successfully + * + * EFAULT if either the source or destination blocks are not + * valid + * + * EINVAL len is greater than 64 + * + */ +SYSCALL_DEFINE3(mcopy, void*, dst, void*, src, size_t, len) +{ + char buf[64]; + + if (len > 64) + return -EINVAL; + + if (copy_from_user(buf, src, len)) + return -EFAULT; + + if (copy_to_user(dst, buf, len)) + return -EFAULT; + + return 0; +} From 73fc79d59ebfdc7601398f2321c8cca7aeb3d187 Mon Sep 17 00:00:00 2001 From: Terry Wilcox Date: Mon, 19 May 2014 15:28:03 -0500 Subject: [PATCH 004/100] kernel: Providing API to allow userland programs to request a cold or warm reboot Another group is requesting that we provide an API to allow them to signal that the next reboot should be "cold". They need this to guarantee that the FPGA will not be running and cause the system to reboot at a bad time. This change creates a RW file at /sys/kernel/ni_requested_reboot_type. The default value is 0. - If when we reboot the value is 0 then we do the normal reset behavior. - If the value is 1 we attempt to do a PCI reboot (using the CF9 register) and fall back to the normal reboot method if that fails. - If the value is 2 we attempt to do an ACPI reboot and fall back to the normal reboot method if that fails. We selected a reboot using the CF9 register over attempting to do an EFI reboot because we don't have much time to test this feature and we've found EFI features to be fairly buggy. For next release the plan is to do an EFI cold reboot, but put it in early enough to properly test it. Rebooting using the CF9 register should work on all x64 hardware that we will support for 2014 (smasher and hammerhead). Signed-off-by: Terry Wilcox Acked-by: Brad Mouring Natinst-ReviewBoard-ID: 68018 --- arch/x86/kernel/reboot.c | 49 ++++++++++++++++++++++++++++++++-------- kernel/ksysfs.c | 18 +++++++++++++++ 2 files changed, 58 insertions(+), 9 deletions(-) diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c index 964f6b0a3d68c..525849c841904 100644 --- a/arch/x86/kernel/reboot.c +++ b/arch/x86/kernel/reboot.c @@ -39,6 +39,14 @@ void (*pm_power_off)(void); EXPORT_SYMBOL(pm_power_off); +enum requested_reboot_type { + REQUEST_DEFAULT_REBOOT, + REQUEST_COLD_REBOOT, + REQUEST_WARM_REBOOT +}; + +enum requested_reboot_type requested_reboot_type = REQUEST_DEFAULT_REBOOT; + /* * This is set if we need to go through the 'emergency' path. * When machine_emergency_restart() is called, we may be on @@ -606,6 +614,21 @@ void __attribute__((weak)) mach_reboot_fixups(void) { } +static void native_machine_restart_cf9(void) +{ + if (port_cf9_safe) { + u8 reboot_code = reboot_mode == REBOOT_WARM ? 0x06 : 0x0E; + u8 cf9 = inb(0xcf9) & ~reboot_code; + + outb(cf9|2, 0xcf9); /* Request hard reset */ + udelay(50); + /* Actually do the reset */ + outb(cf9|reboot_code, 0xcf9); + udelay(50); + } +} + + /* * To the best of our knowledge Windows compatible x86 hardware expects * the following on reboot: @@ -637,6 +660,22 @@ static void native_machine_emergency_restart(void) tboot_shutdown(TB_SHUTDOWN_REBOOT); + + switch (requested_reboot_type) { + case REQUEST_COLD_REBOOT: + port_cf9_safe = true; + native_machine_restart_cf9(); + break; + + case REQUEST_WARM_REBOOT: + acpi_reboot(); + break; + + case REQUEST_DEFAULT_REBOOT: + default: + break; + } + /* Tell the BIOS if we want cold or warm reboot */ mode = reboot_mode == REBOOT_WARM ? 0x1234 : 0; *((unsigned short *)__va(0x472)) = mode; @@ -692,15 +731,7 @@ static void native_machine_emergency_restart(void) fallthrough; case BOOT_CF9_SAFE: - if (port_cf9_safe) { - u8 reboot_code = reboot_mode == REBOOT_WARM ? 0x06 : 0x0E; - u8 cf9 = inb(0xcf9) & ~reboot_code; - outb(cf9|2, 0xcf9); /* Request hard reset */ - udelay(50); - /* Actually do the reset */ - outb(cf9|reboot_code, 0xcf9); - udelay(50); - } + native_machine_restart_cf9(); reboot_type = BOOT_TRIPLE; break; diff --git a/kernel/ksysfs.c b/kernel/ksysfs.c index a93e9303f96d4..bf17cc36783c1 100644 --- a/kernel/ksysfs.c +++ b/kernel/ksysfs.c @@ -252,6 +252,23 @@ static ssize_t rcu_normal_store(struct kobject *kobj, KERNEL_ATTR_RW(rcu_normal); #endif /* #ifndef CONFIG_TINY_RCU */ +extern int requested_reboot_type; +static ssize_t ni_requested_reboot_type_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", requested_reboot_type); +} +static ssize_t ni_requested_reboot_type_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, size_t count) +{ + if (kstrtoint(buf, 0, &requested_reboot_type)) + return -EINVAL; + + return count; +} +KERNEL_ATTR_RW(ni_requested_reboot_type); + /* * Make /sys/kernel/notes give the raw contents of our kernel .notes section. */ @@ -298,6 +315,7 @@ static struct attribute * kernel_attrs[] = { #ifdef __NR_mcopy &ni_syscall_mcopy_attr.attr, #endif + &ni_requested_reboot_type_attr.attr, NULL }; From fbfedc94d2ae4c5a46bb179d8967c705e6991fd3 Mon Sep 17 00:00:00 2001 From: Ben Shelton Date: Tue, 10 Jun 2014 15:04:11 -0500 Subject: [PATCH 005/100] kernel: Add config option to specify NI cold boot support Currently, we provide NI cold boot support on x64 targets. However, at some future point, we may wish to provide this support on other targets as well. Adding a config option to specify that a target supports NI cold boot functionality; this fixes the build for Zynq targets and doesn't paint us into a corner later. Signed-off-by: Ben Shelton [gratian: fix trivial conflict with ceea991a019c ("bpf: Move bpf_dispatcher function out of ftrace locations")] Signed-off-by: Gratian Crisan [gratian: fix trivial conflict with 7bd291abe2da ("sched: Unify the SCHED_{SMT,CLUSTER,MC} Kconfig")] Signed-off-by: Gratian Crisan --- arch/x86/Kconfig | 4 ++++ kernel/ksysfs.c | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index a3700766a8c08..ca5c01fbf03d4 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -333,6 +333,10 @@ config X86 select SCHED_SMT if SMP select ARCH_SUPPORTS_SCHED_CLUSTER if SMP select ARCH_SUPPORTS_SCHED_MC if SMP + select NI_COLD_BOOT_SUPPORT + +config NI_COLD_BOOT_SUPPORT + def_bool n config INSTRUCTION_DECODER def_bool y diff --git a/kernel/ksysfs.c b/kernel/ksysfs.c index bf17cc36783c1..45427bd2875d6 100644 --- a/kernel/ksysfs.c +++ b/kernel/ksysfs.c @@ -252,6 +252,7 @@ static ssize_t rcu_normal_store(struct kobject *kobj, KERNEL_ATTR_RW(rcu_normal); #endif /* #ifndef CONFIG_TINY_RCU */ +#ifdef CONFIG_NI_COLD_BOOT_SUPPORT extern int requested_reboot_type; static ssize_t ni_requested_reboot_type_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) @@ -268,6 +269,7 @@ static ssize_t ni_requested_reboot_type_store(struct kobject *kobj, return count; } KERNEL_ATTR_RW(ni_requested_reboot_type); +#endif /* * Make /sys/kernel/notes give the raw contents of our kernel .notes section. @@ -315,7 +317,9 @@ static struct attribute * kernel_attrs[] = { #ifdef __NR_mcopy &ni_syscall_mcopy_attr.attr, #endif +#ifdef CONFIG_NI_COLD_BOOT_SUPPORT &ni_requested_reboot_type_attr.attr, +#endif NULL }; From 8df2a8eb77e356464a7236806ea05fa0112269aa Mon Sep 17 00:00:00 2001 From: Haris Okanovic Date: Fri, 25 Sep 2015 11:34:42 -0500 Subject: [PATCH 006/100] proc/interrupts: Add polling Implement polling on procfs' "interrupts" file which observes changes to IRQ action handlers. The poll fires each time an action handler is registered or unregistered. This change enables daemons to watch for changes and apply certain system policies relating to IRQ processing. For example, modify execution priority of dedicated IRQ tasks after they're created. include/linux/interrupt.h kernel/irq/manage.c Add change counter for handler registrations and a wait queue to notify tasks on updates. fs/proc/interrupts.c Add polling callback on aforementioned counter and wait queue. Signed-off-by: Haris Okanovic Signed-off-by: Ovidiu-Adrian Vancea Signed-off-by: Brad Mouring Natinst-ReviewBoard-ID: 111860, 163902 [gratian: fixed small rebase conflict] Signed-off-by: Gratian Crisan [bstreiff: un-trivialize from changes in fddda2b7b521 ("proc: introduce proc_create_seq{,_data}") and convert file_operations to proc_ops] Signed-off-by: Brandon Streiff [cvadrevu: include linux/wait.h for wait_queue_head_t] Signed-off-by: Chaitanya Vadrevu [gratian: fix trivial conflict with 827bafd527dd ("genirq: Make a few functions static")] Signed-off-by: Gratian Crisan --- fs/proc/interrupts.c | 74 ++++++++++++++++++++++++++++++++++++++- include/linux/interrupt.h | 5 +++ kernel/irq/manage.c | 18 ++++++++++ 3 files changed, 96 insertions(+), 1 deletion(-) diff --git a/fs/proc/interrupts.c b/fs/proc/interrupts.c index 714a22ded8a8f..a964b8326f900 100644 --- a/fs/proc/interrupts.c +++ b/fs/proc/interrupts.c @@ -1,10 +1,12 @@ // SPDX-License-Identifier: GPL-2.0 #include +#include #include #include #include #include #include +#include /* * /proc/interrupts @@ -34,9 +36,79 @@ static const struct seq_operations int_seq_ops = { .show = show_interrupts }; +struct interrupts_fd_state { + atomic_long_t last_irq_change_count; +}; + +static int interrupts_open(struct inode *inode, struct file *filp) +{ + int res; + struct interrupts_fd_state *privdata; + struct seq_file *sf; + + privdata = kzalloc(sizeof(struct interrupts_fd_state), GFP_KERNEL); + if (!privdata) { + res = -ENOMEM; + goto exit; + } + + res = seq_open(filp, &int_seq_ops); + if (res) { + kfree(privdata); + goto exit; + } + + sf = filp->private_data; + sf->private = privdata; + + atomic_long_set(&(privdata->last_irq_change_count), + get_irq_handler_change_count()); + +exit: + return res; +} + +static int interrupts_release(struct inode *inode, struct file *filp) +{ + struct seq_file *sf = filp->private_data; + + kfree(sf->private); + return seq_release(inode, filp); +} + +static unsigned int interrupts_poll(struct file *filp, + struct poll_table_struct *pt) +{ + unsigned int mask = POLLIN | POLLRDNORM; + long newcount, oldcount; + struct seq_file *sf = filp->private_data; + struct interrupts_fd_state *fds = sf->private; + + /* Register for changes to IRQ handlers */ + poll_wait(filp, &irq_handler_change_wq, pt); + + /* Store new change count in priv data */ + newcount = get_irq_handler_change_count(); + oldcount = atomic_long_xchg( + &(fds->last_irq_change_count), newcount); + + if (newcount != oldcount) + mask |= POLLERR | POLLPRI; + + return mask; +} + +static const struct proc_ops interrupts_proc_ops = { + .proc_open = interrupts_open, + .proc_read = seq_read, + .proc_poll = interrupts_poll, + .proc_lseek = seq_lseek, + .proc_release = interrupts_release, +}; + static int __init proc_interrupts_init(void) { - proc_create_seq("interrupts", 0, NULL, &int_seq_ops); + proc_create("interrupts", 0, NULL, &interrupts_proc_ops); return 0; } fs_initcall(proc_interrupts_init); diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index 51b6484c04934..5fa1dffed92c4 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h @@ -21,6 +21,8 @@ #include #include +#include + /* * These correspond to the IORESOURCE_IRQ_* defines in * linux/ioport.h to select the interrupt line behaviour. When @@ -872,6 +874,9 @@ extern int early_irq_init(void); extern int arch_probe_nr_irqs(void); extern int arch_early_irq_init(void); +extern long get_irq_handler_change_count(void); +extern wait_queue_head_t irq_handler_change_wq; + /* * We want to know which function is an entrypoint of a hardirq or a softirq. */ diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index 400856abf6721..41559ac5d3a09 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c @@ -37,6 +37,22 @@ early_param("threadirqs", setup_forced_irqthreads); static int __irq_get_irqchip_state(struct irq_data *d, enum irqchip_irq_state which, bool *state); +static atomic_long_t irq_handler_change_count = ATOMIC_LONG_INIT(0); +DECLARE_WAIT_QUEUE_HEAD(irq_handler_change_wq); + +/* Bump change count and wake up anything waiting on changes to + * IRQ handlers */ +static void __irq_handler_change_event(void) +{ + atomic_long_inc(&irq_handler_change_count); + wake_up(&irq_handler_change_wq); +} + +long get_irq_handler_change_count(void) +{ + return atomic_long_read(&irq_handler_change_count); +} + static void __synchronize_hardirq(struct irq_desc *desc, bool sync_chip) { struct irq_data *irqd = irq_desc_get_irq_data(desc); @@ -1762,6 +1778,7 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new) register_irq_proc(irq, desc); new->dir = NULL; register_handler_proc(irq, new); + __irq_handler_change_event(); return 0; mismatch: @@ -1934,6 +1951,7 @@ static struct irqaction *__free_irq(struct irq_desc *desc, void *dev_id) irq_chip_pm_put(&desc->irq_data); module_put(desc->owner); kfree(action->secondary); + __irq_handler_change_event(); return action; } From ca8c1b0114e384403eb17ae724b33c6183bbb827 Mon Sep 17 00:00:00 2001 From: Richard Tollerton Date: Wed, 4 Apr 2012 20:13:05 -0400 Subject: [PATCH 007/100] ftrace: ni: add raw marker support for trace tool Signed-off-by: Richard Tollerton [gratian: fix conflict with fa32e8557b47 ("tracing: Add new trace_marker_raw"); rename NI specific implementation until we can replace it] Signed-off-by: Gratian Crisan [bstreiff: fixups due to struct member renames in 13292494379f ("tracing: Make struct ring_buffer less ambiguous")] Signed-off-by: Brandon Streiff [gratian: update for 22c36b182634 ("tracing: make tracing_init_dentry() returns an integer instead of a d_entry pointer")] Signed-off-by: Gratian Crisan [gratian: fixups due to tracing contex introduction in edbaaa13a660 ("tracing: Merge irqflags + preemt counter, add RT bits")] Signed-off-by: Gratian Crisan [gratian: fixups due to tracing_gen_ctx_flags() API change in 8cac5dbf18c7 ("tracing: Merge irqflags + preemt counter, add RT bits")] Signed-off-by: Gratian Crisan [gratian: use always_inlined __trace_buffer_lock_reserve() introduced by 3e9a8aadca48 ("tracing: Create a always_inlined __trace_buffer_lock_reserve()")] Signed-off-by: Gratian Crisan [cvadrevu: deprecate trace_ni_ett_marker] Signed-off-by: Chaitanya Vadrevu [gratian: squash deprecation commit with original to reduce rebase burden; fix trivial conflict] Signed-off-by: Gratian Crisan --- kernel/trace/trace.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 907923d5f8bbb..4cb8db8d0745f 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -7539,6 +7539,23 @@ static int tracing_mark_release(struct inode *inode, struct file *file) return tracing_release_generic_tr(inode, file); } +/* + * tracing_ni_ett_raw_write was added as part of LabVIEW RT's support of the + * Execution Trace Toolkit (RTETT). But RTETT is being deprecated in favor of + * using open source tooling, including ftrace and kernelshark. Keep the + * trace_ni_ett_marker file and just enough implementation to not break existing + * VIs. + * + * This can be completely removed when support is dropped for old LabVIEW + * versions shipping RTETT VIs. + */ +static ssize_t +tracing_ni_ett_raw_write(struct file *filp, const char __user *ubuf, + size_t cnt, loff_t *fpos) +{ + return cnt; +} + static int tracing_clock_show(struct seq_file *m, void *v) { struct trace_array *tr = m->private; @@ -7955,6 +7972,12 @@ static const struct file_operations tracing_mark_raw_fops = { .release = tracing_mark_release, }; +static const struct file_operations tracing_ni_ett_raw_fops = { + .open = tracing_open_generic, + .write = tracing_ni_ett_raw_write, + .llseek = generic_file_llseek, +}; + static const struct file_operations trace_clock_fops = { .open = tracing_clock_open, .read = seq_read, @@ -10614,6 +10637,9 @@ static __init void tracer_init_tracefs_work_func(struct work_struct *work) trace_create_file("README", TRACE_MODE_READ, NULL, NULL, &tracing_readme_fops); + trace_create_file("trace_ni_ett_marker", 0220, NULL, + NULL, &tracing_ni_ett_raw_fops); + trace_create_file("saved_cmdlines", TRACE_MODE_READ, NULL, NULL, &tracing_saved_cmdlines_fops); From ffaba778a73a8fa2764f33d1c3cdc5c46d8fbba4 Mon Sep 17 00:00:00 2001 From: Gratian Crisan Date: Thu, 24 Mar 2016 13:52:00 -0500 Subject: [PATCH 008/100] time: Make the clocksource watchdog user configurable The clocksource watchdog is used to detect instabilities in the current clocksource. This is a beneficial feature on new/unknown hardware however it can create problems by falsely triggering when the watchdog wraps. The reason is that an interrupt storm and/or high priority (FIFO/RR) tasks can preempt the timer softirq long enough for the watchdog to wrap if it has a limited number of bits available by comparison with the main clocksource. One observed example is on a Intel Baytrail platform where TSC is the main clocksource, HPET is disabled due to a hardware bug and acpi_pm gets selected as the watchdog clocksource. Provide the option to disable the clocksource watchdog for hardware where the clocksource stability has been validated. Signed-off-by: Gratian Crisan [gratian: fix trivial conflict with fc153c1c58cb ("clocksource: Add a Kconfig option for WATCHDOG_MAX_SKEW")] Signed-off-by: Gratian Crisan [gratian: fix trivial conflict with 7cf8f44a5a1c ("x86: fs: kmsan: disable CONFIG_DCACHE_WORD_ACCESS")] Signed-off-by: Gratian Crisan [cvadrevu: fix trivial conflict with e26cbab9821a ("timekeeping: Always check for negative motion")] Signed-off-by: Chaitanya Vadrevu --- arch/x86/Kconfig | 2 +- kernel/time/Kconfig | 12 +++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index ca5c01fbf03d4..7d652304211fa 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -154,7 +154,7 @@ config X86 select ARCH_WANT_IRQS_OFF_ACTIVATE_MM select BUILDTIME_TABLE_SORT select CLKEVT_I8253 - select CLOCKSOURCE_WATCHDOG + select HAVE_CLOCKSOURCE_WATCHDOG # Word-size accesses may read uninitialized data past the trailing \0 # in strings and cause false KMSAN reports. select DCACHE_WORD_ACCESS if !KMSAN diff --git a/kernel/time/Kconfig b/kernel/time/Kconfig index 7c6a52f7836ce..0bbe7376728a5 100644 --- a/kernel/time/Kconfig +++ b/kernel/time/Kconfig @@ -6,7 +6,7 @@ # Options selectable by arch Kconfig # Watchdog function for clocksources to detect instabilities -config CLOCKSOURCE_WATCHDOG +config HAVE_CLOCKSOURCE_WATCHDOG bool # Architecture has extra clocksource data @@ -221,4 +221,14 @@ config POSIX_AUX_CLOCKS and other clock domains, which are not correlated to the TAI/NTP notion of time. +config CLOCKSOURCE_WATCHDOG + bool "Clocksource watchdog" + depends on HAVE_CLOCKSOURCE_WATCHDOG + default y + help + This option enables the watchdog function for clocksources. It is + used to detect instabilities in the currently selected clocksource. + + Say Y if you are unsure. + endmenu From bcd1f335ef440448e07b91fd21124ddfeb8fbda9 Mon Sep 17 00:00:00 2001 From: Brad Mouring Date: Wed, 1 Mar 2017 13:43:12 -0600 Subject: [PATCH 009/100] Revert "time: Always make sure wall_to_monotonic isn't positive" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit e1d7ba8735551ed79c7a0463a042353574b96da3. NI has a use case that involves distributed networked Linux devices that need to share the same concept of time using a mechanism like IEEE-1588 or 802.1AS. The “master” device (ie. the device with the time all other devices will be synchronized to) is often a device that boots up set to the Posix Epoch, mainly because it lacks a battery-backed RTC. (note: the existence of an RTC does not prevent a device from booting up at or very near the Posix Epoch, it just greatly reduces the likelihood). If a slave device attempted to synchronize its CLOCK_REALTIME to that of the master – and the master’s time was < Epoch+slave uptime, that slave would not be able to synchronize. This use case is believed to be very common among embedded devices, especially those without RTCs. Long term: We (NI Timing & Sync) are planning on engaging with the upstream community to educate them on our use case and hopefully put a different solution in place which solves the original problem (preventing a negative boot time representation) while also allowing our use case to continue working as it did prior to the change we’re reverting. Once that happens, we can drop this revert. Signed-off-by: Brad Mouring Reported-by: Vineeth Acharya Tested-by: Rick Ratzel Natinst-CAR-ID: 629499 [bstreiff: reduced control flow in do_settimeofday64 due to unassigned 'ret'] Signed-off-by: Brandon Streiff [gratian: fix conflict with b8ac29b40183 ("timekeeping: contribute wall clock to rng on time change")] Signed-off-by: Gratian Crisan [gratian: fix conflicts with bba9898ef399 ("timekeeping: Rework do_settimeofday64() to use shadow_timekeeper") 82214756d35f ("timekeeping: Rework timekeeping_inject_offset() to use shadow_timekeeper")] Signed-off-by: Gratian Crisan --- kernel/time/timekeeping.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index 340fef20bdcd0..4d9e31ce79744 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -1446,11 +1446,6 @@ int do_settimeofday64(const struct timespec64 *ts) xt = tk_xtime(tks); ts_delta = timespec64_sub(*ts, xt); - if (timespec64_compare(&tks->wall_to_monotonic, &ts_delta) > 0) { - timekeeping_restore_shadow(&tk_core); - return -EINVAL; - } - tk_set_wall_to_mono(tks, timespec64_sub(tks->wall_to_monotonic, ts_delta)); tk_set_xtime(tks, ts); timekeeping_update_from_shadow(&tk_core, TK_UPDATE_ALL); @@ -1490,8 +1485,7 @@ static int __timekeeping_inject_offset(struct tk_data *tkd, const struct timespe if (timekeeper_is_core_tk(tks)) { /* Make sure the proposed value is valid */ tmp = timespec64_add(tk_xtime(tks), *ts); - if (timespec64_compare(&tks->wall_to_monotonic, ts) > 0 || - !timespec64_valid_settod(&tmp)) { + if (!timespec64_valid_settod(&tmp)) { timekeeping_restore_shadow(tkd); return -EINVAL; } From e2bf0fb67e09e0e12516e9b6bcfe520067d3f742 Mon Sep 17 00:00:00 2001 From: Charlie Johnston Date: Tue, 5 Sep 2023 15:14:30 -0500 Subject: [PATCH 010/100] include/uapi pps.h: increase PPS_MAX_SOURCES value For consistency with what others use for minors, this change sets PPS_MAX_SOURCES to MINORMASK. The PPS_MAX_SOURCES value is currently set to 16. In some cases this was not sufficient for a system. For example, a system with multiple (4+) PCIe cards each with 4 PTP-capable ethernet interfaces could run out of the available PPS major:minors if each interface registers a PPS source. Signed-off-by: Charlie Johnston Acked-by: Rodolfo Giometti --- include/uapi/linux/pps.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/uapi/linux/pps.h b/include/uapi/linux/pps.h index 009ebcd8ced5e..90f2e86020ba9 100644 --- a/include/uapi/linux/pps.h +++ b/include/uapi/linux/pps.h @@ -26,7 +26,7 @@ #include #define PPS_VERSION "5.3.6" -#define PPS_MAX_SOURCES 16 /* should be enough... */ +#define PPS_MAX_SOURCES MINORMASK /* Implementation note: the logical states ``assert'' and ``clear'' * are implemented in terms of the chip register, i.e. ``assert'' From de7a404118af7d8a74bcd61306656a2c374c9518 Mon Sep 17 00:00:00 2001 From: Wan Ahmad Zainie Date: Tue, 14 Mar 2017 15:45:21 -0500 Subject: [PATCH 011/100] usb: dwc3: call _DSM for core soft reset The issue is, if core soft reset is issued while Intel Apollo Lake USB mux is in Host role mode, it takes close to 7 minutes before we are able to switch USB mux from Host mode to Device mode. This is due to RTL bug. The workaround is to let BIOS issue the core soft reset via _DSM method. It will ensure that USB mux is in Device role mode before issuing core soft reset, and will inform the driver whether the reset is success within the timeout value, or the timeout is exceeded. commit cd78b8067c6e ("usb: dwc3: call _DSM for core soft reset") originated from http://git.yoctoproject.org/cgit/cgit.cgi/linux-yocto-4.1/ Signed-off-by: Wan Ahmad Zainie [akash.mankar@ni.com: changed the way has_dsm_for_softreset property is set in dwc3-pci.c and read in core.c] Signed-off-by: Akash Mankar Signed-off-by: Brad Mouring Acked-by: Gratian Crisan Acked-by: Brandon Streiff Natinst-ReviewBoard-ID: 178124 [gratian: fixed merge conflicts, mainly due to dwc3_soft_reset removal] Signed-off-by: Gratian Crisan [bstreiff: fixed merge conflicts due to property refactor by 1a7b12f69a94 ("usb: dwc3: pci: Supply device properties via driver data")] [gratian: fix merge conflict with f580170f135a ("usb: dwc3: Add splitdisable quirk for Hisilicon Kirin Soc")] Signed-off-by: Gratian Crisan [gratian: fix conflict with 582ab24e096f ("usb: dwc3: pci: Set "linux,phy_charger_detect" property on some Bay Trail boards")] Signed-off-by: Gratian Crisan [cvadrevu: fix trivial conflict with 047161686b813 ("usb: dwc3: Add remote wakeup handling")] [cvadrevu: fix trivial conflict with 4e8ef34e36f28 ("usb: dwc3: fix gadget mode suspend interrupt handler issue")] [cvadrevu: fix conflict with 8bea147dfdf82 ("usb: dwc3: Soft reset phy on probe for host")] [cvadrevu: fix conflict with 917dc99b65911 ("usb: dwc3: pci: Change PCI device macros")] Signed-off-by: Chaitanya Vadrevu [cvadrevu: fix conflict with 4fad737008679 ("usb: dwc3: core: Fix system suspend on TI AM62 platforms")] [cvadrevu: fix conflict with e8d48c2282a91 ("Revert "usb: dwc3: Soft reset phy on probe for host"")] Signed-off-by: Chaitanya Vadrevu --- drivers/usb/dwc3/core.c | 40 +++++++++++++++++++++++++++++++++++++ drivers/usb/dwc3/core.h | 3 +++ drivers/usb/dwc3/dwc3-pci.c | 17 +++++++++++++--- 3 files changed, 57 insertions(+), 3 deletions(-) diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index eb10490a6d92c..a76240d1e2376 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -314,6 +314,38 @@ u32 dwc3_core_fifo_space(struct dwc3_ep *dep, u8 type) return DWC3_GDBGFIFOSPACE_SPACE_AVAILABLE(reg); } +/** + * WORKAROUND: We let BIOS issues the core soft reset to Device + * controller for Intel Apollo Lake, via _DSM method. + * + * The issue is, if core soft reset is issued while Intel Apollo Lake + * USB mux is in Host role mode, it takes close to 7 minutes before + * we are able to switch USB mux from Host mode to Device mode. + */ +static int dwc3_pci_dsm_soft_reset(struct device *dev) +{ + int ret = -ETIMEDOUT; + union acpi_object *obj; + guid_t guid; + + WARN_ON(guid_parse("732b85d5-b7a7-4a1b-9ba0-4bbd00ffd511", &guid)); + + obj = acpi_evaluate_dsm(ACPI_HANDLE(dev), + &guid, + 1, 6, NULL); + if (!obj) { + dev_err(dev, "failed to evaluate _DSM\n"); + return -EIO; + } + + if (obj->type == ACPI_TYPE_INTEGER) + ret = (obj->integer.value == 0) ? 0 : -ETIMEDOUT; + dev_dbg(dev, "dwc3_pci_dsm_soft_reset() ret= %d\n", ret); + + ACPI_FREE(obj); + return ret; +} + /** * dwc3_core_soft_reset - Issues core soft reset and PHY reset * @dwc: pointer to our context structure @@ -331,6 +363,11 @@ int dwc3_core_soft_reset(struct dwc3 *dwc) if (dwc->current_dr_role == DWC3_GCTL_PRTCAP_HOST) return 0; + if (dwc->has_dsm_for_softreset) { + dev_dbg(dwc->dev, "calling dwc3_pci_dsm_soft_reset()"); + return dwc3_pci_dsm_soft_reset(dwc->dev); + } + reg = dwc3_readl(dwc->regs, DWC3_DCTL); reg |= DWC3_DCTL_CSFTRST; reg &= ~DWC3_DCTL_RUN_STOP; @@ -1849,6 +1886,9 @@ static void dwc3_get_properties(struct dwc3 *dwc) dwc->dis_split_quirk = device_property_read_bool(dev, "snps,dis-split-quirk"); + dwc->has_dsm_for_softreset = device_property_read_bool(dev, + "snps,has_dsm_for_softreset"); + dwc->lpm_nyet_threshold = lpm_nyet_threshold; dwc->tx_de_emphasis = tx_de_emphasis; diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 45757169b672f..0292298faec7b 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -1166,6 +1166,7 @@ struct dwc3_glue_ops { * @suspended: set to track suspend event due to U3/L2. * @susphy_state: state of DWC3_GUSB2PHYCFG_SUSPHY + DWC3_GUSB3PIPECTL_SUSPHY * before PM suspend. + * @has_dsm_for_softreset: set if we want to use BIOS to do core soft reset * @imod_interval: set the interrupt moderation interval in 250ns * increments or 0 to disable. * @max_cfg_eps: current max number of IN eps used across all USB configs. @@ -1407,6 +1408,8 @@ struct dwc3 { unsigned suspended:1; unsigned susphy_state:1; + unsigned has_dsm_for_softreset:1; + u16 imod_interval; int max_cfg_eps; diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c index 8f5faf632a8bf..0e81a79210612 100644 --- a/drivers/usb/dwc3/dwc3-pci.c +++ b/drivers/usb/dwc3/dwc3-pci.c @@ -143,6 +143,13 @@ static const struct property_entry dwc3_pci_intel_phy_charger_detect_properties[ {} }; +static const struct property_entry dwc3_pci_intel_bxt_properties[] = { + PROPERTY_ENTRY_STRING("dr_mode", "peripheral"), + PROPERTY_ENTRY_BOOL("snps,has_dsm_for_softreset"), + PROPERTY_ENTRY_BOOL("linux,sysdev_is_parent"), + {} +}; + static const struct property_entry dwc3_pci_intel_byt_properties[] = { PROPERTY_ENTRY_STRING("dr_mode", "peripheral"), PROPERTY_ENTRY_BOOL("snps,dis_u2_susphy_quirk"), @@ -206,6 +213,10 @@ static const struct software_node dwc3_pci_intel_phy_charger_detect_swnode = { .properties = dwc3_pci_intel_phy_charger_detect_properties, }; +static const struct software_node dwc3_pci_intel_bxt_swnode = { + .properties = dwc3_pci_intel_bxt_properties, +}; + static const struct software_node dwc3_pci_intel_byt_swnode = { .properties = dwc3_pci_intel_byt_properties, }; @@ -415,10 +426,10 @@ static void dwc3_pci_remove(struct pci_dev *pci) static const struct pci_device_id dwc3_pci_id_table[] = { { PCI_DEVICE_DATA(INTEL, CMLLP, &dwc3_pci_intel_swnode) }, { PCI_DEVICE_DATA(INTEL, CMLH, &dwc3_pci_intel_swnode) }, - { PCI_DEVICE_DATA(INTEL, BXT, &dwc3_pci_intel_swnode) }, + { PCI_DEVICE_DATA(INTEL, BXT, &dwc3_pci_intel_bxt_swnode) }, { PCI_DEVICE_DATA(INTEL, BYT, &dwc3_pci_intel_byt_swnode) }, { PCI_DEVICE_DATA(INTEL, MRFLD, &dwc3_pci_intel_mrfld_swnode) }, - { PCI_DEVICE_DATA(INTEL, BXT_M, &dwc3_pci_intel_swnode) }, + { PCI_DEVICE_DATA(INTEL, BXT_M, &dwc3_pci_intel_bxt_swnode) }, { PCI_DEVICE_DATA(INTEL, BSW, &dwc3_pci_intel_swnode) }, { PCI_DEVICE_DATA(INTEL, GLK, &dwc3_pci_intel_swnode) }, { PCI_DEVICE_DATA(INTEL, ICLLP, &dwc3_pci_intel_swnode) }, @@ -430,7 +441,7 @@ static const struct pci_device_id dwc3_pci_id_table[] = { { PCI_DEVICE_DATA(INTEL, JSP, &dwc3_pci_intel_swnode) }, { PCI_DEVICE_DATA(INTEL, ADL_PCH, &dwc3_pci_intel_swnode) }, { PCI_DEVICE_DATA(INTEL, ADLN_PCH, &dwc3_pci_intel_swnode) }, - { PCI_DEVICE_DATA(INTEL, APL, &dwc3_pci_intel_swnode) }, + { PCI_DEVICE_DATA(INTEL, APL, &dwc3_pci_intel_bxt_swnode) }, { PCI_DEVICE_DATA(INTEL, NVLS_PCH, &dwc3_pci_intel_swnode) }, { PCI_DEVICE_DATA(INTEL, ARLH_PCH, &dwc3_pci_intel_swnode) }, { PCI_DEVICE_DATA(INTEL, RPLS, &dwc3_pci_intel_swnode) }, From 85dc2838e6ff6e8b10429fe85f2468553e6f0185 Mon Sep 17 00:00:00 2001 From: Chaitanya Vadrevu Date: Mon, 24 Mar 2025 10:47:55 -0500 Subject: [PATCH 012/100] usb: dwc3: Remove mdelay to fix USBLAN issue cRIO-9041, cRIO-9034 and possibly other devices' USBLAN does not work with this mdelay in place when connected to Windows host. Signed-off-by: Chaitanya Vadrevu (cherry picked from commit 29ff169fdb326ff11dba29364b1cd7b6d2530c89) Signed-off-by: Gratian Crisan --- drivers/usb/dwc3/gadget.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 17eebb60900bf..a2915d1edbb99 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -442,9 +442,17 @@ int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned int cmd, dwc3_gadget_ep_get_transfer_index(dep); } + /* + * mdelay below breaks USBLAN in cRIO-9041 and other devices. Commenting + * out instead of removing so git doesn't drop this silently during + * upstream merges if upstream moves this to a different place in + * future. + * + * AB#2419039 + */ if (DWC3_DEPCMD_CMD(cmd) == DWC3_DEPCMD_ENDTRANSFER && !(cmd & DWC3_DEPCMD_CMDIOC)) - mdelay(1); + ; /* mdelay(1); */ if (saved_config) { reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); From 548465cac5e1078b721285ba4f0f74658962862b Mon Sep 17 00:00:00 2001 From: Gratian Crisan Date: Mon, 18 Mar 2024 16:41:28 -0500 Subject: [PATCH 013/100] efivarfs: skip efivar_query_variable_info on PREEMPT_RT Commit d86ff3333cb1 ("efivarfs: expose used and total size") introduced the ability to query the efivars file system size with utilities like 'df'. Unfortunately this introduces large latency spikes in real-time tasks on PREEMPT_RT configured kernels. Skip the EFI run-time services query for EFI_RT_SUPPORTED_QUERY_VARIABLE_INFO if on PREEMPT_RT. The 'df' functionality is lost but the rest of the efivars run-time services continue to work. Upstream status: Inappropriate (configuration) - upstream sets EFI_DISABLE_RUNTIME to 'default y if PREEMPT_RT' thus avoiding the problem entirely. - NILRT sets EFI_DISABLE_RUNTIME to 'n' and uses EFI run-time services to access EFI vars at run-time.[1][2] [1] https://review-board.natinst.com/r/271066 [2] https://review-board.natinst.com/r/303906 Signed-off-by: Gratian Crisan --- fs/efivarfs/super.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/efivarfs/super.c b/fs/efivarfs/super.c index 6de97565d5f78..b6a8ad87ae113 100644 --- a/fs/efivarfs/super.c +++ b/fs/efivarfs/super.c @@ -88,7 +88,8 @@ static int efivarfs_statfs(struct dentry *dentry, struct kstatfs *buf) /* Some UEFI firmware does not implement QueryVariableInfo() */ storage_space = remaining_space = 0; - if (efi_rt_services_supported(EFI_RT_SUPPORTED_QUERY_VARIABLE_INFO)) { + if (efi_rt_services_supported(EFI_RT_SUPPORTED_QUERY_VARIABLE_INFO) && + !IS_ENABLED(CONFIG_PREEMPT_RT)) { status = efivar_query_variable_info(attr, &storage_space, &remaining_space, &max_variable_size); From b22a57c51a3470bbf57cf65632235ecc71fade08 Mon Sep 17 00:00:00 2001 From: Bill Pittman Date: Mon, 30 Aug 2021 13:34:07 -0500 Subject: [PATCH 014/100] i2c-i801.c: Skip SPD initialization on cRIO-903x The cRIO-903x architecture is sort of special, we do not connect a dimm to the SPD because we use flash instead, but the SPD is still present because the processor expects it. However, enumerating and registering the SPD i2c bus is causing interrupt storms, so for now we skip the registration on all 903x devices. Fixes: 01590f3 ("i2c: i801: Instantiate SPD EEPROMs automatically") Signed-off-by: Bill Pittman Natinst-AZDO-ID: 1573148 (cherry picked from commit 4de019e72df37f49e08f352a835cf5779d57fac2) [cvadrevu: fix trivial conflict with d08cac0a6378c ("i2c: i801: reword according to newest specification")] [cvadrevu: fix minor conflict with 80e56b86b59e7 ("i2c: i801: Simplify class-based client device instantiation")] Signed-off-by: Chaitanya Vadrevu [gratian: fix minor conflict with 4d6d35d3417d ("i2c: smbus: introduce Write Disable-aware SPD instantiating functions")] Signed-off-by: Gratian Crisan --- drivers/i2c/busses/i2c-i801.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 57fbec1259bea..4141ccc070cc0 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -1162,6 +1162,8 @@ static void dmi_check_onboard_devices(const struct dmi_header *dm, void *adap) /* Register optional targets */ static void i801_probe_optional_targets(struct i801_priv *priv) { + const char *product; + /* Only register targets on main SMBus channel */ if (priv->features & FEATURE_IDF) return; @@ -1178,11 +1180,16 @@ static void i801_probe_optional_targets(struct i801_priv *priv) if (dmi_name_in_vendors("FUJITSU")) dmi_walk(dmi_check_onboard_devices, &priv->adapter); - /* Instantiate SPD EEPROMs unless the SMBus is multiplexed */ + /* Instantiate SPD EEPROMs unless the SMBus is multiplexed or it's a cRIO-903x */ + product = dmi_get_system_info(DMI_PRODUCT_NAME); + if(strncmp(product, "NI cRIO-903", 11)) { #ifdef CONFIG_I2C_I801_MUX - if (!priv->mux_pdev) + if (!priv->mux_pdev) #endif - i2c_register_spd_write_enable(&priv->adapter); + i2c_register_spd_write_enable(&priv->adapter); + } else { + dev_info(&priv->adapter.dev, "Found %s, skipping SPD registration.", product); + } } #else static void __init input_apanel_init(void) {} From 6c83dd7f882195691f4875f363ce10aa9f2e8e26 Mon Sep 17 00:00:00 2001 From: Jeff Westfahl Date: Mon, 16 Dec 2013 10:33:02 -0600 Subject: [PATCH 015/100] nirtfeatures: Added NI RT features driver Added an NI RT features driver. This is an ACPI device that exposes LEDs, switches, and other hardware features of the Smasher controllers. Not all of the proposed features of the device work as expected, and some features may be removed in the future. Development work on this device by the hardware team is currently not a high priority. These issues will be addressed once the hardware team gets back to this device. Signed-off-by: Jeff Westfahl [gratian: fix conflict with 7a6ff4c4cbc3 ("misc: hisi_hikey_usb: Driver to support onboard USB gpio hub on Hikey960")] Signed-off-by: Gratian Crisan [gratian: fix conflict with bb3b6552a5b0 ("staging: hikey9xx: split hi6421v600 irq into a separate driver")] Signed-off-by: Gratian Crisan [gratian: fix conflict with f396ededbd8b ("misc: open-dice: Add driver to expose DICE data to userspace")] Signed-off-by: Gratian Crisan [gratian: fix trivial conflict with 6c93c6f3bad4 ("misc: Add a mechanism to detect stalls on guest vCPUs")] Signed-off-by: Gratian Crisan [gratian: fix trivial conflict with 393fc2f5948f ("misc: microchip: pci1xxxx: load auxiliary bus driver for the PIO function in the multi-function endpoint of pci1xxxx device.")] Signed-off-by: Gratian Crisan [mpeterse: fix trivial conflicts with new config flags] [mpeterse: change return type of nirtfeatures_acpi_remove due to 6c0eb5ba3500] Signed-off-by: Mike Petersen [cvadrevu: fix trivial conflict with b9873755a6c8c ("misc: Add Nitro Secure Module driver")] [cvadrevu: fix trivial conflict with 5f67eef6dff39 ("misc: mrvl-cn10k-dpi: add Octeon CN10K DPI administrative driver")] Signed-off-by: Chaitanya Vadrevu [gratian: fix trivial conflicts due to upstream additions to Kconfig/Makefile] Signed-off-by: Gratian Crisan --- drivers/misc/Kconfig | 31 ++ drivers/misc/Makefile | 1 + drivers/misc/nirtfeatures.c | 886 ++++++++++++++++++++++++++++++++++++ 3 files changed, 918 insertions(+) create mode 100644 drivers/misc/nirtfeatures.c diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index b9c11f67315f0..fa58f425f064c 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -644,6 +644,37 @@ config MCHP_LAN966X_PCI - lan966x-miim (MDIO_MSCC_MIIM) - lan966x-switch (LAN966X_SWITCH) +config NI_RT_FEATURES + bool "NI 903x/913x support" + depends on X86 && ACPI + help + This driver exposes LEDs and other features of NI 903x/913x Real-Time + controllers. + + If unsure, say N (but it's safe to say "Y"). + +config NI_LED_PREFIX + string "NI 903x/913x LED prefix" + depends on NI_RT_FEATURES + default "nizynqcpld" + help + This option defines the base name of LEDs exposed by NI_RT_FEATURES. + The default value maintains backwards compatibility with user-space + software that was originally written for ARM (Zynq) hardware. + + If unsure, use the default. + +config NI_HW_REBOOT + bool "Hardware reboot for NI 903x/913x" + depends on NI_RT_FEATURES && X86_64 + default n + help + If enabled, when rebooting an NI 903x/913x, on-board hardware will + be used to reset the system. If not enabled, the controller will do + a normal ACPI reset. + + If unsure, say N. + source "drivers/misc/c2port/Kconfig" source "drivers/misc/eeprom/Kconfig" source "drivers/misc/cb710/Kconfig" diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index b32a2597d2467..21f053b719f3f 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -75,3 +75,4 @@ obj-$(CONFIG_MCHP_LAN966X_PCI) += lan966x-pci.o obj-y += keba/ obj-y += amd-sbi/ obj-$(CONFIG_MISC_RP1) += rp1/ +obj-$(CONFIG_NI_RT_FEATURES) += nirtfeatures.o diff --git a/drivers/misc/nirtfeatures.c b/drivers/misc/nirtfeatures.c new file mode 100644 index 0000000000000..40fb9893642e5 --- /dev/null +++ b/drivers/misc/nirtfeatures.c @@ -0,0 +1,886 @@ +/* + * Copyright (C) 2013 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 + +#ifdef CONFIG_NI_HW_REBOOT +#include +#endif + +#define MODULE_NAME "nirtfeatures" + +/* Register addresses */ + +#define NIRTF_SIGNATURE 0x00 +#define NIRTF_YEAR 0x01 +#define NIRTF_MONTH 0x02 +#define NIRTF_DAY 0x03 +#define NIRTF_HOUR 0x04 +#define NIRTF_MINUTE 0x05 +#define NIRTF_SCRATCH 0x06 +#define NIRTF_BPINFO 0x07 +#define NIRTF_RAIL_STATUS1 0x08 +#define NIRTF_RAIL_STATUS2 0x09 +#define NIRTF_RESET 0x10 +#define NIRTF_RESET_SOURCE 0x11 +#define NIRTF_PROCESSOR_MODE 0x12 +#define NIRTF_SYSTEM_LEDS 0x20 +#define NIRTF_STATUS_LED_SHIFT1 0x21 +#define NIRTF_STATUS_LED_SHIFT0 0x22 +#define NIRTF_RT_LEDS 0x23 + +#define NIRTF_IO_SIZE 0x40 + +/* Register values */ + +#define NIRTF_BPINFO_ID_MASK 0x07 + +#define NIRTF_BPINFO_ID_MANHATTAN 0 +#define NIRTF_BPINFO_ID_HAMMERHEAD 1 + +#define NIRTF_RESET_RESET_PROCESSOR 0x80 + +#define NIRTF_RESET_SOURCE_SOFT_OFF 0x20 +#define NIRTF_RESET_SOURCE_SOFTWARE 0x10 +#define NIRTF_RESET_SOURCE_WATCHDOG 0x08 +#define NIRTF_RESET_SOURCE_FPGA 0x04 +#define NIRTF_RESET_SOURCE_PROCESSOR 0x02 +#define NIRTF_RESET_SOURCE_BUTTON 0x01 + +#define NIRTF_PROCESSOR_MODE_HARD_BOOT_N 0x20 +#define NIRTF_PROCESSOR_MODE_NO_FPGA 0x10 +#define NIRTF_PROCESSOR_MODE_RECOVERY 0x08 +#define NIRTF_PROCESSOR_MODE_CONSOLE_OUT 0x04 +#define NIRTF_PROCESSOR_MODE_IP_RESET 0x02 +#define NIRTF_PROCESSOR_MODE_SAFE 0x01 + +#define NIRTF_SYSTEM_LEDS_STATUS_RED 0x08 +#define NIRTF_SYSTEM_LEDS_STATUS_YELLOW 0x04 +#define NIRTF_SYSTEM_LEDS_POWER_GREEN 0x02 +#define NIRTF_SYSTEM_LEDS_POWER_YELLOW 0x01 + +#define NIRTF_RT_LEDS_USER2_GREEN 0x08 +#define NIRTF_RT_LEDS_USER2_YELLOW 0x04 +#define NIRTF_RT_LEDS_USER1_GREEN 0x02 +#define NIRTF_RT_LEDS_USER1_YELLOW 0x01 + +/* Structures */ + +struct nirtfeatures { + struct acpi_device *acpi_device; + u16 io_base; + u16 io_size; + spinlock_t lock; + u8 revision[5]; + const char *bpstring; + struct nirtfeatures_led *extra_leds; + unsigned num_extra_leds; +}; + +struct nirtfeatures_led { + struct led_classdev cdev; + struct nirtfeatures *nirtfeatures; + u8 address; + u8 mask; + u8 pattern_hi_addr; + u8 pattern_lo_addr; +}; + +/* sysfs files */ + +static ssize_t nirtfeatures_revision_get(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct acpi_device *acpi_device = to_acpi_device(dev); + struct nirtfeatures *nirtfeatures = acpi_device->driver_data; + + return sprintf(buf, "20%02X/%02X/%02X %02X:%02X\n", + nirtfeatures->revision[0], nirtfeatures->revision[1], + nirtfeatures->revision[2], nirtfeatures->revision[3], + nirtfeatures->revision[4]); +} + +static DEVICE_ATTR(revision, S_IRUGO, nirtfeatures_revision_get, NULL); + +static ssize_t nirtfeatures_scratch_get(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct acpi_device *acpi_device = to_acpi_device(dev); + struct nirtfeatures *nirtfeatures = acpi_device->driver_data; + u8 data; + + data = inb(nirtfeatures->io_base + NIRTF_SCRATCH); + + return sprintf(buf, "%02x\n", data); +} + +static ssize_t nirtfeatures_scratch_set(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct acpi_device *acpi_device = to_acpi_device(dev); + struct nirtfeatures *nirtfeatures = acpi_device->driver_data; + unsigned long tmp; + u8 data; + + if (kstrtoul(buf, 0, &tmp) || (tmp > 0xFF)) + return -EINVAL; + + data = (u8)tmp; + + outb(data, nirtfeatures->io_base + NIRTF_SCRATCH); + + return count; +} + +static DEVICE_ATTR(scratch, S_IRUGO|S_IWUSR, nirtfeatures_scratch_get, + nirtfeatures_scratch_set); + +static ssize_t nirtfeatures_backplane_id_get(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct acpi_device *acpi_device = to_acpi_device(dev); + struct nirtfeatures *nirtfeatures = acpi_device->driver_data; + + return sprintf(buf, "%s\n", nirtfeatures->bpstring); +} + +static DEVICE_ATTR(backplane_id, S_IRUGO, nirtfeatures_backplane_id_get, NULL); + +static ssize_t nirtfeatures_railstatus1_get(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct acpi_device *acpi_device = to_acpi_device(dev); + struct nirtfeatures *nirtfeatures = acpi_device->driver_data; + u8 data; + + data = inb(nirtfeatures->io_base + NIRTF_RAIL_STATUS1); + + return sprintf(buf, "%02x\n", data); +} + +static DEVICE_ATTR(railstatus1, S_IRUGO, nirtfeatures_railstatus1_get, NULL); + +static ssize_t nirtfeatures_railstatus2_get(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct acpi_device *acpi_device = to_acpi_device(dev); + struct nirtfeatures *nirtfeatures = acpi_device->driver_data; + u8 data; + + data = inb(nirtfeatures->io_base + NIRTF_RAIL_STATUS2); + + return sprintf(buf, "%02x\n", data); +} + +static DEVICE_ATTR(railstatus2, S_IRUGO, nirtfeatures_railstatus2_get, NULL); + +static ssize_t nirtfeatures_reset_set(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct acpi_device *acpi_device = to_acpi_device(dev); + struct nirtfeatures *nirtfeatures = acpi_device->driver_data; + + if (strcmp(buf, "1")) + return -EINVAL; + + outb(NIRTF_RESET_RESET_PROCESSOR, nirtfeatures->io_base + NIRTF_RESET); + + return count; +} + +static DEVICE_ATTR(reset, S_IWUSR, NULL, nirtfeatures_reset_set); + +static ssize_t nirtfeatures_reset_source_get(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct acpi_device *acpi_device = to_acpi_device(dev); + struct nirtfeatures *nirtfeatures = acpi_device->driver_data; + u8 data; + const char *reset_source; + + data = inb(nirtfeatures->io_base + NIRTF_PROCESSOR_MODE); + + data &= NIRTF_PROCESSOR_MODE_HARD_BOOT_N; + + /* Power-on reset status is in a different register from the other reset + sources, we must check it first. */ + if (!data) { + reset_source = "power-on reset"; + } else { + data = inb(nirtfeatures->io_base + NIRTF_RESET_SOURCE); + + switch (data) { + case NIRTF_RESET_SOURCE_SOFT_OFF: + reset_source = "soft off button"; + break; + case NIRTF_RESET_SOURCE_SOFTWARE: + reset_source = "software"; + break; + case NIRTF_RESET_SOURCE_WATCHDOG: + reset_source = "watchdog"; + break; + case NIRTF_RESET_SOURCE_FPGA: + reset_source = "FPGA"; + break; + case NIRTF_RESET_SOURCE_PROCESSOR: + reset_source = "processor"; + break; + case NIRTF_RESET_SOURCE_BUTTON: + reset_source = "reset button"; + break; + default: + dev_err(&nirtfeatures->acpi_device->dev, + "Unrecognized reset source 0x%02X\n", + data); + reset_source = "unknown"; + break; + } + } + + return sprintf(buf, "%s\n", reset_source); +} + +static DEVICE_ATTR(reset_source, S_IRUGO, nirtfeatures_reset_source_get, NULL); + +static ssize_t nirtfeatures_hard_boot_get(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct acpi_device *acpi_device = to_acpi_device(dev); + struct nirtfeatures *nirtfeatures = acpi_device->driver_data; + u8 data; + + data = inb(nirtfeatures->io_base + NIRTF_PROCESSOR_MODE); + + data &= NIRTF_PROCESSOR_MODE_HARD_BOOT_N; + + return sprintf(buf, "%s\n", data ? "soft reset" : "power-on reset"); +} + +static ssize_t nirtfeatures_hard_boot_set(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct acpi_device *acpi_device = to_acpi_device(dev); + struct nirtfeatures *nirtfeatures = acpi_device->driver_data; + u8 data; + + if (strcmp(buf, "1")) + return -EINVAL; + + spin_lock(&nirtfeatures->lock); + + data = inb(nirtfeatures->io_base + NIRTF_PROCESSOR_MODE); + + data |= NIRTF_PROCESSOR_MODE_HARD_BOOT_N; + + outb(data, nirtfeatures->io_base + NIRTF_PROCESSOR_MODE); + + spin_unlock(&nirtfeatures->lock); + + return count; +} + +static DEVICE_ATTR(hard_boot, S_IRUGO|S_IWUSR, nirtfeatures_hard_boot_get, + nirtfeatures_hard_boot_set); + +static ssize_t nirtfeatures_no_fpga_get(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct acpi_device *acpi_device = to_acpi_device(dev); + struct nirtfeatures *nirtfeatures = acpi_device->driver_data; + u8 data; + + data = inb(nirtfeatures->io_base + NIRTF_PROCESSOR_MODE); + + data &= NIRTF_PROCESSOR_MODE_NO_FPGA; + + return sprintf(buf, "%u\n", !!data); +} + +static ssize_t nirtfeatures_no_fpga_set(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct acpi_device *acpi_device = to_acpi_device(dev); + struct nirtfeatures *nirtfeatures = acpi_device->driver_data; + unsigned long tmp; + u8 data; + + if (kstrtoul(buf, 0, &tmp) || (tmp > 1)) + return -EINVAL; + + spin_lock(&nirtfeatures->lock); + + data = inb(nirtfeatures->io_base + NIRTF_PROCESSOR_MODE); + + if (tmp) + data |= NIRTF_PROCESSOR_MODE_NO_FPGA; + else + data &= ~NIRTF_PROCESSOR_MODE_NO_FPGA; + + outb(data, nirtfeatures->io_base + NIRTF_PROCESSOR_MODE); + + spin_unlock(&nirtfeatures->lock); + + return count; +} + +static DEVICE_ATTR(no_fpga, S_IRUGO|S_IWUSR, nirtfeatures_no_fpga_get, + nirtfeatures_no_fpga_set); + +static ssize_t nirtfeatures_recovery_mode_get(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct acpi_device *acpi_device = to_acpi_device(dev); + struct nirtfeatures *nirtfeatures = acpi_device->driver_data; + u8 data; + + data = inb(nirtfeatures->io_base + NIRTF_PROCESSOR_MODE); + + data &= NIRTF_PROCESSOR_MODE_RECOVERY; + + return sprintf(buf, "%u\n", !!data); +} + +static ssize_t nirtfeatures_recovery_mode_set(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct acpi_device *acpi_device = to_acpi_device(dev); + struct nirtfeatures *nirtfeatures = acpi_device->driver_data; + unsigned long tmp; + u8 data; + + if (kstrtoul(buf, 0, &tmp) || (tmp > 1)) + return -EINVAL; + + spin_lock(&nirtfeatures->lock); + + data = inb(nirtfeatures->io_base + NIRTF_PROCESSOR_MODE); + + if (tmp) + data |= NIRTF_PROCESSOR_MODE_RECOVERY; + else + data &= ~NIRTF_PROCESSOR_MODE_RECOVERY; + + outb(data, nirtfeatures->io_base + NIRTF_PROCESSOR_MODE); + + spin_unlock(&nirtfeatures->lock); + + return count; +} + +static DEVICE_ATTR(recovery_mode, S_IRUGO|S_IWUSR, + nirtfeatures_recovery_mode_get, nirtfeatures_recovery_mode_set); + +static ssize_t nirtfeatures_console_out_get(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct acpi_device *acpi_device = to_acpi_device(dev); + struct nirtfeatures *nirtfeatures = acpi_device->driver_data; + u8 data; + + data = inb(nirtfeatures->io_base + NIRTF_PROCESSOR_MODE); + + data &= NIRTF_PROCESSOR_MODE_CONSOLE_OUT; + + return sprintf(buf, "%u\n", !!data); +} + +static DEVICE_ATTR(console_out, S_IRUGO, nirtfeatures_console_out_get, NULL); + +static ssize_t nirtfeatures_ip_reset_get(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct acpi_device *acpi_device = to_acpi_device(dev); + struct nirtfeatures *nirtfeatures = acpi_device->driver_data; + u8 data; + + data = inb(nirtfeatures->io_base + NIRTF_PROCESSOR_MODE); + + data &= NIRTF_PROCESSOR_MODE_IP_RESET; + + return sprintf(buf, "%u\n", !!data); +} + +static DEVICE_ATTR(ip_reset, S_IRUGO, nirtfeatures_ip_reset_get, NULL); + +static ssize_t nirtfeatures_safe_mode_get(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct acpi_device *acpi_device = to_acpi_device(dev); + struct nirtfeatures *nirtfeatures = acpi_device->driver_data; + u8 data; + + data = inb(nirtfeatures->io_base + NIRTF_PROCESSOR_MODE); + + data &= NIRTF_PROCESSOR_MODE_SAFE; + + return sprintf(buf, "%u\n", !!data); +} + +static DEVICE_ATTR(safe_mode, S_IRUGO, nirtfeatures_safe_mode_get, NULL); + +static ssize_t nirtfeatures_register_dump_get(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct acpi_device *acpi_device = to_acpi_device(dev); + struct nirtfeatures *nirtfeatures = acpi_device->driver_data; + u8 signature, year, month, day, hour, minute, scratch, bpinfo; + u8 railstatus1, railstatus2, reset, reset_source, processor_mode; + u8 system_leds, status_led_shift1, status_led_shift0, rt_leds; + + signature = inb(nirtfeatures->io_base + NIRTF_SIGNATURE); + year = inb(nirtfeatures->io_base + NIRTF_YEAR); + month = inb(nirtfeatures->io_base + NIRTF_MONTH); + day = inb(nirtfeatures->io_base + NIRTF_DAY); + hour = inb(nirtfeatures->io_base + NIRTF_HOUR); + minute = inb(nirtfeatures->io_base + NIRTF_MINUTE); + scratch = inb(nirtfeatures->io_base + NIRTF_SCRATCH); + bpinfo = inb(nirtfeatures->io_base + NIRTF_BPINFO); + railstatus1 = inb(nirtfeatures->io_base + NIRTF_RAIL_STATUS1); + railstatus2 = inb(nirtfeatures->io_base + NIRTF_RAIL_STATUS2); + reset = inb(nirtfeatures->io_base + NIRTF_RESET); + reset_source = inb(nirtfeatures->io_base + NIRTF_RESET_SOURCE); + processor_mode = inb(nirtfeatures->io_base + NIRTF_PROCESSOR_MODE); + system_leds = inb(nirtfeatures->io_base + NIRTF_SYSTEM_LEDS); + status_led_shift1 = + inb(nirtfeatures->io_base + NIRTF_STATUS_LED_SHIFT1); + status_led_shift0 = + inb(nirtfeatures->io_base + NIRTF_STATUS_LED_SHIFT0); + rt_leds = inb(nirtfeatures->io_base + NIRTF_RT_LEDS); + + return sprintf(buf, + "Signature: 0x%02X\n" + "Year: 0x%02X\n" + "Month: 0x%02X\n" + "Day: 0x%02X\n" + "Hour: 0x%02X\n" + "Minute: 0x%02X\n" + "Scratch: 0x%02X\n" + "BPInfo: 0x%02X\n" + "Rail status 1: 0x%02X\n" + "Rail status 2: 0x%02X\n" + "Reset: 0x%02X\n" + "Reset source: 0x%02X\n" + "Processor mode: 0x%02X\n" + "System LEDs: 0x%02X\n" + "Status LED shift 1: 0x%02X\n" + "Status LED shift 0: 0x%02X\n" + "RT LEDs: 0x%02X\n", + signature, year, month, day, hour, minute, scratch, + bpinfo, railstatus1, railstatus2, reset, reset_source, + processor_mode, system_leds, status_led_shift1, + status_led_shift0, rt_leds); +} + +static DEVICE_ATTR(register_dump, S_IRUGO, nirtfeatures_register_dump_get, + NULL); + +static const struct attribute *nirtfeatures_attrs[] = { + &dev_attr_revision.attr, + &dev_attr_scratch.attr, + &dev_attr_backplane_id.attr, + &dev_attr_railstatus1.attr, + &dev_attr_railstatus2.attr, + &dev_attr_reset.attr, + &dev_attr_reset_source.attr, + &dev_attr_hard_boot.attr, + &dev_attr_no_fpga.attr, + &dev_attr_recovery_mode.attr, + &dev_attr_console_out.attr, + &dev_attr_ip_reset.attr, + &dev_attr_safe_mode.attr, + &dev_attr_register_dump.attr, + NULL +}; + +/* LEDs */ + +static void nirtfeatures_led_brightness_set(struct led_classdev *led_cdev, + enum led_brightness brightness) +{ + struct nirtfeatures_led *led = (struct nirtfeatures_led *)led_cdev; + u8 data; + bool on; + u16 pattern; + + on = !!brightness; + pattern = brightness; + + spin_lock(&led->nirtfeatures->lock); + + data = inb(led->nirtfeatures->io_base + led->address); + + data &= ~led->mask; + + if (on) + data |= led->mask; + + outb(data, led->nirtfeatures->io_base + led->address); + + if (led->pattern_hi_addr && led->pattern_lo_addr) { + /* Write the high byte first. */ + outb(pattern >> 8, + led->nirtfeatures->io_base + led->pattern_hi_addr); + outb(pattern & 0xFF, + led->nirtfeatures->io_base + led->pattern_lo_addr); + } + + spin_unlock(&led->nirtfeatures->lock); +} + +static enum led_brightness +nirtfeatures_led_brightness_get(struct led_classdev *led_cdev) +{ + struct nirtfeatures_led *led = (struct nirtfeatures_led *)led_cdev; + u8 data; + + data = inb(led->nirtfeatures->io_base + led->address); + + /* For the yellow status LED, the blink pattern used for brightness + on write is write-only, so we just return on/off for all LEDs. */ + return (data & led->mask) ? LED_FULL : LED_OFF; +} + +static struct nirtfeatures_led nirtfeatures_leds_common[] = { + { + { + .name = CONFIG_NI_LED_PREFIX ":user1:green", + }, + .address = NIRTF_RT_LEDS, + .mask = NIRTF_RT_LEDS_USER1_GREEN, + }, + { + { + .name = CONFIG_NI_LED_PREFIX ":user1:yellow", + }, + .address = NIRTF_RT_LEDS, + .mask = NIRTF_RT_LEDS_USER1_YELLOW, + }, + { + { + .name = CONFIG_NI_LED_PREFIX ":status:red", + }, + .address = NIRTF_SYSTEM_LEDS, + .mask = NIRTF_SYSTEM_LEDS_STATUS_RED, + }, + { + { + .name = CONFIG_NI_LED_PREFIX ":status:yellow", + .max_brightness = 0xFFFF, + }, + .address = NIRTF_SYSTEM_LEDS, + .mask = NIRTF_SYSTEM_LEDS_STATUS_YELLOW, + .pattern_hi_addr = NIRTF_STATUS_LED_SHIFT1, + .pattern_lo_addr = NIRTF_STATUS_LED_SHIFT0, + }, + { + { + .name = CONFIG_NI_LED_PREFIX ":power:green", + }, + .address = NIRTF_SYSTEM_LEDS, + .mask = NIRTF_SYSTEM_LEDS_POWER_GREEN, + }, + { + { + .name = CONFIG_NI_LED_PREFIX ":power:yellow", + }, + .address = NIRTF_SYSTEM_LEDS, + .mask = NIRTF_SYSTEM_LEDS_POWER_YELLOW, + }, +}; + +static struct nirtfeatures_led nirtfeatures_leds_cdaq[] = { + { + { + .name = CONFIG_NI_LED_PREFIX ":user2:green", + }, + .address = NIRTF_RT_LEDS, + .mask = NIRTF_RT_LEDS_USER2_GREEN, + }, + { + { + .name = CONFIG_NI_LED_PREFIX ":user2:yellow", + }, + .address = NIRTF_RT_LEDS, + .mask = NIRTF_RT_LEDS_USER2_YELLOW, + }, +}; + +static int nirtfeatures_create_leds(struct nirtfeatures *nirtfeatures) +{ + int i; + int err; + + for (i = 0; i < ARRAY_SIZE(nirtfeatures_leds_common); ++i) { + + nirtfeatures_leds_common[i].nirtfeatures = nirtfeatures; + + if (0 == nirtfeatures_leds_common[i].cdev.max_brightness) + nirtfeatures_leds_common[i].cdev.max_brightness = 1; + + nirtfeatures_leds_common[i].cdev.brightness_set = + nirtfeatures_led_brightness_set; + + nirtfeatures_leds_common[i].cdev.brightness_get = + nirtfeatures_led_brightness_get; + + err = led_classdev_register(&nirtfeatures->acpi_device->dev, + &nirtfeatures_leds_common[i].cdev); + if (err) + return err; + } + + for (i = 0; i < nirtfeatures->num_extra_leds; ++i) { + + nirtfeatures->extra_leds[i].nirtfeatures = nirtfeatures; + + if (0 == nirtfeatures->extra_leds[i].cdev.max_brightness) + nirtfeatures->extra_leds[i].cdev.max_brightness = 1; + + nirtfeatures->extra_leds[i].cdev.brightness_set = + nirtfeatures_led_brightness_set; + + nirtfeatures->extra_leds[i].cdev.brightness_get = + nirtfeatures_led_brightness_get; + + err = led_classdev_register(&nirtfeatures->acpi_device->dev, + &nirtfeatures->extra_leds[i].cdev); + if (err) + return err; + } + + return 0; +} + +static void nirtfeatures_remove_leds(struct nirtfeatures *nirtfeatures) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(nirtfeatures_leds_common); ++i) + led_classdev_unregister(&nirtfeatures_leds_common[i].cdev); + + for (i = 0; i < nirtfeatures->num_extra_leds; ++i) + led_classdev_unregister(&nirtfeatures->extra_leds[i].cdev); +} + +/* Board specific reboot fixup */ + +#ifdef CONFIG_NI_HW_REBOOT + +static u16 mach_reboot_fixup_io_base; + +void mach_reboot_fixups(void) +{ + int i; + + if (mach_reboot_fixup_io_base) + for (i = 0; i < 10; ++i) { + outb(NIRTF_RESET_RESET_PROCESSOR, + mach_reboot_fixup_io_base + NIRTF_RESET); + udelay(100); + } +} + +#endif + +/* ACPI driver */ + +static acpi_status nirtfeatures_resources(struct acpi_resource *res, void *data) +{ + struct nirtfeatures *nirtfeatures = data; + + switch (res->type) { + case ACPI_RESOURCE_TYPE_IO: + if ((nirtfeatures->io_base != 0) || + (nirtfeatures->io_size != 0)) { + dev_err(&nirtfeatures->acpi_device->dev, + "too many IO resources\n"); + return AE_ERROR; + } + + nirtfeatures->io_base = res->data.io.minimum; + nirtfeatures->io_size = res->data.io.address_length; + + return AE_OK; + + case ACPI_RESOURCE_TYPE_END_TAG: + return AE_OK; + + default: + dev_err(&nirtfeatures->acpi_device->dev, + "unsupported resource type %u\n", + res->type); + return AE_ERROR; + } + + return AE_OK; +} + +static void nirtfeatures_acpi_remove(struct acpi_device *device) +{ + struct nirtfeatures *nirtfeatures = device->driver_data; + + nirtfeatures_remove_leds(nirtfeatures); + + sysfs_remove_files(&nirtfeatures->acpi_device->dev.kobj, + nirtfeatures_attrs); + + if ((nirtfeatures->io_base != 0) && + (nirtfeatures->io_size == NIRTF_IO_SIZE)) + release_region(nirtfeatures->io_base, nirtfeatures->io_size); + + device->driver_data = NULL; + + kfree(nirtfeatures); +} + +static int nirtfeatures_acpi_add(struct acpi_device *device) +{ + struct nirtfeatures *nirtfeatures; + acpi_status acpi_ret; + u8 bpinfo; + int err; + + nirtfeatures = kzalloc(sizeof(*nirtfeatures), GFP_KERNEL); + + if (!nirtfeatures) + return -ENOMEM; + + device->driver_data = nirtfeatures; + + nirtfeatures->acpi_device = device; + + acpi_ret = acpi_walk_resources(device->handle, METHOD_NAME__CRS, + nirtfeatures_resources, nirtfeatures); + + if (ACPI_FAILURE(acpi_ret) || + (nirtfeatures->io_base == 0) || + (nirtfeatures->io_size != NIRTF_IO_SIZE)) { + nirtfeatures_acpi_remove(device); + return -ENODEV; + } + + if (!request_region(nirtfeatures->io_base, nirtfeatures->io_size, + MODULE_NAME)) { + nirtfeatures_acpi_remove(device); + return -EBUSY; + } + +#ifdef CONFIG_NI_HW_REBOOT + mach_reboot_fixup_io_base = nirtfeatures->io_base; + reboot_type = BOOT_KBD; +#endif + + bpinfo = inb(nirtfeatures->io_base + NIRTF_BPINFO); + + bpinfo &= NIRTF_BPINFO_ID_MASK; + + switch (bpinfo) { + case NIRTF_BPINFO_ID_MANHATTAN: + nirtfeatures->bpstring = "Manhattan"; + break; + case NIRTF_BPINFO_ID_HAMMERHEAD: + nirtfeatures->bpstring = "Hammerhead"; + nirtfeatures->extra_leds = nirtfeatures_leds_cdaq; + nirtfeatures->num_extra_leds = + ARRAY_SIZE(nirtfeatures_leds_cdaq); + break; + default: + dev_err(&nirtfeatures->acpi_device->dev, + "Unrecognized backplane type %u\n", + bpinfo); + nirtfeatures_acpi_remove(device); + return -ENODEV; + } + + err = sysfs_create_files(&nirtfeatures->acpi_device->dev.kobj, + nirtfeatures_attrs); + if (0 != err) { + nirtfeatures_acpi_remove(device); + return err; + } + + err = nirtfeatures_create_leds(nirtfeatures); + if (0 != err) { + nirtfeatures_acpi_remove(device); + return err; + } + + spin_lock_init(&nirtfeatures->lock); + + nirtfeatures->revision[0] = inb(nirtfeatures->io_base + NIRTF_YEAR); + nirtfeatures->revision[1] = inb(nirtfeatures->io_base + NIRTF_MONTH); + nirtfeatures->revision[2] = inb(nirtfeatures->io_base + NIRTF_DAY); + nirtfeatures->revision[3] = inb(nirtfeatures->io_base + NIRTF_HOUR); + nirtfeatures->revision[4] = inb(nirtfeatures->io_base + NIRTF_MINUTE); + + dev_info(&nirtfeatures->acpi_device->dev, + "IO range 0x%04X-0x%04X\n", + nirtfeatures->io_base, + nirtfeatures->io_base + nirtfeatures->io_size - 1); + + return 0; +} + +static const struct acpi_device_id nirtfeatures_device_ids[] = { + {"NIC775D", 0}, + {"", 0}, +}; + +static struct acpi_driver nirtfeatures_acpi_driver = { + .name = MODULE_NAME, + .ids = nirtfeatures_device_ids, + .ops = { + .add = nirtfeatures_acpi_add, + .remove = nirtfeatures_acpi_remove, + }, +}; + +static int __init nirtfeatures_init(void) +{ + return acpi_bus_register_driver(&nirtfeatures_acpi_driver); +} + +static void __exit nirtfeatures_exit(void) +{ + acpi_bus_unregister_driver(&nirtfeatures_acpi_driver); +} + +module_init(nirtfeatures_init); +module_exit(nirtfeatures_exit); + +MODULE_DEVICE_TABLE(acpi, nirtfeatures_device_ids); +MODULE_DESCRIPTION("NI RT Features"); +MODULE_AUTHOR("Jeff Westfahl "); +MODULE_LICENSE("GPL"); From e941acb71aed604ad3f5c3373fde2cf1fbd2fe17 Mon Sep 17 00:00:00 2001 From: Jeff Westfahl Date: Fri, 14 Mar 2014 17:24:18 -0500 Subject: [PATCH 016/100] nirtfeatures: change hard_boot to soft_reset to match our Zynq targets On our Zynq targets, we expose the power-on reset status of the controller via a soft_reset sysfs file. The same underlying bit in the CPLD is exposed as hard_boot on our Smasher targets. In this commit we change the Smasher implementation to match Zynq. Signed-off-by: Jeff Westfahl --- drivers/misc/nirtfeatures.c | 37 ++++++------------------------------- 1 file changed, 6 insertions(+), 31 deletions(-) diff --git a/drivers/misc/nirtfeatures.c b/drivers/misc/nirtfeatures.c index 40fb9893642e5..3fb9ed5d248b0 100644 --- a/drivers/misc/nirtfeatures.c +++ b/drivers/misc/nirtfeatures.c @@ -264,9 +264,9 @@ static ssize_t nirtfeatures_reset_source_get(struct device *dev, static DEVICE_ATTR(reset_source, S_IRUGO, nirtfeatures_reset_source_get, NULL); -static ssize_t nirtfeatures_hard_boot_get(struct device *dev, - struct device_attribute *attr, - char *buf) +static ssize_t nirtfeatures_soft_reset_get(struct device *dev, + struct device_attribute *attr, + char *buf) { struct acpi_device *acpi_device = to_acpi_device(dev); struct nirtfeatures *nirtfeatures = acpi_device->driver_data; @@ -276,35 +276,10 @@ static ssize_t nirtfeatures_hard_boot_get(struct device *dev, data &= NIRTF_PROCESSOR_MODE_HARD_BOOT_N; - return sprintf(buf, "%s\n", data ? "soft reset" : "power-on reset"); -} - -static ssize_t nirtfeatures_hard_boot_set(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct acpi_device *acpi_device = to_acpi_device(dev); - struct nirtfeatures *nirtfeatures = acpi_device->driver_data; - u8 data; - - if (strcmp(buf, "1")) - return -EINVAL; - - spin_lock(&nirtfeatures->lock); - - data = inb(nirtfeatures->io_base + NIRTF_PROCESSOR_MODE); - - data |= NIRTF_PROCESSOR_MODE_HARD_BOOT_N; - - outb(data, nirtfeatures->io_base + NIRTF_PROCESSOR_MODE); - - spin_unlock(&nirtfeatures->lock); - - return count; + return sprintf(buf, "%u\n", !!data); } -static DEVICE_ATTR(hard_boot, S_IRUGO|S_IWUSR, nirtfeatures_hard_boot_get, - nirtfeatures_hard_boot_set); +static DEVICE_ATTR(soft_reset, S_IRUGO, nirtfeatures_soft_reset_get, NULL); static ssize_t nirtfeatures_no_fpga_get(struct device *dev, struct device_attribute *attr, @@ -514,7 +489,7 @@ static const struct attribute *nirtfeatures_attrs[] = { &dev_attr_railstatus2.attr, &dev_attr_reset.attr, &dev_attr_reset_source.attr, - &dev_attr_hard_boot.attr, + &dev_attr_soft_reset.attr, &dev_attr_no_fpga.attr, &dev_attr_recovery_mode.attr, &dev_attr_console_out.attr, From 98cfdb9372b63dcd4d46d6640e61cb38a096f112 Mon Sep 17 00:00:00 2001 From: Jeff Westfahl Date: Fri, 14 Mar 2014 17:00:58 -0500 Subject: [PATCH 017/100] nirtfeatures: modify reset_source to match Zynq Changed the strings returned by the reset_source sysfs file to match those returned on Zynq. Changed the algorithm used to determine the reset source to match Zynq. Signed-off-by: Jeff Westfahl (Note that the Smasher CPLD currently returns incorrect values for the reset source in some cases. See CARs 458093 and 458094.) --- drivers/misc/nirtfeatures.c | 50 ++++++++----------------------------- 1 file changed, 11 insertions(+), 39 deletions(-) diff --git a/drivers/misc/nirtfeatures.c b/drivers/misc/nirtfeatures.c index 3fb9ed5d248b0..c373b79650fdb 100644 --- a/drivers/misc/nirtfeatures.c +++ b/drivers/misc/nirtfeatures.c @@ -211,6 +211,10 @@ static ssize_t nirtfeatures_reset_set(struct device *dev, static DEVICE_ATTR(reset, S_IWUSR, NULL, nirtfeatures_reset_set); +static const char * const nirtfeatures_reset_source_strings[] = { + "button", "processor", "fpga", "watchdog", "software", "softoff", +}; + static ssize_t nirtfeatures_reset_source_get(struct device *dev, struct device_attribute *attr, char *buf) @@ -218,48 +222,16 @@ static ssize_t nirtfeatures_reset_source_get(struct device *dev, struct acpi_device *acpi_device = to_acpi_device(dev); struct nirtfeatures *nirtfeatures = acpi_device->driver_data; u8 data; - const char *reset_source; + int i; - data = inb(nirtfeatures->io_base + NIRTF_PROCESSOR_MODE); + data = inb(nirtfeatures->io_base + NIRTF_RESET_SOURCE); - data &= NIRTF_PROCESSOR_MODE_HARD_BOOT_N; - - /* Power-on reset status is in a different register from the other reset - sources, we must check it first. */ - if (!data) { - reset_source = "power-on reset"; - } else { - data = inb(nirtfeatures->io_base + NIRTF_RESET_SOURCE); - - switch (data) { - case NIRTF_RESET_SOURCE_SOFT_OFF: - reset_source = "soft off button"; - break; - case NIRTF_RESET_SOURCE_SOFTWARE: - reset_source = "software"; - break; - case NIRTF_RESET_SOURCE_WATCHDOG: - reset_source = "watchdog"; - break; - case NIRTF_RESET_SOURCE_FPGA: - reset_source = "FPGA"; - break; - case NIRTF_RESET_SOURCE_PROCESSOR: - reset_source = "processor"; - break; - case NIRTF_RESET_SOURCE_BUTTON: - reset_source = "reset button"; - break; - default: - dev_err(&nirtfeatures->acpi_device->dev, - "Unrecognized reset source 0x%02X\n", - data); - reset_source = "unknown"; - break; - } - } + for (i = 0; i < ARRAY_SIZE(nirtfeatures_reset_source_strings); i++) + if ((1 << i) & data) + return sprintf(buf, "%s\n", + nirtfeatures_reset_source_strings[i]); - return sprintf(buf, "%s\n", reset_source); + return sprintf(buf, "poweron\n"); } static DEVICE_ATTR(reset_source, S_IRUGO, nirtfeatures_reset_source_get, NULL); From 7c45f8e77237a992a88f3f9de35d57965b8a5e4a Mon Sep 17 00:00:00 2001 From: Jeff Westfahl Date: Fri, 14 Mar 2014 17:12:01 -0500 Subject: [PATCH 018/100] nirtfeatures: restructure init function to close holes In nirtfeatures_acpi_add, we create several sysfs files. As currently implemented, there is a window where access to a sysfs file may cause our spinlock to be used before it's been initialized, or may cause us to write an incorrect value to an I/O port. We can close this window by moving the creation of the sysfs files closer to the end of the function. Signed-off-by: Jeff Westfahl [cvadrevu: fixed trivial conflict due to dropping 9cbd2f25fe01 ("nirtfeatures: set HARD_BOOT_N if necessary when the driver loads")] Signed-off-by: Chaitanya Vadrevu --- drivers/misc/nirtfeatures.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/misc/nirtfeatures.c b/drivers/misc/nirtfeatures.c index c373b79650fdb..89bf4516579bc 100644 --- a/drivers/misc/nirtfeatures.c +++ b/drivers/misc/nirtfeatures.c @@ -771,6 +771,14 @@ static int nirtfeatures_acpi_add(struct acpi_device *device) return -ENODEV; } + spin_lock_init(&nirtfeatures->lock); + + nirtfeatures->revision[0] = inb(nirtfeatures->io_base + NIRTF_YEAR); + nirtfeatures->revision[1] = inb(nirtfeatures->io_base + NIRTF_MONTH); + nirtfeatures->revision[2] = inb(nirtfeatures->io_base + NIRTF_DAY); + nirtfeatures->revision[3] = inb(nirtfeatures->io_base + NIRTF_HOUR); + nirtfeatures->revision[4] = inb(nirtfeatures->io_base + NIRTF_MINUTE); + err = sysfs_create_files(&nirtfeatures->acpi_device->dev.kobj, nirtfeatures_attrs); if (0 != err) { @@ -784,14 +792,6 @@ static int nirtfeatures_acpi_add(struct acpi_device *device) return err; } - spin_lock_init(&nirtfeatures->lock); - - nirtfeatures->revision[0] = inb(nirtfeatures->io_base + NIRTF_YEAR); - nirtfeatures->revision[1] = inb(nirtfeatures->io_base + NIRTF_MONTH); - nirtfeatures->revision[2] = inb(nirtfeatures->io_base + NIRTF_DAY); - nirtfeatures->revision[3] = inb(nirtfeatures->io_base + NIRTF_HOUR); - nirtfeatures->revision[4] = inb(nirtfeatures->io_base + NIRTF_MINUTE); - dev_info(&nirtfeatures->acpi_device->dev, "IO range 0x%04X-0x%04X\n", nirtfeatures->io_base, From 61496f15c78c4b3caab4ec5510401c073c5b9b74 Mon Sep 17 00:00:00 2001 From: Jeff Westfahl Date: Fri, 14 Mar 2014 17:14:42 -0500 Subject: [PATCH 019/100] nirtfeatures: add LOCK, DEBUG_SWITCH, and GP_BUTTON registers The Smasher CPLD has recently exposed some new registers. In this commit we display the values of these registers in the output of the register_dump sysfs file. Signed-off-by: Jeff Westfahl --- drivers/misc/nirtfeatures.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/drivers/misc/nirtfeatures.c b/drivers/misc/nirtfeatures.c index 89bf4516579bc..d5ba6c8baec4e 100644 --- a/drivers/misc/nirtfeatures.c +++ b/drivers/misc/nirtfeatures.c @@ -35,6 +35,7 @@ #define NIRTF_BPINFO 0x07 #define NIRTF_RAIL_STATUS1 0x08 #define NIRTF_RAIL_STATUS2 0x09 +#define NIRTF_LOCK 0x0F #define NIRTF_RESET 0x10 #define NIRTF_RESET_SOURCE 0x11 #define NIRTF_PROCESSOR_MODE 0x12 @@ -42,6 +43,8 @@ #define NIRTF_STATUS_LED_SHIFT1 0x21 #define NIRTF_STATUS_LED_SHIFT0 0x22 #define NIRTF_RT_LEDS 0x23 +#define NIRTF_DEBUG_SWITCH 0x30 +#define NIRTF_GP_BUTTON 0x31 #define NIRTF_IO_SIZE 0x40 @@ -403,8 +406,9 @@ static ssize_t nirtfeatures_register_dump_get(struct device *dev, struct acpi_device *acpi_device = to_acpi_device(dev); struct nirtfeatures *nirtfeatures = acpi_device->driver_data; u8 signature, year, month, day, hour, minute, scratch, bpinfo; - u8 railstatus1, railstatus2, reset, reset_source, processor_mode; + u8 railstatus1, railstatus2, lock, reset, reset_source, processor_mode; u8 system_leds, status_led_shift1, status_led_shift0, rt_leds; + u8 debug_switch, gp_button; signature = inb(nirtfeatures->io_base + NIRTF_SIGNATURE); year = inb(nirtfeatures->io_base + NIRTF_YEAR); @@ -416,6 +420,7 @@ static ssize_t nirtfeatures_register_dump_get(struct device *dev, bpinfo = inb(nirtfeatures->io_base + NIRTF_BPINFO); railstatus1 = inb(nirtfeatures->io_base + NIRTF_RAIL_STATUS1); railstatus2 = inb(nirtfeatures->io_base + NIRTF_RAIL_STATUS2); + lock = inb(nirtfeatures->io_base + NIRTF_LOCK); reset = inb(nirtfeatures->io_base + NIRTF_RESET); reset_source = inb(nirtfeatures->io_base + NIRTF_RESET_SOURCE); processor_mode = inb(nirtfeatures->io_base + NIRTF_PROCESSOR_MODE); @@ -425,6 +430,8 @@ static ssize_t nirtfeatures_register_dump_get(struct device *dev, status_led_shift0 = inb(nirtfeatures->io_base + NIRTF_STATUS_LED_SHIFT0); rt_leds = inb(nirtfeatures->io_base + NIRTF_RT_LEDS); + debug_switch = inb(nirtfeatures->io_base + NIRTF_DEBUG_SWITCH); + gp_button = inb(nirtfeatures->io_base + NIRTF_GP_BUTTON); return sprintf(buf, "Signature: 0x%02X\n" @@ -437,17 +444,21 @@ static ssize_t nirtfeatures_register_dump_get(struct device *dev, "BPInfo: 0x%02X\n" "Rail status 1: 0x%02X\n" "Rail status 2: 0x%02X\n" + "Lock: 0x%02X\n" "Reset: 0x%02X\n" "Reset source: 0x%02X\n" "Processor mode: 0x%02X\n" "System LEDs: 0x%02X\n" "Status LED shift 1: 0x%02X\n" "Status LED shift 0: 0x%02X\n" - "RT LEDs: 0x%02X\n", + "RT LEDs: 0x%02X\n" + "Debug switch: 0x%02X\n" + "GP button: 0x%02X\n", signature, year, month, day, hour, minute, scratch, - bpinfo, railstatus1, railstatus2, reset, reset_source, - processor_mode, system_leds, status_led_shift1, - status_led_shift0, rt_leds); + bpinfo, railstatus1, railstatus2, lock, reset, + reset_source, processor_mode, system_leds, + status_led_shift1, status_led_shift0, rt_leds, + debug_switch, gp_button); } static DEVICE_ATTR(register_dump, S_IRUGO, nirtfeatures_register_dump_get, From b8617b062ac0d2d2e8e7c639465e00c6c246a8e7 Mon Sep 17 00:00:00 2001 From: Jeff Westfahl Date: Fri, 21 Mar 2014 15:42:17 -0500 Subject: [PATCH 020/100] nirtfeatures: Change Hammerhead ID to match hardware When we built Hammerhead, we used ID 4 instead of 1. We don't want to rework all of the boards to match the documentation, so we're just changing the documentation and driver to match what we built. Signed-off-by: Jeff Westfahl --- drivers/misc/nirtfeatures.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/misc/nirtfeatures.c b/drivers/misc/nirtfeatures.c index d5ba6c8baec4e..74e0b67f875c5 100644 --- a/drivers/misc/nirtfeatures.c +++ b/drivers/misc/nirtfeatures.c @@ -53,7 +53,7 @@ #define NIRTF_BPINFO_ID_MASK 0x07 #define NIRTF_BPINFO_ID_MANHATTAN 0 -#define NIRTF_BPINFO_ID_HAMMERHEAD 1 +#define NIRTF_BPINFO_ID_HAMMERHEAD 4 #define NIRTF_RESET_RESET_PROCESSOR 0x80 From 2170abf0754cd29b4353930ef50e2ee3ce1e91c2 Mon Sep 17 00:00:00 2001 From: Jeff Westfahl Date: Tue, 1 Apr 2014 13:37:37 -0500 Subject: [PATCH 021/100] nirtfeatures: support for Winghead variant Signed-off-by: Jeff Westfahl --- drivers/misc/nirtfeatures.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/misc/nirtfeatures.c b/drivers/misc/nirtfeatures.c index 74e0b67f875c5..df3a40b29f79f 100644 --- a/drivers/misc/nirtfeatures.c +++ b/drivers/misc/nirtfeatures.c @@ -54,6 +54,7 @@ #define NIRTF_BPINFO_ID_MANHATTAN 0 #define NIRTF_BPINFO_ID_HAMMERHEAD 4 +#define NIRTF_BPINFO_ID_WINGHEAD 5 #define NIRTF_RESET_RESET_PROCESSOR 0x80 @@ -774,6 +775,12 @@ static int nirtfeatures_acpi_add(struct acpi_device *device) nirtfeatures->num_extra_leds = ARRAY_SIZE(nirtfeatures_leds_cdaq); break; + case NIRTF_BPINFO_ID_WINGHEAD: + nirtfeatures->bpstring = "Winghead"; + nirtfeatures->extra_leds = nirtfeatures_leds_cdaq; + nirtfeatures->num_extra_leds = + ARRAY_SIZE(nirtfeatures_leds_cdaq); + break; default: dev_err(&nirtfeatures->acpi_device->dev, "Unrecognized backplane type %u\n", From 887f3cfbdd47753207730ecd1df7a338550efcfa Mon Sep 17 00:00:00 2001 From: Jeff Westfahl Date: Tue, 1 Apr 2014 13:58:01 -0500 Subject: [PATCH 022/100] nirtfeatures: support latest CPLD The existing recovery_mode and no_fpga bits are now read only. A new bit, no_fpga_sw, exists for software to tell the CPLD to assert NO_FPGA at the next reset. Signed-off-by: Jeff Westfahl --- drivers/misc/nirtfeatures.c | 85 +++++++++++++++++-------------------- 1 file changed, 38 insertions(+), 47 deletions(-) diff --git a/drivers/misc/nirtfeatures.c b/drivers/misc/nirtfeatures.c index df3a40b29f79f..e31caacaf8e4a 100644 --- a/drivers/misc/nirtfeatures.c +++ b/drivers/misc/nirtfeatures.c @@ -65,6 +65,7 @@ #define NIRTF_RESET_SOURCE_PROCESSOR 0x02 #define NIRTF_RESET_SOURCE_BUTTON 0x01 +#define NIRTF_PROCESSOR_MODE_NO_FPGA_SW 0x40 #define NIRTF_PROCESSOR_MODE_HARD_BOOT_N 0x20 #define NIRTF_PROCESSOR_MODE_NO_FPGA 0x10 #define NIRTF_PROCESSOR_MODE_RECOVERY 0x08 @@ -240,7 +241,7 @@ static ssize_t nirtfeatures_reset_source_get(struct device *dev, static DEVICE_ATTR(reset_source, S_IRUGO, nirtfeatures_reset_source_get, NULL); -static ssize_t nirtfeatures_soft_reset_get(struct device *dev, +static ssize_t nirtfeatures_no_fpga_sw_get(struct device *dev, struct device_attribute *attr, char *buf) { @@ -250,31 +251,14 @@ static ssize_t nirtfeatures_soft_reset_get(struct device *dev, data = inb(nirtfeatures->io_base + NIRTF_PROCESSOR_MODE); - data &= NIRTF_PROCESSOR_MODE_HARD_BOOT_N; + data &= NIRTF_PROCESSOR_MODE_NO_FPGA_SW; return sprintf(buf, "%u\n", !!data); } -static DEVICE_ATTR(soft_reset, S_IRUGO, nirtfeatures_soft_reset_get, NULL); - -static ssize_t nirtfeatures_no_fpga_get(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct acpi_device *acpi_device = to_acpi_device(dev); - struct nirtfeatures *nirtfeatures = acpi_device->driver_data; - u8 data; - - data = inb(nirtfeatures->io_base + NIRTF_PROCESSOR_MODE); - - data &= NIRTF_PROCESSOR_MODE_NO_FPGA; - - return sprintf(buf, "%u\n", !!data); -} - -static ssize_t nirtfeatures_no_fpga_set(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t nirtfeatures_no_fpga_sw_set(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) { struct acpi_device *acpi_device = to_acpi_device(dev); struct nirtfeatures *nirtfeatures = acpi_device->driver_data; @@ -289,9 +273,9 @@ static ssize_t nirtfeatures_no_fpga_set(struct device *dev, data = inb(nirtfeatures->io_base + NIRTF_PROCESSOR_MODE); if (tmp) - data |= NIRTF_PROCESSOR_MODE_NO_FPGA; + data |= NIRTF_PROCESSOR_MODE_NO_FPGA_SW; else - data &= ~NIRTF_PROCESSOR_MODE_NO_FPGA; + data &= ~NIRTF_PROCESSOR_MODE_NO_FPGA_SW; outb(data, nirtfeatures->io_base + NIRTF_PROCESSOR_MODE); @@ -300,12 +284,12 @@ static ssize_t nirtfeatures_no_fpga_set(struct device *dev, return count; } -static DEVICE_ATTR(no_fpga, S_IRUGO|S_IWUSR, nirtfeatures_no_fpga_get, - nirtfeatures_no_fpga_set); +static DEVICE_ATTR(no_fpga_sw, S_IRUGO|S_IWUSR, nirtfeatures_no_fpga_sw_get, + nirtfeatures_no_fpga_sw_set); -static ssize_t nirtfeatures_recovery_mode_get(struct device *dev, - struct device_attribute *attr, - char *buf) +static ssize_t nirtfeatures_soft_reset_get(struct device *dev, + struct device_attribute *attr, + char *buf) { struct acpi_device *acpi_device = to_acpi_device(dev); struct nirtfeatures *nirtfeatures = acpi_device->driver_data; @@ -313,41 +297,47 @@ static ssize_t nirtfeatures_recovery_mode_get(struct device *dev, data = inb(nirtfeatures->io_base + NIRTF_PROCESSOR_MODE); - data &= NIRTF_PROCESSOR_MODE_RECOVERY; + data &= NIRTF_PROCESSOR_MODE_HARD_BOOT_N; return sprintf(buf, "%u\n", !!data); } -static ssize_t nirtfeatures_recovery_mode_set(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) +static DEVICE_ATTR(soft_reset, S_IRUGO, nirtfeatures_soft_reset_get, NULL); + +static ssize_t nirtfeatures_no_fpga_get(struct device *dev, + struct device_attribute *attr, + char *buf) { struct acpi_device *acpi_device = to_acpi_device(dev); struct nirtfeatures *nirtfeatures = acpi_device->driver_data; - unsigned long tmp; u8 data; - if (kstrtoul(buf, 0, &tmp) || (tmp > 1)) - return -EINVAL; + data = inb(nirtfeatures->io_base + NIRTF_PROCESSOR_MODE); - spin_lock(&nirtfeatures->lock); + data &= NIRTF_PROCESSOR_MODE_NO_FPGA; - data = inb(nirtfeatures->io_base + NIRTF_PROCESSOR_MODE); + return sprintf(buf, "%u\n", !!data); +} - if (tmp) - data |= NIRTF_PROCESSOR_MODE_RECOVERY; - else - data &= ~NIRTF_PROCESSOR_MODE_RECOVERY; +static DEVICE_ATTR(no_fpga, S_IRUGO, nirtfeatures_no_fpga_get, NULL); - outb(data, nirtfeatures->io_base + NIRTF_PROCESSOR_MODE); +static ssize_t nirtfeatures_recovery_mode_get(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct acpi_device *acpi_device = to_acpi_device(dev); + struct nirtfeatures *nirtfeatures = acpi_device->driver_data; + u8 data; - spin_unlock(&nirtfeatures->lock); + data = inb(nirtfeatures->io_base + NIRTF_PROCESSOR_MODE); - return count; + data &= NIRTF_PROCESSOR_MODE_RECOVERY; + + return sprintf(buf, "%u\n", !!data); } -static DEVICE_ATTR(recovery_mode, S_IRUGO|S_IWUSR, - nirtfeatures_recovery_mode_get, nirtfeatures_recovery_mode_set); +static DEVICE_ATTR(recovery_mode, S_IRUGO, + nirtfeatures_recovery_mode_get, NULL); static ssize_t nirtfeatures_console_out_get(struct device *dev, struct device_attribute *attr, @@ -473,6 +463,7 @@ static const struct attribute *nirtfeatures_attrs[] = { &dev_attr_railstatus2.attr, &dev_attr_reset.attr, &dev_attr_reset_source.attr, + &dev_attr_no_fpga_sw.attr, &dev_attr_soft_reset.attr, &dev_attr_no_fpga.attr, &dev_attr_recovery_mode.attr, From 47e2f7c615021a3e38f0a16ab2fda1cedf99b0ae Mon Sep 17 00:00:00 2001 From: Jeff Westfahl Date: Thu, 10 Apr 2014 16:56:04 -0500 Subject: [PATCH 023/100] nirtfeatures: don't bail out on unrecognized ID The driver currently returns an error from init if it doesn't recognize the backplane ID. This causes the kernel to hang on boot. Although this is probably a bug somewhere else in the kernel, there's no real benefit to returning an error in this case. It's sufficient to print an error message to the console and return "Unknown" as the backplane ID. Signed-off-by: Jeff Westfahl --- drivers/misc/nirtfeatures.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/misc/nirtfeatures.c b/drivers/misc/nirtfeatures.c index e31caacaf8e4a..dbfd065a15ac7 100644 --- a/drivers/misc/nirtfeatures.c +++ b/drivers/misc/nirtfeatures.c @@ -776,8 +776,8 @@ static int nirtfeatures_acpi_add(struct acpi_device *device) dev_err(&nirtfeatures->acpi_device->dev, "Unrecognized backplane type %u\n", bpinfo); - nirtfeatures_acpi_remove(device); - return -ENODEV; + nirtfeatures->bpstring = "Unknown"; + break; } spin_lock_init(&nirtfeatures->lock); From 2c3ed04613f9c836aac1e62f1882fd488cbbdc68 Mon Sep 17 00:00:00 2001 From: Jeff Westfahl Date: Fri, 11 Apr 2014 09:01:06 -0500 Subject: [PATCH 024/100] nirtfeatures: remove unused NI_HW_REBOOT config option Remove the unused NI_HW_REBOOT config option. We're not going to use this. Signed-off-by: Jeff Westfahl --- drivers/misc/Kconfig | 11 ----------- drivers/misc/nirtfeatures.c | 29 ----------------------------- 2 files changed, 40 deletions(-) diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index fa58f425f064c..b491c63576ece 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -664,17 +664,6 @@ config NI_LED_PREFIX If unsure, use the default. -config NI_HW_REBOOT - bool "Hardware reboot for NI 903x/913x" - depends on NI_RT_FEATURES && X86_64 - default n - help - If enabled, when rebooting an NI 903x/913x, on-board hardware will - be used to reset the system. If not enabled, the controller will do - a normal ACPI reset. - - If unsure, say N. - source "drivers/misc/c2port/Kconfig" source "drivers/misc/eeprom/Kconfig" source "drivers/misc/cb710/Kconfig" diff --git a/drivers/misc/nirtfeatures.c b/drivers/misc/nirtfeatures.c index dbfd065a15ac7..9b1e3232d4a58 100644 --- a/drivers/misc/nirtfeatures.c +++ b/drivers/misc/nirtfeatures.c @@ -17,10 +17,6 @@ #include #include -#ifdef CONFIG_NI_HW_REBOOT -#include -#endif - #define MODULE_NAME "nirtfeatures" /* Register addresses */ @@ -644,26 +640,6 @@ static void nirtfeatures_remove_leds(struct nirtfeatures *nirtfeatures) led_classdev_unregister(&nirtfeatures->extra_leds[i].cdev); } -/* Board specific reboot fixup */ - -#ifdef CONFIG_NI_HW_REBOOT - -static u16 mach_reboot_fixup_io_base; - -void mach_reboot_fixups(void) -{ - int i; - - if (mach_reboot_fixup_io_base) - for (i = 0; i < 10; ++i) { - outb(NIRTF_RESET_RESET_PROCESSOR, - mach_reboot_fixup_io_base + NIRTF_RESET); - udelay(100); - } -} - -#endif - /* ACPI driver */ static acpi_status nirtfeatures_resources(struct acpi_resource *res, void *data) @@ -747,11 +723,6 @@ static int nirtfeatures_acpi_add(struct acpi_device *device) return -EBUSY; } -#ifdef CONFIG_NI_HW_REBOOT - mach_reboot_fixup_io_base = nirtfeatures->io_base; - reboot_type = BOOT_KBD; -#endif - bpinfo = inb(nirtfeatures->io_base + NIRTF_BPINFO); bpinfo &= NIRTF_BPINFO_ID_MASK; From ff2d2ce6ce7656300e48b8fd62f366c226e7e921 Mon Sep 17 00:00:00 2001 From: Jeff Westfahl Date: Fri, 11 Apr 2014 10:09:59 -0500 Subject: [PATCH 025/100] nirtfeatures: update to latest CPLD and remove debugging features Updated registers to match the latest CPLD documentation, removed several sysfs files that were only used for development debugging, and removed several now unused constants. Signed-off-by: Jeff Westfahl --- drivers/misc/nirtfeatures.c | 211 +++++++----------------------------- 1 file changed, 39 insertions(+), 172 deletions(-) diff --git a/drivers/misc/nirtfeatures.c b/drivers/misc/nirtfeatures.c index 9b1e3232d4a58..def78a22cf403 100644 --- a/drivers/misc/nirtfeatures.c +++ b/drivers/misc/nirtfeatures.c @@ -21,53 +21,36 @@ /* Register addresses */ -#define NIRTF_SIGNATURE 0x00 #define NIRTF_YEAR 0x01 #define NIRTF_MONTH 0x02 #define NIRTF_DAY 0x03 #define NIRTF_HOUR 0x04 #define NIRTF_MINUTE 0x05 #define NIRTF_SCRATCH 0x06 -#define NIRTF_BPINFO 0x07 -#define NIRTF_RAIL_STATUS1 0x08 -#define NIRTF_RAIL_STATUS2 0x09 -#define NIRTF_LOCK 0x0F -#define NIRTF_RESET 0x10 -#define NIRTF_RESET_SOURCE 0x11 -#define NIRTF_PROCESSOR_MODE 0x12 +#define NIRTF_PLATFORM_MISC 0x07 +#define NIRTF_PROC_RESET_SOURCE 0x11 +#define NIRTF_CONTROLLER_MODE 0x12 #define NIRTF_SYSTEM_LEDS 0x20 #define NIRTF_STATUS_LED_SHIFT1 0x21 #define NIRTF_STATUS_LED_SHIFT0 0x22 #define NIRTF_RT_LEDS 0x23 -#define NIRTF_DEBUG_SWITCH 0x30 -#define NIRTF_GP_BUTTON 0x31 #define NIRTF_IO_SIZE 0x40 /* Register values */ -#define NIRTF_BPINFO_ID_MASK 0x07 +#define NIRTF_PLATFORM_MISC_ID_MASK 0x07 +#define NIRTF_PLATFORM_MISC_ID_MANHATTAN 0 +#define NIRTF_PLATFORM_MISC_ID_HAMMERHEAD 4 +#define NIRTF_PLATFORM_MISC_ID_WINGHEAD 5 -#define NIRTF_BPINFO_ID_MANHATTAN 0 -#define NIRTF_BPINFO_ID_HAMMERHEAD 4 -#define NIRTF_BPINFO_ID_WINGHEAD 5 - -#define NIRTF_RESET_RESET_PROCESSOR 0x80 - -#define NIRTF_RESET_SOURCE_SOFT_OFF 0x20 -#define NIRTF_RESET_SOURCE_SOFTWARE 0x10 -#define NIRTF_RESET_SOURCE_WATCHDOG 0x08 -#define NIRTF_RESET_SOURCE_FPGA 0x04 -#define NIRTF_RESET_SOURCE_PROCESSOR 0x02 -#define NIRTF_RESET_SOURCE_BUTTON 0x01 - -#define NIRTF_PROCESSOR_MODE_NO_FPGA_SW 0x40 -#define NIRTF_PROCESSOR_MODE_HARD_BOOT_N 0x20 -#define NIRTF_PROCESSOR_MODE_NO_FPGA 0x10 -#define NIRTF_PROCESSOR_MODE_RECOVERY 0x08 -#define NIRTF_PROCESSOR_MODE_CONSOLE_OUT 0x04 -#define NIRTF_PROCESSOR_MODE_IP_RESET 0x02 -#define NIRTF_PROCESSOR_MODE_SAFE 0x01 +#define NIRTF_CONTROLLER_MODE_NO_FPGA_SW 0x40 +#define NIRTF_CONTROLLER_MODE_HARD_BOOT_N 0x20 +#define NIRTF_CONTROLLER_MODE_NO_FPGA 0x10 +#define NIRTF_CONTROLLER_MODE_RECOVERY 0x08 +#define NIRTF_CONTROLLER_MODE_CONSOLE_OUT 0x04 +#define NIRTF_CONTROLLER_MODE_IP_RESET 0x02 +#define NIRTF_CONTROLLER_MODE_SAFE 0x01 #define NIRTF_SYSTEM_LEDS_STATUS_RED 0x08 #define NIRTF_SYSTEM_LEDS_STATUS_YELLOW 0x04 @@ -165,55 +148,8 @@ static ssize_t nirtfeatures_backplane_id_get(struct device *dev, static DEVICE_ATTR(backplane_id, S_IRUGO, nirtfeatures_backplane_id_get, NULL); -static ssize_t nirtfeatures_railstatus1_get(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct acpi_device *acpi_device = to_acpi_device(dev); - struct nirtfeatures *nirtfeatures = acpi_device->driver_data; - u8 data; - - data = inb(nirtfeatures->io_base + NIRTF_RAIL_STATUS1); - - return sprintf(buf, "%02x\n", data); -} - -static DEVICE_ATTR(railstatus1, S_IRUGO, nirtfeatures_railstatus1_get, NULL); - -static ssize_t nirtfeatures_railstatus2_get(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct acpi_device *acpi_device = to_acpi_device(dev); - struct nirtfeatures *nirtfeatures = acpi_device->driver_data; - u8 data; - - data = inb(nirtfeatures->io_base + NIRTF_RAIL_STATUS2); - - return sprintf(buf, "%02x\n", data); -} - -static DEVICE_ATTR(railstatus2, S_IRUGO, nirtfeatures_railstatus2_get, NULL); - -static ssize_t nirtfeatures_reset_set(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct acpi_device *acpi_device = to_acpi_device(dev); - struct nirtfeatures *nirtfeatures = acpi_device->driver_data; - - if (strcmp(buf, "1")) - return -EINVAL; - - outb(NIRTF_RESET_RESET_PROCESSOR, nirtfeatures->io_base + NIRTF_RESET); - - return count; -} - -static DEVICE_ATTR(reset, S_IWUSR, NULL, nirtfeatures_reset_set); - static const char * const nirtfeatures_reset_source_strings[] = { - "button", "processor", "fpga", "watchdog", "software", "softoff", + "button", "processor", "fpga", "watchdog", "software", }; static ssize_t nirtfeatures_reset_source_get(struct device *dev, @@ -225,7 +161,7 @@ static ssize_t nirtfeatures_reset_source_get(struct device *dev, u8 data; int i; - data = inb(nirtfeatures->io_base + NIRTF_RESET_SOURCE); + data = inb(nirtfeatures->io_base + NIRTF_PROC_RESET_SOURCE); for (i = 0; i < ARRAY_SIZE(nirtfeatures_reset_source_strings); i++) if ((1 << i) & data) @@ -245,9 +181,9 @@ static ssize_t nirtfeatures_no_fpga_sw_get(struct device *dev, struct nirtfeatures *nirtfeatures = acpi_device->driver_data; u8 data; - data = inb(nirtfeatures->io_base + NIRTF_PROCESSOR_MODE); + data = inb(nirtfeatures->io_base + NIRTF_CONTROLLER_MODE); - data &= NIRTF_PROCESSOR_MODE_NO_FPGA_SW; + data &= NIRTF_CONTROLLER_MODE_NO_FPGA_SW; return sprintf(buf, "%u\n", !!data); } @@ -266,14 +202,14 @@ static ssize_t nirtfeatures_no_fpga_sw_set(struct device *dev, spin_lock(&nirtfeatures->lock); - data = inb(nirtfeatures->io_base + NIRTF_PROCESSOR_MODE); + data = inb(nirtfeatures->io_base + NIRTF_CONTROLLER_MODE); if (tmp) - data |= NIRTF_PROCESSOR_MODE_NO_FPGA_SW; + data |= NIRTF_CONTROLLER_MODE_NO_FPGA_SW; else - data &= ~NIRTF_PROCESSOR_MODE_NO_FPGA_SW; + data &= ~NIRTF_CONTROLLER_MODE_NO_FPGA_SW; - outb(data, nirtfeatures->io_base + NIRTF_PROCESSOR_MODE); + outb(data, nirtfeatures->io_base + NIRTF_CONTROLLER_MODE); spin_unlock(&nirtfeatures->lock); @@ -291,9 +227,9 @@ static ssize_t nirtfeatures_soft_reset_get(struct device *dev, struct nirtfeatures *nirtfeatures = acpi_device->driver_data; u8 data; - data = inb(nirtfeatures->io_base + NIRTF_PROCESSOR_MODE); + data = inb(nirtfeatures->io_base + NIRTF_CONTROLLER_MODE); - data &= NIRTF_PROCESSOR_MODE_HARD_BOOT_N; + data &= NIRTF_CONTROLLER_MODE_HARD_BOOT_N; return sprintf(buf, "%u\n", !!data); } @@ -308,9 +244,9 @@ static ssize_t nirtfeatures_no_fpga_get(struct device *dev, struct nirtfeatures *nirtfeatures = acpi_device->driver_data; u8 data; - data = inb(nirtfeatures->io_base + NIRTF_PROCESSOR_MODE); + data = inb(nirtfeatures->io_base + NIRTF_CONTROLLER_MODE); - data &= NIRTF_PROCESSOR_MODE_NO_FPGA; + data &= NIRTF_CONTROLLER_MODE_NO_FPGA; return sprintf(buf, "%u\n", !!data); } @@ -325,9 +261,9 @@ static ssize_t nirtfeatures_recovery_mode_get(struct device *dev, struct nirtfeatures *nirtfeatures = acpi_device->driver_data; u8 data; - data = inb(nirtfeatures->io_base + NIRTF_PROCESSOR_MODE); + data = inb(nirtfeatures->io_base + NIRTF_CONTROLLER_MODE); - data &= NIRTF_PROCESSOR_MODE_RECOVERY; + data &= NIRTF_CONTROLLER_MODE_RECOVERY; return sprintf(buf, "%u\n", !!data); } @@ -343,9 +279,9 @@ static ssize_t nirtfeatures_console_out_get(struct device *dev, struct nirtfeatures *nirtfeatures = acpi_device->driver_data; u8 data; - data = inb(nirtfeatures->io_base + NIRTF_PROCESSOR_MODE); + data = inb(nirtfeatures->io_base + NIRTF_CONTROLLER_MODE); - data &= NIRTF_PROCESSOR_MODE_CONSOLE_OUT; + data &= NIRTF_CONTROLLER_MODE_CONSOLE_OUT; return sprintf(buf, "%u\n", !!data); } @@ -360,9 +296,9 @@ static ssize_t nirtfeatures_ip_reset_get(struct device *dev, struct nirtfeatures *nirtfeatures = acpi_device->driver_data; u8 data; - data = inb(nirtfeatures->io_base + NIRTF_PROCESSOR_MODE); + data = inb(nirtfeatures->io_base + NIRTF_CONTROLLER_MODE); - data &= NIRTF_PROCESSOR_MODE_IP_RESET; + data &= NIRTF_CONTROLLER_MODE_IP_RESET; return sprintf(buf, "%u\n", !!data); } @@ -377,87 +313,19 @@ static ssize_t nirtfeatures_safe_mode_get(struct device *dev, struct nirtfeatures *nirtfeatures = acpi_device->driver_data; u8 data; - data = inb(nirtfeatures->io_base + NIRTF_PROCESSOR_MODE); + data = inb(nirtfeatures->io_base + NIRTF_CONTROLLER_MODE); - data &= NIRTF_PROCESSOR_MODE_SAFE; + data &= NIRTF_CONTROLLER_MODE_SAFE; return sprintf(buf, "%u\n", !!data); } static DEVICE_ATTR(safe_mode, S_IRUGO, nirtfeatures_safe_mode_get, NULL); -static ssize_t nirtfeatures_register_dump_get(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct acpi_device *acpi_device = to_acpi_device(dev); - struct nirtfeatures *nirtfeatures = acpi_device->driver_data; - u8 signature, year, month, day, hour, minute, scratch, bpinfo; - u8 railstatus1, railstatus2, lock, reset, reset_source, processor_mode; - u8 system_leds, status_led_shift1, status_led_shift0, rt_leds; - u8 debug_switch, gp_button; - - signature = inb(nirtfeatures->io_base + NIRTF_SIGNATURE); - year = inb(nirtfeatures->io_base + NIRTF_YEAR); - month = inb(nirtfeatures->io_base + NIRTF_MONTH); - day = inb(nirtfeatures->io_base + NIRTF_DAY); - hour = inb(nirtfeatures->io_base + NIRTF_HOUR); - minute = inb(nirtfeatures->io_base + NIRTF_MINUTE); - scratch = inb(nirtfeatures->io_base + NIRTF_SCRATCH); - bpinfo = inb(nirtfeatures->io_base + NIRTF_BPINFO); - railstatus1 = inb(nirtfeatures->io_base + NIRTF_RAIL_STATUS1); - railstatus2 = inb(nirtfeatures->io_base + NIRTF_RAIL_STATUS2); - lock = inb(nirtfeatures->io_base + NIRTF_LOCK); - reset = inb(nirtfeatures->io_base + NIRTF_RESET); - reset_source = inb(nirtfeatures->io_base + NIRTF_RESET_SOURCE); - processor_mode = inb(nirtfeatures->io_base + NIRTF_PROCESSOR_MODE); - system_leds = inb(nirtfeatures->io_base + NIRTF_SYSTEM_LEDS); - status_led_shift1 = - inb(nirtfeatures->io_base + NIRTF_STATUS_LED_SHIFT1); - status_led_shift0 = - inb(nirtfeatures->io_base + NIRTF_STATUS_LED_SHIFT0); - rt_leds = inb(nirtfeatures->io_base + NIRTF_RT_LEDS); - debug_switch = inb(nirtfeatures->io_base + NIRTF_DEBUG_SWITCH); - gp_button = inb(nirtfeatures->io_base + NIRTF_GP_BUTTON); - - return sprintf(buf, - "Signature: 0x%02X\n" - "Year: 0x%02X\n" - "Month: 0x%02X\n" - "Day: 0x%02X\n" - "Hour: 0x%02X\n" - "Minute: 0x%02X\n" - "Scratch: 0x%02X\n" - "BPInfo: 0x%02X\n" - "Rail status 1: 0x%02X\n" - "Rail status 2: 0x%02X\n" - "Lock: 0x%02X\n" - "Reset: 0x%02X\n" - "Reset source: 0x%02X\n" - "Processor mode: 0x%02X\n" - "System LEDs: 0x%02X\n" - "Status LED shift 1: 0x%02X\n" - "Status LED shift 0: 0x%02X\n" - "RT LEDs: 0x%02X\n" - "Debug switch: 0x%02X\n" - "GP button: 0x%02X\n", - signature, year, month, day, hour, minute, scratch, - bpinfo, railstatus1, railstatus2, lock, reset, - reset_source, processor_mode, system_leds, - status_led_shift1, status_led_shift0, rt_leds, - debug_switch, gp_button); -} - -static DEVICE_ATTR(register_dump, S_IRUGO, nirtfeatures_register_dump_get, - NULL); - static const struct attribute *nirtfeatures_attrs[] = { &dev_attr_revision.attr, &dev_attr_scratch.attr, &dev_attr_backplane_id.attr, - &dev_attr_railstatus1.attr, - &dev_attr_railstatus2.attr, - &dev_attr_reset.attr, &dev_attr_reset_source.attr, &dev_attr_no_fpga_sw.attr, &dev_attr_soft_reset.attr, @@ -466,7 +334,6 @@ static const struct attribute *nirtfeatures_attrs[] = { &dev_attr_console_out.attr, &dev_attr_ip_reset.attr, &dev_attr_safe_mode.attr, - &dev_attr_register_dump.attr, NULL }; @@ -723,21 +590,21 @@ static int nirtfeatures_acpi_add(struct acpi_device *device) return -EBUSY; } - bpinfo = inb(nirtfeatures->io_base + NIRTF_BPINFO); + bpinfo = inb(nirtfeatures->io_base + NIRTF_PLATFORM_MISC); - bpinfo &= NIRTF_BPINFO_ID_MASK; + bpinfo &= NIRTF_PLATFORM_MISC_ID_MASK; switch (bpinfo) { - case NIRTF_BPINFO_ID_MANHATTAN: + case NIRTF_PLATFORM_MISC_ID_MANHATTAN: nirtfeatures->bpstring = "Manhattan"; break; - case NIRTF_BPINFO_ID_HAMMERHEAD: + case NIRTF_PLATFORM_MISC_ID_HAMMERHEAD: nirtfeatures->bpstring = "Hammerhead"; nirtfeatures->extra_leds = nirtfeatures_leds_cdaq; nirtfeatures->num_extra_leds = ARRAY_SIZE(nirtfeatures_leds_cdaq); break; - case NIRTF_BPINFO_ID_WINGHEAD: + case NIRTF_PLATFORM_MISC_ID_WINGHEAD: nirtfeatures->bpstring = "Winghead"; nirtfeatures->extra_leds = nirtfeatures_leds_cdaq; nirtfeatures->num_extra_leds = From bd3025edccf0e8823f3084d97602d10f18edd4d3 Mon Sep 17 00:00:00 2001 From: Gratian Crisan Date: Tue, 13 May 2014 16:12:02 -0500 Subject: [PATCH 026/100] nirtfeatures: Physical interface element support These changes add support for PIEs (physical interface elements), which are defined as physical elements fixed to a controller/chassis with which a user can interact (e.g. LEDs and switches) and whose meaning is user-defined and implementation-specific. The support for these elements, in terms of enumerating and interacting with them (i.e. retrieving the list of elements, getting/setting their current state, enabling notifications, etc.) is embedded within the BIOS as a set of ACPI methods. The changes to the CPLD driver act as a bridge between these methods and existing Linux kernel facilities as described below to expose the elements and any applicable metadata to user mode. The metadata or knowledge needed for the interpretation thereof is not a prerequisite to interacting with the elements--it is there for upper-level value add software to use to improve the user experience. In other words, Linux users familiar with the class drivers by which the elements are surfaced should not have any issues interfacing with them without knowing the meaning of the attached metadata. Output elements, which consist currently of LEDs, are surfaced via the LED class driver. Each LED and color becomes its own LED class device with the naming convention 'nilrt:{name}:{color}'. Any additional attributes/metadata intended for upper-level software are appended to the name, each separated by colons, as suggested by the LED class driver documentation in the Linux kernel proper, except where there is already a standard way to communicate a specific piece of metadata (e.g., maximum brightness, which is exposed via the /sys/class/leds/.../ max_brightness attribute node). Input elements as surfaced via the input class driver. As with output elements, each input element registers its own separate driver whose name and associated metadata are transmitted via the name attribute attached to the input device, retrievable via the EVIOCGNAME ioctl, using the same convention as described above for output elements. The input class driver model is that events are pushed (i.e. reported) to indicate state changes, so to facilitate this, the CPLD driver has an ACPI notify callback that is invoked when an input element changes state and its BIOS support generates a general purpose event per the ACPI GPE model. The notify callback checks the instantaneous state of the input element and reports a keyboard event on its particular device with a scan code of 256 (BTN_0), where a key down event means that the input element is in the '1' state (down, engaged, on, pressed, etc.) and a key up event means that the input element is in the '0' state (off, disengaged, released, etc.). User mode software can then monitor for these specific events to determine when the state of the element has changed, or can use the EVIOCGKEY ioctl on the appropriate input device to retrieve the instantaneous state of the element. Signed-off-by: Aaron Rossetto (joshc: fixed up strnicmp -> strncasecmp for 4.0) Signed-off-by: Josh Cartwright [mpeterse: change return type of nirtfeatures_acpi_remove due to 6c0eb5ba3500] Signed-off-by: Mike Petersen --- drivers/misc/nirtfeatures.c | 812 +++++++++++++++++++++++++++++++++--- 1 file changed, 751 insertions(+), 61 deletions(-) diff --git a/drivers/misc/nirtfeatures.c b/drivers/misc/nirtfeatures.c index def78a22cf403..1ae01b7a4ad2a 100644 --- a/drivers/misc/nirtfeatures.c +++ b/drivers/misc/nirtfeatures.c @@ -15,7 +15,9 @@ #include #include #include +#include #include +#include #define MODULE_NAME "nirtfeatures" @@ -57,10 +59,49 @@ #define NIRTF_SYSTEM_LEDS_POWER_GREEN 0x02 #define NIRTF_SYSTEM_LEDS_POWER_YELLOW 0x01 -#define NIRTF_RT_LEDS_USER2_GREEN 0x08 -#define NIRTF_RT_LEDS_USER2_YELLOW 0x04 -#define NIRTF_RT_LEDS_USER1_GREEN 0x02 -#define NIRTF_RT_LEDS_USER1_YELLOW 0x01 +/*===================================================================== + * ACPI NI physical interface element support + *===================================================================*/ +#define MAX_NAMELEN 64 +#define MAX_NODELEN 128 +#define MIN_PIE_CAPS_VERSION 2 +#define MAX_PIE_CAPS_VERSION 2 + +enum nirtfeatures_pie_class { + PIE_CLASS_INPUT = 0, + PIE_CLASS_OUTPUT = 1 +}; + +enum nirtfeatures_pie_type { + PIE_TYPE_UNKNOWN = 0, + PIE_TYPE_SWITCH = 1, + PIE_TYPE_LED = 2 +}; + +struct nirtfeatures_pie_descriptor { + char name[MAX_NAMELEN]; + enum nirtfeatures_pie_class pie_class; + enum nirtfeatures_pie_type pie_type; + bool is_user_visible; + unsigned int notification_value; +}; + +struct nirtfeatures_pie_descriptor_led_color { + char name[MAX_NAMELEN]; + int brightness_range_low; + int brightness_range_high; +}; + +struct nirtfeatures_pie_descriptor_switch { + unsigned int num_states; + unsigned int state_value[1]; +}; + +struct nirtfeatures_pie_location { + unsigned int element; + unsigned int subelement; +}; + /* Structures */ @@ -71,18 +112,31 @@ struct nirtfeatures { spinlock_t lock; u8 revision[5]; const char *bpstring; - struct nirtfeatures_led *extra_leds; - unsigned num_extra_leds; }; struct nirtfeatures_led { struct led_classdev cdev; struct nirtfeatures *nirtfeatures; + struct nirtfeatures_pie_location pie_location; + char name_string[MAX_NODELEN]; u8 address; u8 mask; u8 pattern_hi_addr; u8 pattern_lo_addr; + struct list_head node; +}; +LIST_HEAD(nirtfeatures_led_pie_list); + +struct nirtfeatures_switch { + struct input_dev *cdev; + struct nirtfeatures *nirtfeatures; + struct nirtfeatures_pie_descriptor pie_descriptor; + struct nirtfeatures_pie_location pie_location; + char name_string[MAX_NODELEN]; + char phys_location_string[MAX_NODELEN]; + struct list_head node; }; +LIST_HEAD(nirtfeatures_switch_pie_list); /* sysfs files */ @@ -386,20 +440,6 @@ nirtfeatures_led_brightness_get(struct led_classdev *led_cdev) } static struct nirtfeatures_led nirtfeatures_leds_common[] = { - { - { - .name = CONFIG_NI_LED_PREFIX ":user1:green", - }, - .address = NIRTF_RT_LEDS, - .mask = NIRTF_RT_LEDS_USER1_GREEN, - }, - { - { - .name = CONFIG_NI_LED_PREFIX ":user1:yellow", - }, - .address = NIRTF_RT_LEDS, - .mask = NIRTF_RT_LEDS_USER1_YELLOW, - }, { { .name = CONFIG_NI_LED_PREFIX ":status:red", @@ -433,22 +473,610 @@ static struct nirtfeatures_led nirtfeatures_leds_common[] = { }, }; -static struct nirtfeatures_led nirtfeatures_leds_cdaq[] = { - { - { - .name = CONFIG_NI_LED_PREFIX ":user2:green", - }, - .address = NIRTF_RT_LEDS, - .mask = NIRTF_RT_LEDS_USER2_GREEN, - }, - { - { - .name = CONFIG_NI_LED_PREFIX ":user2:yellow", - }, - .address = NIRTF_RT_LEDS, - .mask = NIRTF_RT_LEDS_USER2_YELLOW, - }, -}; +/*===================================================================== + * ACPI NI physical interface element support + *===================================================================*/ + +/* Note that callers of this function are responsible for deallocating + * the buffer allocated by acpi_evaluate_object() by calling + * kfree() on the pointer passed back in result_buffer. + */ +static int nirtfeatures_call_acpi_method(struct nirtfeatures *nirtfeatures, + const char *method_name, + int argc, + union acpi_object *argv, + acpi_size *result_size, + void **result_buffer) +{ + acpi_status acpi_ret; + acpi_handle acpi_hdl; + struct acpi_object_list acpi_params; + struct acpi_buffer acpi_result = { ACPI_ALLOCATE_BUFFER, NULL }; + + if (NULL == nirtfeatures || NULL == result_size || + NULL == result_buffer) + return -EINVAL; + + acpi_ret = acpi_get_handle(nirtfeatures->acpi_device->handle, + (acpi_string) method_name, &acpi_hdl); + if (ACPI_FAILURE(acpi_ret)) { + dev_err(&nirtfeatures->acpi_device->dev, + "nirtfeatures: ACPI get handle for %s failed (%d)\n", + method_name, acpi_ret); + return -1; + } + + acpi_params.count = argc; + acpi_params.pointer = argv; + + acpi_ret = acpi_evaluate_object(acpi_hdl, NULL, + &acpi_params, &acpi_result); + if (ACPI_FAILURE(acpi_ret)) { + dev_err(&nirtfeatures->acpi_device->dev, + "nirtfeatures: ACPI evaluate for %s failed (%d)\n", + method_name, acpi_ret); + return -1; + } + + *result_size = acpi_result.length; + *result_buffer = acpi_result.pointer; + return 0; +} + +/* This is the generic PIE set state wrapper. It invokes the PIES + * ACPI method to modify the state of the given PIE. + */ +static int nirtfeatures_pie_set_state(struct nirtfeatures *nirtfeatures, + unsigned int element, unsigned int subelement, int state) +{ + union acpi_object pies_args[3]; + acpi_size result_size; + void *result_buffer; + union acpi_object *acpi_buffer; + int err = 0; + + if (NULL == nirtfeatures) + return -EINVAL; + + pies_args[0].type = ACPI_TYPE_INTEGER; + pies_args[0].integer.value = element; + pies_args[1].type = ACPI_TYPE_INTEGER; + pies_args[1].integer.value = subelement; + pies_args[2].type = ACPI_TYPE_INTEGER; + pies_args[2].integer.value = state; + + /* evaluate PIES(element, subelement, value) ACPI method */ + err = nirtfeatures_call_acpi_method(nirtfeatures, "PIES", + 3, &pies_args[0], &result_size, &result_buffer); + + if (err == 0) { + acpi_buffer = (union acpi_object *) result_buffer; + if (ACPI_TYPE_INTEGER == acpi_buffer->type) + err = (int) acpi_buffer->integer.value; + kfree(result_buffer); + } + + return err; +} + +/* This is the generic PIE get state wrapper. It invokes the PIEG + * ACPI method to query the state of the given PIE. + */ +static int nirtfeatures_pie_get_state(struct nirtfeatures *nirtfeatures, + unsigned int element, unsigned int subelement, int *result) +{ + union acpi_object pies_args[2]; + acpi_size result_size; + void *result_buffer; + union acpi_object *acpi_buffer; + int err = 0; + + if (NULL == nirtfeatures || NULL == result) + return -EINVAL; + + pies_args[0].type = ACPI_TYPE_INTEGER; + pies_args[0].integer.value = element; + pies_args[1].type = ACPI_TYPE_INTEGER; + pies_args[1].integer.value = subelement; + + /* evaluate PIEG(element, subelement) ACPI method */ + err = nirtfeatures_call_acpi_method(nirtfeatures, "PIEG", + 2, &pies_args[0], &result_size, &result_buffer); + + if (err == 0) { + acpi_buffer = (union acpi_object *) result_buffer; + if (ACPI_TYPE_INTEGER == acpi_buffer->type) + *result = (int) acpi_buffer->integer.value; + kfree(result_buffer); + } + + return err; +} + +/* This function enables or disables notifications for a particular + * input class PIE. + */ +static int nirtfeatures_pie_enable_notifications( + struct nirtfeatures *nirtfeatures, + unsigned int element, unsigned int subelement, int enable) +{ + union acpi_object pies_args[3]; + acpi_size result_size; + void *result_buffer; + union acpi_object *acpi_buffer; + int err = 0; + + if (NULL == nirtfeatures) + return -EINVAL; + + pies_args[0].type = ACPI_TYPE_INTEGER; + pies_args[0].integer.value = element; + pies_args[1].type = ACPI_TYPE_INTEGER; + pies_args[1].integer.value = subelement; + pies_args[2].type = ACPI_TYPE_INTEGER; + pies_args[2].integer.value = enable; + + /* evaluate PIEF(element, subelement, enable) ACPI method */ + err = nirtfeatures_call_acpi_method(nirtfeatures, "PIEF", + 3, &pies_args[0], &result_size, &result_buffer); + + if (err == 0) { + acpi_buffer = (union acpi_object *) result_buffer; + if (ACPI_TYPE_INTEGER == acpi_buffer->type) + err = (int) acpi_buffer->integer.value; + kfree(result_buffer); + } + + return err; +} + +/* This is the set_brightness callback for a PIE-enumerated LED. + */ +static void nirtfeatures_led_pie_brightness_set( + struct led_classdev *led_cdev, enum led_brightness brightness) +{ + struct nirtfeatures_led *led = (struct nirtfeatures_led *)led_cdev; + + spin_lock(&led->nirtfeatures->lock); + + /* Delegate the control of the PIE to the ACPI method. */ + if (nirtfeatures_pie_set_state(led->nirtfeatures, + led->pie_location.element, led->pie_location.subelement, + brightness)) { + dev_err(&led->nirtfeatures->acpi_device->dev, + "nirtfeatures: set brightness failed for %s\n", + led->name_string); + } + + spin_unlock(&led->nirtfeatures->lock); +} + +/* This is the get_brightness callback for a PIE-enumerated LED. + */ +static enum led_brightness nirtfeatures_led_pie_brightness_get( + struct led_classdev *led_cdev) +{ + struct nirtfeatures_led *led = (struct nirtfeatures_led *)led_cdev; + int state = 0; + + spin_lock(&led->nirtfeatures->lock); + + if (nirtfeatures_pie_get_state(led->nirtfeatures, + led->pie_location.element, led->pie_location.subelement, &state)) { + dev_err(&led->nirtfeatures->acpi_device->dev, + "nirtfeatures: get brightness failed for %s\n", + led->name_string); + } + + spin_unlock(&led->nirtfeatures->lock); + return state; +} + +/* Parse a PIE LED color caps package and populate the + * corresponding nirtfeatures_pie_descriptor_led_color structure. + */ +static int nirtfeatures_parse_led_pie_color(struct nirtfeatures *nirtfeatures, + unsigned int pie_caps_version, + struct nirtfeatures_pie_descriptor_led_color *led_color_descriptor, + union acpi_object *acpi_buffer) +{ + unsigned int i; + + if (NULL == nirtfeatures || NULL == led_color_descriptor || + NULL == acpi_buffer) + return -EINVAL; + + /* element 0 of a PIE LED color caps package is the name */ + if (ACPI_TYPE_BUFFER == acpi_buffer->package.elements[0].type) { + for (i = 0; + i < acpi_buffer->package.elements[0].buffer.length; i++) { + /* get pointer to Nth Unicode character in name */ + unsigned short *unicode_char = (unsigned short *) + (acpi_buffer->package.elements[0].buffer.pointer + + (2 * i)); + /* naive convert to ASCII */ + led_color_descriptor->name[i] = + (char) *unicode_char & 0xff; + } + } else + return -EINVAL; + + /* element 1 is the brightness min value */ + if (ACPI_TYPE_INTEGER == acpi_buffer->package.elements[1].type) + led_color_descriptor->brightness_range_low = + (int) acpi_buffer->package.elements[1].integer.value; + else + return -EINVAL; + + /* element 2 is the brightness max value */ + if (ACPI_TYPE_INTEGER == acpi_buffer->package.elements[2].type) + led_color_descriptor->brightness_range_high = + (int) acpi_buffer->package.elements[2].integer.value; + else + return -EINVAL; + + return 0; +} + +/* Parse a PIE LED caps package and create an LED class device + * with the appropriate metadata. + */ +static int nirtfeatures_parse_led_pie( + struct nirtfeatures *nirtfeatures, + unsigned int pie_caps_version, + unsigned int pie_element, + struct nirtfeatures_pie_descriptor *pie, + union acpi_object *acpi_buffer) +{ + unsigned int num_colors; + unsigned int i; + struct nirtfeatures_pie_descriptor_led_color led_descriptor; + struct nirtfeatures_led *led_dev; + int err; + + if (NULL == nirtfeatures || NULL == pie || + NULL == acpi_buffer) + return -EINVAL; + + if (ACPI_TYPE_PACKAGE != acpi_buffer->type) + return -EINVAL; + + /* element 0 is the number of colors */ + if (ACPI_TYPE_INTEGER == acpi_buffer->package.elements[0].type) { + num_colors = (unsigned int) + acpi_buffer->package.elements[0].integer.value; + } else { + return -EINVAL; + } + + /* parse color caps and create LED class device */ + for (i = 0; i < num_colors; i++) { + if (nirtfeatures_parse_led_pie_color(nirtfeatures, + pie_caps_version, &led_descriptor, + &(acpi_buffer->package.elements[i + 1]))) + return -EINVAL; + + /* create an LED class device for this LED */ + led_dev = kzalloc(sizeof(struct nirtfeatures_led), GFP_KERNEL); + if (NULL == led_dev) + return -ENOMEM; + + /* for compatibility with existing LVRT support, PIEs beginning + * with 'user' should not affix the uservisible attribute to + * their name */ + if (strncasecmp(pie->name, "user", strlen("user")) != 0) { + snprintf(led_dev->name_string, MAX_NODELEN, + "%s:%s:%s:uservisible=%d", + CONFIG_NI_LED_PREFIX, + pie->name, led_descriptor.name, + pie->is_user_visible); + } else { + snprintf(led_dev->name_string, MAX_NODELEN, + "%s:%s:%s", + CONFIG_NI_LED_PREFIX, + pie->name, led_descriptor.name); + } + + led_dev->cdev.name = led_dev->name_string; + led_dev->cdev.brightness = + led_descriptor.brightness_range_low; + led_dev->cdev.max_brightness = + led_descriptor.brightness_range_high; + led_dev->cdev.brightness_set = + nirtfeatures_led_pie_brightness_set; + led_dev->cdev.brightness_get = + nirtfeatures_led_pie_brightness_get; + led_dev->nirtfeatures = nirtfeatures; + led_dev->pie_location.element = pie_element; + led_dev->pie_location.subelement = i; + + err = led_classdev_register(&nirtfeatures->acpi_device->dev, + &led_dev->cdev); + if (0 != err) { + kfree(led_dev); + return err; + } + + list_add_tail(&led_dev->node, &nirtfeatures_led_pie_list); + } + + return 0; +} + +/* Parse a PIE switch caps package and create an input class device + * with the appropriate metadata. + */ +static int nirtfeatures_parse_switch_pie(struct nirtfeatures *nirtfeatures, + unsigned int pie_caps_version, + unsigned int pie_element, + struct nirtfeatures_pie_descriptor *pie, + union acpi_object *acpi_buffer) +{ + unsigned int num_states; + unsigned int i; + struct nirtfeatures_pie_descriptor_switch *switch_descriptor = NULL; + struct nirtfeatures_switch *switch_dev = NULL; + int err = 0; + + if (NULL == nirtfeatures || NULL == pie || NULL == acpi_buffer) + return -EINVAL; + + if (ACPI_TYPE_PACKAGE != acpi_buffer->type) + return -EINVAL; + + /* element 0 is the number of states */ + if (ACPI_TYPE_INTEGER == acpi_buffer->package.elements[0].type) + num_states = (unsigned int) + acpi_buffer->package.elements[0].integer.value; + else + return -EINVAL; + + /* allocate storage for switch descriptor */ + switch_descriptor = kzalloc( + sizeof(struct nirtfeatures_pie_descriptor_switch) + + sizeof(int) * (num_states - 1), GFP_KERNEL); + if (NULL == switch_descriptor) + return -ENOMEM; + + switch_descriptor->num_states = num_states; + + /* parse individual states in elements 1..N-1 */ + for (i = 0; i < num_states; i++) { + if (ACPI_TYPE_INTEGER != + acpi_buffer->package.elements[i + 1].type) { + err = -EINVAL; + goto exit; + } + + switch_descriptor->state_value[i] = + (int) acpi_buffer->package.elements[i + 1].integer.value; + } + + /* create an input class device for this switch */ + switch_dev = kzalloc(sizeof(struct nirtfeatures_switch), GFP_KERNEL); + if (NULL == switch_dev) { + err = -ENOMEM; + goto exit; + } + + switch_dev->cdev = input_allocate_device(); + if (NULL == switch_dev->cdev) { + err = -ENOMEM; + goto exit_dealloc_switch_dev; + } + + switch_dev->nirtfeatures = nirtfeatures; + switch_dev->pie_location.element = pie_element; + switch_dev->pie_location.subelement = 0; + memcpy(&switch_dev->pie_descriptor, pie, + sizeof(struct nirtfeatures_pie_descriptor)); + + snprintf(switch_dev->name_string, MAX_NODELEN, + "%s:%s:uservisible=%d:states=(", + CONFIG_NI_LED_PREFIX, pie->name, pie->is_user_visible); + for (i = 0; i < switch_descriptor->num_states; i++) { + char temp[4] = { '\0' }; + + sprintf(temp, "%d%c", switch_descriptor->state_value[i], + (i < switch_descriptor->num_states - 1) ? ',' : ')'); + strncat(switch_dev->name_string, temp, MAX_NODELEN); + } + + snprintf(switch_dev->phys_location_string, MAX_NODELEN, "%s/%s/%s", + CONFIG_NI_LED_PREFIX, nirtfeatures->bpstring, pie->name); + + switch_dev->cdev->name = switch_dev->name_string; + switch_dev->cdev->phys = switch_dev->phys_location_string; + switch_dev->cdev->id.bustype = BUS_HOST; + switch_dev->cdev->id.vendor = 0x3923; + switch_dev->cdev->id.product = pie->pie_type; + switch_dev->cdev->id.version = pie_caps_version; + switch_dev->cdev->dev.parent = &nirtfeatures->acpi_device->dev; + + switch_dev->cdev->evbit[0] = BIT_MASK(EV_KEY); + set_bit(BTN_0, switch_dev->cdev->keybit); + + err = input_register_device(switch_dev->cdev); + if (0 != err) { + input_free_device(switch_dev->cdev); + goto exit_dealloc_switch_dev; + } + + /* if this PIE supports notifications, enable them now */ + if (pie->notification_value != 0) { + err = nirtfeatures_pie_enable_notifications(nirtfeatures, + pie_element, 0, 1); + if (0 != err) { + input_unregister_device(switch_dev->cdev); + input_free_device(switch_dev->cdev); + goto exit_dealloc_switch_dev; + } + } + + /* add the new device to our list of switch PIEs */ + list_add_tail(&switch_dev->node, &nirtfeatures_switch_pie_list); + goto exit; + +exit_dealloc_switch_dev: + kfree(switch_dev); + +exit: + kfree(switch_descriptor); + return err; +} + + +/* Parse a single PIE caps package from the PIEC buffer, determine the + * type of PIE it is, then dispatch to the appropriate parsing routine. + */ +static int nirtfeatures_parse_one_pie(struct nirtfeatures *nirtfeatures, + unsigned int pie_caps_version, + unsigned int pie_element, + union acpi_object *acpi_buffer) +{ + struct nirtfeatures_pie_descriptor pie; + unsigned int i; + + if (NULL == nirtfeatures || NULL == acpi_buffer) + return -EINVAL; + + /* check for proper type and number of elements */ + if (ACPI_TYPE_PACKAGE != acpi_buffer->type || + 6 != acpi_buffer->package.count) + return -EINVAL; + + /* element 0 of the package is the name */ + if (ACPI_TYPE_BUFFER == acpi_buffer->package.elements[0].type) { + for (i = 0; + i < acpi_buffer->package.elements[0].buffer.length && + i < MAX_NAMELEN; i++) { + /* get pointer to Nth Unicode character in name */ + unsigned short *unicode_char = (unsigned short *) + (acpi_buffer->package.elements[0].buffer.pointer + + (2 * i)); + /* naive convert to ASCII */ + pie.name[i] = (char) *unicode_char & 0xff; + } + } else + return -EINVAL; + + /* element 1 of the package is the PIE class */ + if (ACPI_TYPE_INTEGER == acpi_buffer->package.elements[1].type) + pie.pie_class = (enum nirtfeatures_pie_class) + acpi_buffer->package.elements[1].integer.value; + else + return -EINVAL; + + /* element 2 of the package is the PIE type */ + if (ACPI_TYPE_INTEGER == acpi_buffer->package.elements[2].type) + pie.pie_type = (enum nirtfeatures_pie_type) + acpi_buffer->package.elements[2].integer.value; + else + return -EINVAL; + + /* element 4 of an package is the visible flag */ + if (ACPI_TYPE_INTEGER == acpi_buffer->package.elements[4].type) + pie.is_user_visible = + (acpi_buffer->package.elements[4].integer.value != 0); + else + return -EINVAL; + + /* element 5 of the package is the notification value */ + if (ACPI_TYPE_INTEGER == acpi_buffer->package.elements[5].type) + pie.notification_value = + acpi_buffer->package.elements[5].integer.value; + else + return -EINVAL; + + /* parse the type-specific descriptor in element 3 */ + switch (pie.pie_type) { + case PIE_TYPE_LED: + if (nirtfeatures_parse_led_pie(nirtfeatures, + pie_caps_version, pie_element, &pie, + &(acpi_buffer->package.elements[3]))) + return -EINVAL; + break; + case PIE_TYPE_SWITCH: + if (nirtfeatures_parse_switch_pie(nirtfeatures, + pie_caps_version, pie_element, &pie, + &(acpi_buffer->package.elements[3]))) + return -EINVAL; + break; + + default: + return -EINVAL; + break; + } + + return 0; +} + +/* Populate the list of physical interface elements from the table in + * the DSDT and then generate the appropriate class devices. + */ +static int nirtfeatures_populate_pies(struct nirtfeatures *nirtfeatures) +{ + acpi_size result_size; + void *result_buffer; + union acpi_object *acpi_buffer; + unsigned int num_elements = 0; + unsigned int pie_caps_version; + unsigned int i; + unsigned int err = 0; + + if (NULL == nirtfeatures) + return -EINVAL; + + /* get the PIE descriptor buffer from DSDT */ + if (nirtfeatures_call_acpi_method(nirtfeatures, + "PIEC", 0, NULL, &result_size, &result_buffer)) + return -1; + + acpi_buffer = (union acpi_object *) result_buffer; + if (ACPI_TYPE_PACKAGE != acpi_buffer->type) { + err = -1; + goto exit; + } + + /* the first element of the package is the caps version */ + if (ACPI_TYPE_INTEGER == acpi_buffer->package.elements[0].type) + pie_caps_version = (unsigned int) + acpi_buffer->package.elements[0].integer.value; + else { + err = -1; + goto exit; + } + + if (pie_caps_version < MIN_PIE_CAPS_VERSION || + pie_caps_version > MAX_PIE_CAPS_VERSION) { + dev_err(&nirtfeatures->acpi_device->dev, + "nirtfeatures: invalid PIE caps version\n"); + err = -1; + goto exit; + } + + /* the second element of the package is the number of PIEs */ + if (ACPI_TYPE_INTEGER == acpi_buffer->package.elements[1].type) + num_elements = (unsigned int) + acpi_buffer->package.elements[1].integer.value; + else { + err = -1; + goto exit; + } + + /* parse elements 2..N as PIE descriptors */ + for (i = 2; i < acpi_buffer->package.count; i++) { + err = nirtfeatures_parse_one_pie(nirtfeatures, + pie_caps_version, i - 2, + &(acpi_buffer->package.elements[i])); + if (0 != err) + break; + } + +exit: + kfree(result_buffer); + return err; +} static int nirtfeatures_create_leds(struct nirtfeatures *nirtfeatures) { @@ -474,37 +1102,57 @@ static int nirtfeatures_create_leds(struct nirtfeatures *nirtfeatures) return err; } - for (i = 0; i < nirtfeatures->num_extra_leds; ++i) { + return 0; +} - nirtfeatures->extra_leds[i].nirtfeatures = nirtfeatures; +static void nirtfeatures_remove_leds(struct nirtfeatures *nirtfeatures) +{ + int i; - if (0 == nirtfeatures->extra_leds[i].cdev.max_brightness) - nirtfeatures->extra_leds[i].cdev.max_brightness = 1; + for (i = 0; i < ARRAY_SIZE(nirtfeatures_leds_common); ++i) + led_classdev_unregister(&nirtfeatures_leds_common[i].cdev); +} - nirtfeatures->extra_leds[i].cdev.brightness_set = - nirtfeatures_led_brightness_set; +static void nirtfeatures_remove_led_pies(struct nirtfeatures *nirtfeatures) +{ + struct nirtfeatures_led *cdev_iter; + struct nirtfeatures_led *temp; - nirtfeatures->extra_leds[i].cdev.brightness_get = - nirtfeatures_led_brightness_get; + spin_lock(&nirtfeatures->lock); - err = led_classdev_register(&nirtfeatures->acpi_device->dev, - &nirtfeatures->extra_leds[i].cdev); - if (err) - return err; + /* walk the list of non-fixed LEDs and unregister/free their devices */ + list_for_each_entry_safe( + cdev_iter, temp, &nirtfeatures_led_pie_list, node) { + led_classdev_unregister(&cdev_iter->cdev); + kfree(cdev_iter); } - return 0; + spin_unlock(&nirtfeatures->lock); } -static void nirtfeatures_remove_leds(struct nirtfeatures *nirtfeatures) +static void nirtfeatures_remove_switch_pies(struct nirtfeatures *nirtfeatures) { - int i; + struct nirtfeatures_switch *cdev_iter; + struct nirtfeatures_switch *temp; - for (i = 0; i < ARRAY_SIZE(nirtfeatures_leds_common); ++i) - led_classdev_unregister(&nirtfeatures_leds_common[i].cdev); + spin_lock(&nirtfeatures->lock); + + /* walk the list of switch devices and unregister/free each one */ + list_for_each_entry_safe( + cdev_iter, temp, &nirtfeatures_switch_pie_list, node) { + /* disable notifications for this PIE if supported */ + if (cdev_iter->pie_descriptor.notification_value != 0) { + nirtfeatures_pie_enable_notifications(nirtfeatures, + cdev_iter->pie_location.element, + cdev_iter->pie_location.subelement, + 0); + } + input_unregister_device(cdev_iter->cdev); + input_free_device(cdev_iter->cdev); + kfree(cdev_iter); + } - for (i = 0; i < nirtfeatures->num_extra_leds; ++i) - led_classdev_unregister(&nirtfeatures->extra_leds[i].cdev); + spin_unlock(&nirtfeatures->lock); } /* ACPI driver */ @@ -540,12 +1188,53 @@ static acpi_status nirtfeatures_resources(struct acpi_resource *res, void *data) return AE_OK; } +/* Process a notification from ACPI, which typically occurs when a switch + * PIE is signalling a change of state via its GPE. + */ +static void nirtfeatures_acpi_notify(struct acpi_device *device, u32 event) +{ + /* find the switch PIE for which this notification was generated, + * and push an event into its associated input subsystem node + */ + struct nirtfeatures_switch *iter; + int state = 0; + struct nirtfeatures *nirtfeatures = + (struct nirtfeatures *)device->driver_data; + + spin_lock(&nirtfeatures->lock); + + list_for_each_entry(iter, &nirtfeatures_switch_pie_list, node) { + if (event == iter->pie_descriptor.notification_value) { + + /* query instantaneous switch state */ + if (!nirtfeatures_pie_get_state(iter->nirtfeatures, + iter->pie_location.element, + iter->pie_location.subelement, + &state)) { + /* push current state of switch */ + input_report_key(iter->cdev, BTN_0, !!state); + input_sync(iter->cdev); + } + spin_unlock(&nirtfeatures->lock); + return; + } + } + + spin_unlock(&nirtfeatures->lock); + + dev_err(&device->dev, "no input found for notification (event %02X)\n", + event); +} + static void nirtfeatures_acpi_remove(struct acpi_device *device) { struct nirtfeatures *nirtfeatures = device->driver_data; nirtfeatures_remove_leds(nirtfeatures); + nirtfeatures_remove_led_pies(nirtfeatures); + nirtfeatures_remove_switch_pies(nirtfeatures); + sysfs_remove_files(&nirtfeatures->acpi_device->dev.kobj, nirtfeatures_attrs); @@ -600,15 +1289,9 @@ static int nirtfeatures_acpi_add(struct acpi_device *device) break; case NIRTF_PLATFORM_MISC_ID_HAMMERHEAD: nirtfeatures->bpstring = "Hammerhead"; - nirtfeatures->extra_leds = nirtfeatures_leds_cdaq; - nirtfeatures->num_extra_leds = - ARRAY_SIZE(nirtfeatures_leds_cdaq); break; case NIRTF_PLATFORM_MISC_ID_WINGHEAD: nirtfeatures->bpstring = "Winghead"; - nirtfeatures->extra_leds = nirtfeatures_leds_cdaq; - nirtfeatures->num_extra_leds = - ARRAY_SIZE(nirtfeatures_leds_cdaq); break; default: dev_err(&nirtfeatures->acpi_device->dev, @@ -620,6 +1303,12 @@ static int nirtfeatures_acpi_add(struct acpi_device *device) spin_lock_init(&nirtfeatures->lock); + err = nirtfeatures_populate_pies(nirtfeatures); + if (0 != err) { + nirtfeatures_acpi_remove(device); + return err; + } + nirtfeatures->revision[0] = inb(nirtfeatures->io_base + NIRTF_YEAR); nirtfeatures->revision[1] = inb(nirtfeatures->io_base + NIRTF_MONTH); nirtfeatures->revision[2] = inb(nirtfeatures->io_base + NIRTF_DAY); @@ -658,6 +1347,7 @@ static struct acpi_driver nirtfeatures_acpi_driver = { .ops = { .add = nirtfeatures_acpi_add, .remove = nirtfeatures_acpi_remove, + .notify = nirtfeatures_acpi_notify, }, }; From 3d55cc551947b4c45f66a3892f08a39347074be2 Mon Sep 17 00:00:00 2001 From: Nathan Sullivan Date: Tue, 29 Sep 2015 12:45:12 -0500 Subject: [PATCH 027/100] nirtfeatures: Don't rename wifi LEDs For compatibility with myRIO, don't change the name of the wireless PIE LEDs. Signed-off-by: Nathan Sullivan Reviewed-by: Jaeden Amero Reviewed-by: Josh Cartwright Natinst-ReviewBoard-ID: 107067 Natinst-CAR-ID: 540272 --- drivers/misc/nirtfeatures.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/misc/nirtfeatures.c b/drivers/misc/nirtfeatures.c index 1ae01b7a4ad2a..9a7d438c05416 100644 --- a/drivers/misc/nirtfeatures.c +++ b/drivers/misc/nirtfeatures.c @@ -762,9 +762,10 @@ static int nirtfeatures_parse_led_pie( return -ENOMEM; /* for compatibility with existing LVRT support, PIEs beginning - * with 'user' should not affix the uservisible attribute to - * their name */ - if (strncasecmp(pie->name, "user", strlen("user")) != 0) { + * with 'user' or 'wifi' should not affix the uservisible + * attribute to their name */ + if (strncasecmp(pie->name, "user", strlen("user")) != 0 && + strncasecmp(pie->name, "wifi", strlen("wifi")) != 0) { snprintf(led_dev->name_string, MAX_NODELEN, "%s:%s:%s:uservisible=%d", CONFIG_NI_LED_PREFIX, From e2dfb0f20ab1c2465a3dc4723dcee4a16b9bf840 Mon Sep 17 00:00:00 2001 From: James Minor Date: Tue, 9 Aug 2016 13:50:02 -0500 Subject: [PATCH 028/100] nirtfeatures: Add control for WiFi reset as a vmmc regulator The MMC driver will enable/disable external regulators as part of enabling/disabling the SD Host Controller. The WLAN_PWD_L line (controlled from the CPLD) must be enabled/disabled at the same time that the controller is enabled/disabled. Allow the MMC driver to just control that pin directly via the regulator framework. Signed-off-by: James Minor --- drivers/misc/Kconfig | 1 + drivers/misc/nirtfeatures.c | 127 +++++++++++++++++++++++++++++++++++- 2 files changed, 126 insertions(+), 2 deletions(-) diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index b491c63576ece..76727dd1acdb9 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -647,6 +647,7 @@ config MCHP_LAN966X_PCI config NI_RT_FEATURES bool "NI 903x/913x support" depends on X86 && ACPI + select REGULATOR help This driver exposes LEDs and other features of NI 903x/913x Real-Time controllers. diff --git a/drivers/misc/nirtfeatures.c b/drivers/misc/nirtfeatures.c index 9a7d438c05416..ea2978c4692f5 100644 --- a/drivers/misc/nirtfeatures.c +++ b/drivers/misc/nirtfeatures.c @@ -18,6 +18,8 @@ #include #include #include +#include +#include #define MODULE_NAME "nirtfeatures" @@ -36,6 +38,7 @@ #define NIRTF_STATUS_LED_SHIFT1 0x21 #define NIRTF_STATUS_LED_SHIFT0 0x22 #define NIRTF_RT_LEDS 0x23 +#define NIRTF_WLAN_CONTROLREG 0x32 #define NIRTF_IO_SIZE 0x40 @@ -59,6 +62,9 @@ #define NIRTF_SYSTEM_LEDS_POWER_GREEN 0x02 #define NIRTF_SYSTEM_LEDS_POWER_YELLOW 0x01 +#define NIRTF_WLAN_RESET_N 0x02 +#define NIRTF_WLAN_RESETENABLE 0x01 + /*===================================================================== * ACPI NI physical interface element support *===================================================================*/ @@ -112,6 +118,8 @@ struct nirtfeatures { spinlock_t lock; u8 revision[5]; const char *bpstring; + bool has_wifi; + struct regulator_dev *reg_dev; }; struct nirtfeatures_led { @@ -733,6 +741,7 @@ static int nirtfeatures_parse_led_pie( struct nirtfeatures_pie_descriptor_led_color led_descriptor; struct nirtfeatures_led *led_dev; int err; + int is_wifi, is_user; if (NULL == nirtfeatures || NULL == pie || NULL == acpi_buffer) @@ -764,8 +773,10 @@ static int nirtfeatures_parse_led_pie( /* for compatibility with existing LVRT support, PIEs beginning * with 'user' or 'wifi' should not affix the uservisible * attribute to their name */ - if (strncasecmp(pie->name, "user", strlen("user")) != 0 && - strncasecmp(pie->name, "wifi", strlen("wifi")) != 0) { + is_user = strncasecmp(pie->name, "user", strlen("user")); + is_wifi = strncasecmp(pie->name, "wifi", strlen("wifi")); + if (is_user != 0 && + is_wifi != 0) { snprintf(led_dev->name_string, MAX_NODELEN, "%s:%s:%s:uservisible=%d", CONFIG_NI_LED_PREFIX, @@ -778,6 +789,10 @@ static int nirtfeatures_parse_led_pie( pie->name, led_descriptor.name); } + /* The presence of any WiFi LED means this target has wifi */ + if (is_wifi == 0) + nirtfeatures->has_wifi = true; + led_dev->cdev.name = led_dev->name_string; led_dev->cdev.brightness = led_descriptor.brightness_range_low; @@ -1239,6 +1254,9 @@ static void nirtfeatures_acpi_remove(struct acpi_device *device) sysfs_remove_files(&nirtfeatures->acpi_device->dev.kobj, nirtfeatures_attrs); + if (nirtfeatures->reg_dev) + regulator_unregister(nirtfeatures->reg_dev); + if ((nirtfeatures->io_base != 0) && (nirtfeatures->io_size == NIRTF_IO_SIZE)) release_region(nirtfeatures->io_base, nirtfeatures->io_size); @@ -1248,6 +1266,102 @@ static void nirtfeatures_acpi_remove(struct acpi_device *device) kfree(nirtfeatures); } +static int nirtfeatures_wifi_regulator_list_voltage(struct regulator_dev *dev, + unsigned selector) +{ + return 3300000; +} + +static int nirtfeatures_wifi_regulator_enable(struct regulator_dev *dev) +{ + struct nirtfeatures *nirtfeatures; + + nirtfeatures = rdev_get_drvdata(dev); + + /* WiFi out of Reset */ + outb(NIRTF_WLAN_RESET_N | NIRTF_WLAN_RESETENABLE, + nirtfeatures->io_base + NIRTF_WLAN_CONTROLREG); + /* WiFi Reset Disable */ + outb(NIRTF_WLAN_RESET_N, + nirtfeatures->io_base + NIRTF_WLAN_CONTROLREG); + + return 0; +} + +static int nirtfeatures_wifi_regulator_disable(struct regulator_dev *dev) +{ + struct nirtfeatures *nirtfeatures; + + nirtfeatures = rdev_get_drvdata(dev); + + /* WiFi Reset Enable */ + outb(NIRTF_WLAN_RESET_N | NIRTF_WLAN_RESETENABLE, + nirtfeatures->io_base + NIRTF_WLAN_CONTROLREG); + /* WiFi into Reset */ + outb(NIRTF_WLAN_RESETENABLE, + nirtfeatures->io_base + NIRTF_WLAN_CONTROLREG); + + /* Silex specs say to assert reset for 5 us, make it 10 to be sure */ + usleep_range(10, 1000); + + return 0; +} + +static int nirtfeatures_wifi_regulator_is_enabled(struct regulator_dev *dev) +{ + struct nirtfeatures *nirtfeatures; + u8 data; + + nirtfeatures = rdev_get_drvdata(dev); + + data = inb(nirtfeatures->io_base + NIRTF_WLAN_CONTROLREG); + + return !!(data & NIRTF_WLAN_RESET_N); +} + +static struct regulator_ops nirtfeatures_wifi_regulator_voltage_ops = { + .list_voltage = nirtfeatures_wifi_regulator_list_voltage, + .enable = nirtfeatures_wifi_regulator_enable, + .disable = nirtfeatures_wifi_regulator_disable, + .is_enabled = nirtfeatures_wifi_regulator_is_enabled +}; + +static const struct regulator_desc nirtfeatures_wifi_regulator_desc = { + .name = "vmmc", + .id = -1, + .n_voltages = 1, + .ops = &nirtfeatures_wifi_regulator_voltage_ops, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE +}; + +static const struct regulator_init_data wifi_reset_init_data = { + .constraints = { + .min_uV = 3300000, + .max_uV = 3300000, + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + } +}; + +static int nirtfeatures_wifi_regulator_init(struct device *dev, + struct nirtfeatures *nirtfeatures) +{ + struct regulator_config cfg = { }; + struct regulator_dev *reg_dev; + + cfg.dev = dev; + cfg.init_data = &wifi_reset_init_data; + cfg.driver_data = nirtfeatures; + reg_dev = regulator_register(&nirtfeatures_wifi_regulator_desc, + &cfg); + if (IS_ERR(reg_dev)) { + pr_err("Failed to register vmmc regulator for wifi\n"); + return -ENODEV; + } + nirtfeatures->reg_dev = reg_dev; + return 0; +} + static int nirtfeatures_acpi_add(struct acpi_device *device) { struct nirtfeatures *nirtfeatures; @@ -1334,6 +1448,15 @@ static int nirtfeatures_acpi_add(struct acpi_device *device) nirtfeatures->io_base, nirtfeatures->io_base + nirtfeatures->io_size - 1); + if (nirtfeatures->has_wifi) { + err = nirtfeatures_wifi_regulator_init(&device->dev, + nirtfeatures); + if (0 != err) { + nirtfeatures_acpi_remove(device); + return err; + } + } + return 0; } From 2e4e34aa40f2492d98aa561caf39c1afbb139678 Mon Sep 17 00:00:00 2001 From: Kyle Roeschley Date: Fri, 9 Sep 2016 13:07:35 -0500 Subject: [PATCH 029/100] nirtfeatures: Add Fire Eagle backplane ID Add the new Fire Eagle backplane ID so we stop complaining on boot. Signed-off-by: Kyle Roeschley Signed-off-by: Brad Mouring Acked-by: Xander Huff Natinst-ReviewBoard-ID: 152156 --- drivers/misc/nirtfeatures.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/misc/nirtfeatures.c b/drivers/misc/nirtfeatures.c index ea2978c4692f5..6d43c89b7ce4c 100644 --- a/drivers/misc/nirtfeatures.c +++ b/drivers/misc/nirtfeatures.c @@ -46,6 +46,7 @@ #define NIRTF_PLATFORM_MISC_ID_MASK 0x07 #define NIRTF_PLATFORM_MISC_ID_MANHATTAN 0 +#define NIRTF_PLATFORM_MISC_ID_FIRE_EAGLE 2 #define NIRTF_PLATFORM_MISC_ID_HAMMERHEAD 4 #define NIRTF_PLATFORM_MISC_ID_WINGHEAD 5 @@ -1402,6 +1403,9 @@ static int nirtfeatures_acpi_add(struct acpi_device *device) case NIRTF_PLATFORM_MISC_ID_MANHATTAN: nirtfeatures->bpstring = "Manhattan"; break; + case NIRTF_PLATFORM_MISC_ID_FIRE_EAGLE: + nirtfeatures->bpstring = "Fire Eagle"; + break; case NIRTF_PLATFORM_MISC_ID_HAMMERHEAD: nirtfeatures->bpstring = "Hammerhead"; break; From 19a85b21987183638ab70ed9f4d4b3de49c3780b Mon Sep 17 00:00:00 2001 From: Xander Huff Date: Fri, 14 Oct 2016 13:54:00 -0500 Subject: [PATCH 030/100] nirtfeatures: Housecleaning of comments, comparisons, etc. Fix checkpatch warnings: Block comments use * on subsequent lines Block comments use a trailing */ on a separate line Comparisons should place the constant on the right side of the test break is not useful after a goto or return Signed-off-by: Xander Huff Natinst-ReviewBoard-ID: 157395 --- drivers/misc/nirtfeatures.c | 107 ++++++++++++++++++------------------ 1 file changed, 55 insertions(+), 52 deletions(-) diff --git a/drivers/misc/nirtfeatures.c b/drivers/misc/nirtfeatures.c index 6d43c89b7ce4c..01c6af81caaae 100644 --- a/drivers/misc/nirtfeatures.c +++ b/drivers/misc/nirtfeatures.c @@ -68,7 +68,8 @@ /*===================================================================== * ACPI NI physical interface element support - *===================================================================*/ + *===================================================================== + */ #define MAX_NAMELEN 64 #define MAX_NODELEN 128 #define MIN_PIE_CAPS_VERSION 2 @@ -444,7 +445,8 @@ nirtfeatures_led_brightness_get(struct led_classdev *led_cdev) data = inb(led->nirtfeatures->io_base + led->address); /* For the yellow status LED, the blink pattern used for brightness - on write is write-only, so we just return on/off for all LEDs. */ + * on write is write-only, so we just return on/off for all LEDs. + */ return (data & led->mask) ? LED_FULL : LED_OFF; } @@ -484,7 +486,8 @@ static struct nirtfeatures_led nirtfeatures_leds_common[] = { /*===================================================================== * ACPI NI physical interface element support - *===================================================================*/ + *===================================================================== + */ /* Note that callers of this function are responsible for deallocating * the buffer allocated by acpi_evaluate_object() by calling @@ -502,8 +505,8 @@ static int nirtfeatures_call_acpi_method(struct nirtfeatures *nirtfeatures, struct acpi_object_list acpi_params; struct acpi_buffer acpi_result = { ACPI_ALLOCATE_BUFFER, NULL }; - if (NULL == nirtfeatures || NULL == result_size || - NULL == result_buffer) + if (nirtfeatures == NULL || result_size == NULL || + result_buffer == NULL) return -EINVAL; acpi_ret = acpi_get_handle(nirtfeatures->acpi_device->handle, @@ -544,7 +547,7 @@ static int nirtfeatures_pie_set_state(struct nirtfeatures *nirtfeatures, union acpi_object *acpi_buffer; int err = 0; - if (NULL == nirtfeatures) + if (nirtfeatures == NULL) return -EINVAL; pies_args[0].type = ACPI_TYPE_INTEGER; @@ -560,7 +563,7 @@ static int nirtfeatures_pie_set_state(struct nirtfeatures *nirtfeatures, if (err == 0) { acpi_buffer = (union acpi_object *) result_buffer; - if (ACPI_TYPE_INTEGER == acpi_buffer->type) + if (acpi_buffer->type == ACPI_TYPE_INTEGER) err = (int) acpi_buffer->integer.value; kfree(result_buffer); } @@ -580,7 +583,7 @@ static int nirtfeatures_pie_get_state(struct nirtfeatures *nirtfeatures, union acpi_object *acpi_buffer; int err = 0; - if (NULL == nirtfeatures || NULL == result) + if (nirtfeatures == NULL || result == NULL) return -EINVAL; pies_args[0].type = ACPI_TYPE_INTEGER; @@ -594,7 +597,7 @@ static int nirtfeatures_pie_get_state(struct nirtfeatures *nirtfeatures, if (err == 0) { acpi_buffer = (union acpi_object *) result_buffer; - if (ACPI_TYPE_INTEGER == acpi_buffer->type) + if (acpi_buffer->type == ACPI_TYPE_INTEGER) *result = (int) acpi_buffer->integer.value; kfree(result_buffer); } @@ -615,7 +618,7 @@ static int nirtfeatures_pie_enable_notifications( union acpi_object *acpi_buffer; int err = 0; - if (NULL == nirtfeatures) + if (nirtfeatures == NULL) return -EINVAL; pies_args[0].type = ACPI_TYPE_INTEGER; @@ -631,7 +634,7 @@ static int nirtfeatures_pie_enable_notifications( if (err == 0) { acpi_buffer = (union acpi_object *) result_buffer; - if (ACPI_TYPE_INTEGER == acpi_buffer->type) + if (acpi_buffer->type == ACPI_TYPE_INTEGER) err = (int) acpi_buffer->integer.value; kfree(result_buffer); } @@ -691,12 +694,12 @@ static int nirtfeatures_parse_led_pie_color(struct nirtfeatures *nirtfeatures, { unsigned int i; - if (NULL == nirtfeatures || NULL == led_color_descriptor || - NULL == acpi_buffer) + if (nirtfeatures == NULL || led_color_descriptor == NULL || + acpi_buffer == NULL) return -EINVAL; /* element 0 of a PIE LED color caps package is the name */ - if (ACPI_TYPE_BUFFER == acpi_buffer->package.elements[0].type) { + if (acpi_buffer->package.elements[0].type == ACPI_TYPE_BUFFER) { for (i = 0; i < acpi_buffer->package.elements[0].buffer.length; i++) { /* get pointer to Nth Unicode character in name */ @@ -711,14 +714,14 @@ static int nirtfeatures_parse_led_pie_color(struct nirtfeatures *nirtfeatures, return -EINVAL; /* element 1 is the brightness min value */ - if (ACPI_TYPE_INTEGER == acpi_buffer->package.elements[1].type) + if (acpi_buffer->package.elements[1].type == ACPI_TYPE_INTEGER) led_color_descriptor->brightness_range_low = (int) acpi_buffer->package.elements[1].integer.value; else return -EINVAL; /* element 2 is the brightness max value */ - if (ACPI_TYPE_INTEGER == acpi_buffer->package.elements[2].type) + if (acpi_buffer->package.elements[2].type == ACPI_TYPE_INTEGER) led_color_descriptor->brightness_range_high = (int) acpi_buffer->package.elements[2].integer.value; else @@ -744,15 +747,15 @@ static int nirtfeatures_parse_led_pie( int err; int is_wifi, is_user; - if (NULL == nirtfeatures || NULL == pie || - NULL == acpi_buffer) + if (nirtfeatures == NULL || pie == NULL || + acpi_buffer == NULL) return -EINVAL; - if (ACPI_TYPE_PACKAGE != acpi_buffer->type) + if (acpi_buffer->type != ACPI_TYPE_PACKAGE) return -EINVAL; /* element 0 is the number of colors */ - if (ACPI_TYPE_INTEGER == acpi_buffer->package.elements[0].type) { + if (acpi_buffer->package.elements[0].type == ACPI_TYPE_INTEGER) { num_colors = (unsigned int) acpi_buffer->package.elements[0].integer.value; } else { @@ -768,12 +771,13 @@ static int nirtfeatures_parse_led_pie( /* create an LED class device for this LED */ led_dev = kzalloc(sizeof(struct nirtfeatures_led), GFP_KERNEL); - if (NULL == led_dev) + if (led_dev == NULL) return -ENOMEM; /* for compatibility with existing LVRT support, PIEs beginning * with 'user' or 'wifi' should not affix the uservisible - * attribute to their name */ + * attribute to their name + */ is_user = strncasecmp(pie->name, "user", strlen("user")); is_wifi = strncasecmp(pie->name, "wifi", strlen("wifi")); if (is_user != 0 && @@ -809,7 +813,7 @@ static int nirtfeatures_parse_led_pie( err = led_classdev_register(&nirtfeatures->acpi_device->dev, &led_dev->cdev); - if (0 != err) { + if (err != 0) { kfree(led_dev); return err; } @@ -835,14 +839,14 @@ static int nirtfeatures_parse_switch_pie(struct nirtfeatures *nirtfeatures, struct nirtfeatures_switch *switch_dev = NULL; int err = 0; - if (NULL == nirtfeatures || NULL == pie || NULL == acpi_buffer) + if (nirtfeatures == NULL || pie == NULL || acpi_buffer == NULL) return -EINVAL; - if (ACPI_TYPE_PACKAGE != acpi_buffer->type) + if (acpi_buffer->type != ACPI_TYPE_PACKAGE) return -EINVAL; /* element 0 is the number of states */ - if (ACPI_TYPE_INTEGER == acpi_buffer->package.elements[0].type) + if (acpi_buffer->package.elements[0].type == ACPI_TYPE_INTEGER) num_states = (unsigned int) acpi_buffer->package.elements[0].integer.value; else @@ -852,15 +856,15 @@ static int nirtfeatures_parse_switch_pie(struct nirtfeatures *nirtfeatures, switch_descriptor = kzalloc( sizeof(struct nirtfeatures_pie_descriptor_switch) + sizeof(int) * (num_states - 1), GFP_KERNEL); - if (NULL == switch_descriptor) + if (switch_descriptor == NULL) return -ENOMEM; switch_descriptor->num_states = num_states; /* parse individual states in elements 1..N-1 */ for (i = 0; i < num_states; i++) { - if (ACPI_TYPE_INTEGER != - acpi_buffer->package.elements[i + 1].type) { + if (acpi_buffer->package.elements[i + 1].type + != ACPI_TYPE_INTEGER) { err = -EINVAL; goto exit; } @@ -871,13 +875,13 @@ static int nirtfeatures_parse_switch_pie(struct nirtfeatures *nirtfeatures, /* create an input class device for this switch */ switch_dev = kzalloc(sizeof(struct nirtfeatures_switch), GFP_KERNEL); - if (NULL == switch_dev) { + if (switch_dev == NULL) { err = -ENOMEM; goto exit; } switch_dev->cdev = input_allocate_device(); - if (NULL == switch_dev->cdev) { + if (switch_dev->cdev == NULL) { err = -ENOMEM; goto exit_dealloc_switch_dev; } @@ -914,7 +918,7 @@ static int nirtfeatures_parse_switch_pie(struct nirtfeatures *nirtfeatures, set_bit(BTN_0, switch_dev->cdev->keybit); err = input_register_device(switch_dev->cdev); - if (0 != err) { + if (err != 0) { input_free_device(switch_dev->cdev); goto exit_dealloc_switch_dev; } @@ -923,7 +927,7 @@ static int nirtfeatures_parse_switch_pie(struct nirtfeatures *nirtfeatures, if (pie->notification_value != 0) { err = nirtfeatures_pie_enable_notifications(nirtfeatures, pie_element, 0, 1); - if (0 != err) { + if (err != 0) { input_unregister_device(switch_dev->cdev); input_free_device(switch_dev->cdev); goto exit_dealloc_switch_dev; @@ -954,16 +958,16 @@ static int nirtfeatures_parse_one_pie(struct nirtfeatures *nirtfeatures, struct nirtfeatures_pie_descriptor pie; unsigned int i; - if (NULL == nirtfeatures || NULL == acpi_buffer) + if (nirtfeatures == NULL || acpi_buffer == NULL) return -EINVAL; /* check for proper type and number of elements */ - if (ACPI_TYPE_PACKAGE != acpi_buffer->type || - 6 != acpi_buffer->package.count) + if (acpi_buffer->type != ACPI_TYPE_PACKAGE || + acpi_buffer->package.count != 6) return -EINVAL; /* element 0 of the package is the name */ - if (ACPI_TYPE_BUFFER == acpi_buffer->package.elements[0].type) { + if (acpi_buffer->package.elements[0].type == ACPI_TYPE_BUFFER) { for (i = 0; i < acpi_buffer->package.elements[0].buffer.length && i < MAX_NAMELEN; i++) { @@ -978,28 +982,28 @@ static int nirtfeatures_parse_one_pie(struct nirtfeatures *nirtfeatures, return -EINVAL; /* element 1 of the package is the PIE class */ - if (ACPI_TYPE_INTEGER == acpi_buffer->package.elements[1].type) + if (acpi_buffer->package.elements[1].type == ACPI_TYPE_INTEGER) pie.pie_class = (enum nirtfeatures_pie_class) acpi_buffer->package.elements[1].integer.value; else return -EINVAL; /* element 2 of the package is the PIE type */ - if (ACPI_TYPE_INTEGER == acpi_buffer->package.elements[2].type) + if (acpi_buffer->package.elements[2].type == ACPI_TYPE_INTEGER) pie.pie_type = (enum nirtfeatures_pie_type) acpi_buffer->package.elements[2].integer.value; else return -EINVAL; /* element 4 of an package is the visible flag */ - if (ACPI_TYPE_INTEGER == acpi_buffer->package.elements[4].type) + if (acpi_buffer->package.elements[4].type == ACPI_TYPE_INTEGER) pie.is_user_visible = (acpi_buffer->package.elements[4].integer.value != 0); else return -EINVAL; /* element 5 of the package is the notification value */ - if (ACPI_TYPE_INTEGER == acpi_buffer->package.elements[5].type) + if (acpi_buffer->package.elements[5].type == ACPI_TYPE_INTEGER) pie.notification_value = acpi_buffer->package.elements[5].integer.value; else @@ -1022,7 +1026,6 @@ static int nirtfeatures_parse_one_pie(struct nirtfeatures *nirtfeatures, default: return -EINVAL; - break; } return 0; @@ -1041,7 +1044,7 @@ static int nirtfeatures_populate_pies(struct nirtfeatures *nirtfeatures) unsigned int i; unsigned int err = 0; - if (NULL == nirtfeatures) + if (nirtfeatures == NULL) return -EINVAL; /* get the PIE descriptor buffer from DSDT */ @@ -1050,13 +1053,13 @@ static int nirtfeatures_populate_pies(struct nirtfeatures *nirtfeatures) return -1; acpi_buffer = (union acpi_object *) result_buffer; - if (ACPI_TYPE_PACKAGE != acpi_buffer->type) { + if (acpi_buffer->type != ACPI_TYPE_PACKAGE) { err = -1; goto exit; } /* the first element of the package is the caps version */ - if (ACPI_TYPE_INTEGER == acpi_buffer->package.elements[0].type) + if (acpi_buffer->package.elements[0].type == ACPI_TYPE_INTEGER) pie_caps_version = (unsigned int) acpi_buffer->package.elements[0].integer.value; else { @@ -1073,7 +1076,7 @@ static int nirtfeatures_populate_pies(struct nirtfeatures *nirtfeatures) } /* the second element of the package is the number of PIEs */ - if (ACPI_TYPE_INTEGER == acpi_buffer->package.elements[1].type) + if (acpi_buffer->package.elements[1].type == ACPI_TYPE_INTEGER) num_elements = (unsigned int) acpi_buffer->package.elements[1].integer.value; else { @@ -1086,7 +1089,7 @@ static int nirtfeatures_populate_pies(struct nirtfeatures *nirtfeatures) err = nirtfeatures_parse_one_pie(nirtfeatures, pie_caps_version, i - 2, &(acpi_buffer->package.elements[i])); - if (0 != err) + if (err != 0) break; } @@ -1104,7 +1107,7 @@ static int nirtfeatures_create_leds(struct nirtfeatures *nirtfeatures) nirtfeatures_leds_common[i].nirtfeatures = nirtfeatures; - if (0 == nirtfeatures_leds_common[i].cdev.max_brightness) + if (nirtfeatures_leds_common[i].cdev.max_brightness == 0) nirtfeatures_leds_common[i].cdev.max_brightness = 1; nirtfeatures_leds_common[i].cdev.brightness_set = @@ -1423,7 +1426,7 @@ static int nirtfeatures_acpi_add(struct acpi_device *device) spin_lock_init(&nirtfeatures->lock); err = nirtfeatures_populate_pies(nirtfeatures); - if (0 != err) { + if (err != 0) { nirtfeatures_acpi_remove(device); return err; } @@ -1436,13 +1439,13 @@ static int nirtfeatures_acpi_add(struct acpi_device *device) err = sysfs_create_files(&nirtfeatures->acpi_device->dev.kobj, nirtfeatures_attrs); - if (0 != err) { + if (err != 0) { nirtfeatures_acpi_remove(device); return err; } err = nirtfeatures_create_leds(nirtfeatures); - if (0 != err) { + if (err != 0) { nirtfeatures_acpi_remove(device); return err; } @@ -1455,7 +1458,7 @@ static int nirtfeatures_acpi_add(struct acpi_device *device) if (nirtfeatures->has_wifi) { err = nirtfeatures_wifi_regulator_init(&device->dev, nirtfeatures); - if (0 != err) { + if (err != 0) { nirtfeatures_acpi_remove(device); return err; } From 100fd66989ecf58992d0e7246667b937792050a5 Mon Sep 17 00:00:00 2001 From: Akash Mankar Date: Fri, 17 Feb 2017 16:52:58 -0600 Subject: [PATCH 031/100] nirtfeatures: Implement serial IRQ mechanism for user push button. This commit assumes that BIOS will implement a change to add a new field to PIEC capability structure. Also bumping the capabilities version by 1. Adding IRQ mechanism for user Push button instead of GPIO This change registers and requests an IRQ for User push button.Adds a new handler pushbutton_interrupt_handler() to handle the interrupt when the button is pressed or released. Adds a new field to struct nirtfeatures_pie_descriptor called notification_method. If this field is 1, it indicates interrupt mechanism. We check this field only for caps version=3 and pie_type=switch. Also bumps the MAX_PIE_CAPS_VERSION to 3. The kernel and BIOS have to be updated at the same time in order for this change to be successful. If kernel is updated first on a controller, user button will simply not function but will have no other side effects. If BIOS is updated first, then system will end in kernel panic and reboot constantly. Signed-off-by: Akash Mankar Signed-off-by: Brad Mouring Acked-by: Zach Hindes Acked-by: Aaron Rossetto Natinst-ReviewBoard-ID: 174593 --- drivers/misc/nirtfeatures.c | 85 ++++++++++++++++++++++++++++++++++--- 1 file changed, 80 insertions(+), 5 deletions(-) diff --git a/drivers/misc/nirtfeatures.c b/drivers/misc/nirtfeatures.c index 01c6af81caaae..3458cd44efed7 100644 --- a/drivers/misc/nirtfeatures.c +++ b/drivers/misc/nirtfeatures.c @@ -13,6 +13,7 @@ */ #include +#include #include #include #include @@ -73,7 +74,9 @@ #define MAX_NAMELEN 64 #define MAX_NODELEN 128 #define MIN_PIE_CAPS_VERSION 2 -#define MAX_PIE_CAPS_VERSION 2 +#define MAX_PIE_CAPS_VERSION 3 +#define NOTIFY_METHOD_INTERRUPT 1 +#define NOTIFY_METHOD_GPIO 0 enum nirtfeatures_pie_class { PIE_CLASS_INPUT = 0, @@ -92,6 +95,8 @@ struct nirtfeatures_pie_descriptor { enum nirtfeatures_pie_type pie_type; bool is_user_visible; unsigned int notification_value; + /* notification_method applicable only for caps version 3 & above */ + unsigned int notification_method; }; struct nirtfeatures_pie_descriptor_led_color { @@ -122,6 +127,7 @@ struct nirtfeatures { const char *bpstring; bool has_wifi; struct regulator_dev *reg_dev; + unsigned int irq; }; struct nirtfeatures_led { @@ -961,9 +967,14 @@ static int nirtfeatures_parse_one_pie(struct nirtfeatures *nirtfeatures, if (nirtfeatures == NULL || acpi_buffer == NULL) return -EINVAL; - /* check for proper type and number of elements */ + /* + * check for proper type and number of elements + * caps_version 2 or less, support only 6 elements in package + * caps_version 3 or more, support only up to 7 elements in package + */ if (acpi_buffer->type != ACPI_TYPE_PACKAGE || - acpi_buffer->package.count != 6) + (acpi_buffer->package.count != 6 && pie_caps_version < 3) || + (acpi_buffer->package.count > 7 && pie_caps_version >= 3)) return -EINVAL; /* element 0 of the package is the name */ @@ -1005,10 +1016,23 @@ static int nirtfeatures_parse_one_pie(struct nirtfeatures *nirtfeatures, /* element 5 of the package is the notification value */ if (acpi_buffer->package.elements[5].type == ACPI_TYPE_INTEGER) pie.notification_value = - acpi_buffer->package.elements[5].integer.value; + acpi_buffer->package.elements[5].integer.value; else return -EINVAL; + /* + * element 6 of the package is notification method + * used only for pie type switch and caps_Version >= 3 + * don't worry about it for lower caps versions. + */ + if (pie_caps_version >= 3 && pie.pie_type == PIE_TYPE_SWITCH) { + if (acpi_buffer->package.elements[6].type == ACPI_TYPE_INTEGER) + pie.notification_method = + acpi_buffer->package.elements[6].integer.value; + else + return -EINVAL; + } + /* parse the type-specific descriptor in element 3 */ switch (pie.pie_type) { case PIE_TYPE_LED: @@ -1175,13 +1199,64 @@ static void nirtfeatures_remove_switch_pies(struct nirtfeatures *nirtfeatures) spin_unlock(&nirtfeatures->lock); } +/* IRQ Handler for User push button */ +static irqreturn_t pushbutton_interrupt_handler(int irq, void *data) +{ + /* find the switch PIE for which this interrupt was generated */ + struct nirtfeatures_switch *iter; + struct nirtfeatures *nirtfeatures = (struct nirtfeatures *)data; + int state = 0; + + spin_lock(&nirtfeatures->lock); + list_for_each_entry(iter, &nirtfeatures_switch_pie_list, node) { + if (iter->pie_descriptor.notification_method == NOTIFY_METHOD_INTERRUPT && + iter->pie_descriptor.notification_value == irq) { + /* query instantaneous switch state */ + if (!nirtfeatures_pie_get_state(iter->nirtfeatures, + iter->pie_location.element, + iter->pie_location.subelement, + &state)) { + /* push current state of switch */ + input_report_key(iter->cdev, BTN_0, !!state); + input_sync(iter->cdev); + } + spin_unlock(&nirtfeatures->lock); + return IRQ_HANDLED; + } + } + spin_unlock(&nirtfeatures->lock); + return IRQ_NONE; +} + /* ACPI driver */ static acpi_status nirtfeatures_resources(struct acpi_resource *res, void *data) { struct nirtfeatures *nirtfeatures = data; + int err; switch (res->type) { + case ACPI_RESOURCE_TYPE_IRQ: + if (nirtfeatures->irq != 0) { + dev_err(&nirtfeatures->acpi_device->dev, + "too many IRQ resources\n"); + return AE_ERROR; + } + + nirtfeatures->irq = res->data.irq.interrupts[0]; + + err = devm_request_irq(&nirtfeatures->acpi_device->dev, + nirtfeatures->irq, + pushbutton_interrupt_handler, + 0 /*irq_flags*/, MODULE_NAME, + nirtfeatures); + if (err) { + dev_err(&nirtfeatures->acpi_device->dev, + "failed to request IRQ (err %d)\n", err); + return AE_ERROR; + } + return AE_OK; + case ACPI_RESOURCE_TYPE_IO: if ((nirtfeatures->io_base != 0) || (nirtfeatures->io_size != 0)) { @@ -1383,7 +1458,7 @@ static int nirtfeatures_acpi_add(struct acpi_device *device) nirtfeatures->acpi_device = device; acpi_ret = acpi_walk_resources(device->handle, METHOD_NAME__CRS, - nirtfeatures_resources, nirtfeatures); + nirtfeatures_resources, nirtfeatures); if (ACPI_FAILURE(acpi_ret) || (nirtfeatures->io_base == 0) || From 1ebc2fed451dfa555b223f8a5298401c99cfe67e Mon Sep 17 00:00:00 2001 From: Kyle Roeschley Date: Wed, 15 Feb 2017 09:12:38 -0600 Subject: [PATCH 032/100] nirtfeatures: Add Ironclad reset source string On Fire Eagle, the Ironclad ASIC has an internal watchdog which will reset the chip if the its firmware hangs. Unless we're in button- directed safemode, this will also reset the whole system. Add this reset reason to our strings so we can tell when this happens. Signed-off-by: Kyle Roeschley Signed-off-by: Brad Mouring Acked-by: James Minor Acked-by: Zach Brown Acked-by: Akash Mankar Natinst-ReviewBoard-ID: 176049 --- drivers/misc/nirtfeatures.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/misc/nirtfeatures.c b/drivers/misc/nirtfeatures.c index 3458cd44efed7..3077a5dca82fe 100644 --- a/drivers/misc/nirtfeatures.c +++ b/drivers/misc/nirtfeatures.c @@ -219,7 +219,7 @@ static ssize_t nirtfeatures_backplane_id_get(struct device *dev, static DEVICE_ATTR(backplane_id, S_IRUGO, nirtfeatures_backplane_id_get, NULL); static const char * const nirtfeatures_reset_source_strings[] = { - "button", "processor", "fpga", "watchdog", "software", + "button", "processor", "fpga", "watchdog", "software", "ironclad", }; static ssize_t nirtfeatures_reset_source_get(struct device *dev, From f3ab444549a08903b2e5ab3a7367a65a1522528a Mon Sep 17 00:00:00 2001 From: Kyle Roeschley Date: Thu, 16 Mar 2017 14:13:38 -0500 Subject: [PATCH 033/100] nirtfeatures: Use managed resource allocation Adding a new ACPI resource to device BIOS exposed the fact that our error handling on a failed device probe is very broken. To fix this, use managed allocation (devm_*) for all resources which support it. Signed-off-by: Kyle Roeschley Signed-off-by: Brad Mouring Acked-by: James Minor Acked-by: Zach Brown Acked-by: Akash Mankar Natinst-ReviewBoard-ID: 176049 [mpeterse: change return type of nirtfeatures_acpi_remove due to 6c0eb5ba3500] Signed-off-by: Mike Petersen --- drivers/misc/nirtfeatures.c | 191 +++++++++--------------------------- 1 file changed, 48 insertions(+), 143 deletions(-) diff --git a/drivers/misc/nirtfeatures.c b/drivers/misc/nirtfeatures.c index 3077a5dca82fe..fcb6bcdf2ffab 100644 --- a/drivers/misc/nirtfeatures.c +++ b/drivers/misc/nirtfeatures.c @@ -776,7 +776,9 @@ static int nirtfeatures_parse_led_pie( return -EINVAL; /* create an LED class device for this LED */ - led_dev = kzalloc(sizeof(struct nirtfeatures_led), GFP_KERNEL); + led_dev = devm_kzalloc(&nirtfeatures->acpi_device->dev, + sizeof(struct nirtfeatures_led), + GFP_KERNEL); if (led_dev == NULL) return -ENOMEM; @@ -817,12 +819,10 @@ static int nirtfeatures_parse_led_pie( led_dev->pie_location.element = pie_element; led_dev->pie_location.subelement = i; - err = led_classdev_register(&nirtfeatures->acpi_device->dev, - &led_dev->cdev); - if (err != 0) { - kfree(led_dev); + err = devm_led_classdev_register(&nirtfeatures->acpi_device->dev, + &led_dev->cdev); + if (err) return err; - } list_add_tail(&led_dev->node, &nirtfeatures_led_pie_list); } @@ -844,6 +844,7 @@ static int nirtfeatures_parse_switch_pie(struct nirtfeatures *nirtfeatures, struct nirtfeatures_pie_descriptor_switch *switch_descriptor = NULL; struct nirtfeatures_switch *switch_dev = NULL; int err = 0; + struct device *dev = &nirtfeatures->acpi_device->dev; if (nirtfeatures == NULL || pie == NULL || acpi_buffer == NULL) return -EINVAL; @@ -859,9 +860,9 @@ static int nirtfeatures_parse_switch_pie(struct nirtfeatures *nirtfeatures, return -EINVAL; /* allocate storage for switch descriptor */ - switch_descriptor = kzalloc( - sizeof(struct nirtfeatures_pie_descriptor_switch) + - sizeof(int) * (num_states - 1), GFP_KERNEL); + switch_descriptor = devm_kzalloc(dev, sizeof(*switch_descriptor) + + sizeof(int) * (num_states - 1), + GFP_KERNEL); if (switch_descriptor == NULL) return -ENOMEM; @@ -869,28 +870,23 @@ static int nirtfeatures_parse_switch_pie(struct nirtfeatures *nirtfeatures, /* parse individual states in elements 1..N-1 */ for (i = 0; i < num_states; i++) { - if (acpi_buffer->package.elements[i + 1].type - != ACPI_TYPE_INTEGER) { - err = -EINVAL; - goto exit; - } + if (acpi_buffer->package.elements[i + 1].type != + ACPI_TYPE_INTEGER) + return -EINVAL; switch_descriptor->state_value[i] = (int) acpi_buffer->package.elements[i + 1].integer.value; } /* create an input class device for this switch */ - switch_dev = kzalloc(sizeof(struct nirtfeatures_switch), GFP_KERNEL); - if (switch_dev == NULL) { - err = -ENOMEM; - goto exit; - } + switch_dev = devm_kzalloc(dev, sizeof(struct nirtfeatures_switch), + GFP_KERNEL); + if (switch_dev == NULL) + return -ENOMEM; - switch_dev->cdev = input_allocate_device(); - if (switch_dev->cdev == NULL) { - err = -ENOMEM; - goto exit_dealloc_switch_dev; - } + switch_dev->cdev = devm_input_allocate_device(dev); + if (switch_dev->cdev == NULL) + return -ENOMEM; switch_dev->nirtfeatures = nirtfeatures; switch_dev->pie_location.element = pie_element; @@ -924,32 +920,21 @@ static int nirtfeatures_parse_switch_pie(struct nirtfeatures *nirtfeatures, set_bit(BTN_0, switch_dev->cdev->keybit); err = input_register_device(switch_dev->cdev); - if (err != 0) { - input_free_device(switch_dev->cdev); - goto exit_dealloc_switch_dev; - } + if (err) + return err; /* if this PIE supports notifications, enable them now */ if (pie->notification_value != 0) { err = nirtfeatures_pie_enable_notifications(nirtfeatures, - pie_element, 0, 1); - if (err != 0) { - input_unregister_device(switch_dev->cdev); - input_free_device(switch_dev->cdev); - goto exit_dealloc_switch_dev; - } + pie_element, 0, 1); + if (err) + return err; } /* add the new device to our list of switch PIEs */ list_add_tail(&switch_dev->node, &nirtfeatures_switch_pie_list); - goto exit; - -exit_dealloc_switch_dev: - kfree(switch_dev); -exit: - kfree(switch_descriptor); - return err; + return 0; } @@ -1140,8 +1125,8 @@ static int nirtfeatures_create_leds(struct nirtfeatures *nirtfeatures) nirtfeatures_leds_common[i].cdev.brightness_get = nirtfeatures_led_brightness_get; - err = led_classdev_register(&nirtfeatures->acpi_device->dev, - &nirtfeatures_leds_common[i].cdev); + err = devm_led_classdev_register(&nirtfeatures->acpi_device->dev, + &nirtfeatures_leds_common[i].cdev); if (err) return err; } @@ -1149,56 +1134,6 @@ static int nirtfeatures_create_leds(struct nirtfeatures *nirtfeatures) return 0; } -static void nirtfeatures_remove_leds(struct nirtfeatures *nirtfeatures) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(nirtfeatures_leds_common); ++i) - led_classdev_unregister(&nirtfeatures_leds_common[i].cdev); -} - -static void nirtfeatures_remove_led_pies(struct nirtfeatures *nirtfeatures) -{ - struct nirtfeatures_led *cdev_iter; - struct nirtfeatures_led *temp; - - spin_lock(&nirtfeatures->lock); - - /* walk the list of non-fixed LEDs and unregister/free their devices */ - list_for_each_entry_safe( - cdev_iter, temp, &nirtfeatures_led_pie_list, node) { - led_classdev_unregister(&cdev_iter->cdev); - kfree(cdev_iter); - } - - spin_unlock(&nirtfeatures->lock); -} - -static void nirtfeatures_remove_switch_pies(struct nirtfeatures *nirtfeatures) -{ - struct nirtfeatures_switch *cdev_iter; - struct nirtfeatures_switch *temp; - - spin_lock(&nirtfeatures->lock); - - /* walk the list of switch devices and unregister/free each one */ - list_for_each_entry_safe( - cdev_iter, temp, &nirtfeatures_switch_pie_list, node) { - /* disable notifications for this PIE if supported */ - if (cdev_iter->pie_descriptor.notification_value != 0) { - nirtfeatures_pie_enable_notifications(nirtfeatures, - cdev_iter->pie_location.element, - cdev_iter->pie_location.subelement, - 0); - } - input_unregister_device(cdev_iter->cdev); - input_free_device(cdev_iter->cdev); - kfree(cdev_iter); - } - - spin_unlock(&nirtfeatures->lock); -} - /* IRQ Handler for User push button */ static irqreturn_t pushbutton_interrupt_handler(int irq, void *data) { @@ -1323,26 +1258,7 @@ static void nirtfeatures_acpi_notify(struct acpi_device *device, u32 event) static void nirtfeatures_acpi_remove(struct acpi_device *device) { - struct nirtfeatures *nirtfeatures = device->driver_data; - - nirtfeatures_remove_leds(nirtfeatures); - - nirtfeatures_remove_led_pies(nirtfeatures); - nirtfeatures_remove_switch_pies(nirtfeatures); - - sysfs_remove_files(&nirtfeatures->acpi_device->dev.kobj, - nirtfeatures_attrs); - - if (nirtfeatures->reg_dev) - regulator_unregister(nirtfeatures->reg_dev); - - if ((nirtfeatures->io_base != 0) && - (nirtfeatures->io_size == NIRTF_IO_SIZE)) - release_region(nirtfeatures->io_base, nirtfeatures->io_size); - - device->driver_data = NULL; - - kfree(nirtfeatures); + sysfs_remove_files(&device->dev.kobj, nirtfeatures_attrs); } static int nirtfeatures_wifi_regulator_list_voltage(struct regulator_dev *dev, @@ -1431,8 +1347,9 @@ static int nirtfeatures_wifi_regulator_init(struct device *dev, cfg.dev = dev; cfg.init_data = &wifi_reset_init_data; cfg.driver_data = nirtfeatures; - reg_dev = regulator_register(&nirtfeatures_wifi_regulator_desc, - &cfg); + reg_dev = devm_regulator_register(dev, + &nirtfeatures_wifi_regulator_desc, + &cfg); if (IS_ERR(reg_dev)) { pr_err("Failed to register vmmc regulator for wifi\n"); return -ENODEV; @@ -1448,7 +1365,8 @@ static int nirtfeatures_acpi_add(struct acpi_device *device) u8 bpinfo; int err; - nirtfeatures = kzalloc(sizeof(*nirtfeatures), GFP_KERNEL); + nirtfeatures = devm_kzalloc(&device->dev, sizeof(*nirtfeatures), + GFP_KERNEL); if (!nirtfeatures) return -ENOMEM; @@ -1462,16 +1380,12 @@ static int nirtfeatures_acpi_add(struct acpi_device *device) if (ACPI_FAILURE(acpi_ret) || (nirtfeatures->io_base == 0) || - (nirtfeatures->io_size != NIRTF_IO_SIZE)) { - nirtfeatures_acpi_remove(device); + (nirtfeatures->io_size != NIRTF_IO_SIZE)) return -ENODEV; - } - if (!request_region(nirtfeatures->io_base, nirtfeatures->io_size, - MODULE_NAME)) { - nirtfeatures_acpi_remove(device); + if (!devm_request_region(&device->dev, nirtfeatures->io_base, + nirtfeatures->io_size, MODULE_NAME)) return -EBUSY; - } bpinfo = inb(nirtfeatures->io_base + NIRTF_PLATFORM_MISC); @@ -1501,10 +1415,8 @@ static int nirtfeatures_acpi_add(struct acpi_device *device) spin_lock_init(&nirtfeatures->lock); err = nirtfeatures_populate_pies(nirtfeatures); - if (err != 0) { - nirtfeatures_acpi_remove(device); + if (err) return err; - } nirtfeatures->revision[0] = inb(nirtfeatures->io_base + NIRTF_YEAR); nirtfeatures->revision[1] = inb(nirtfeatures->io_base + NIRTF_MONTH); @@ -1512,33 +1424,26 @@ static int nirtfeatures_acpi_add(struct acpi_device *device) nirtfeatures->revision[3] = inb(nirtfeatures->io_base + NIRTF_HOUR); nirtfeatures->revision[4] = inb(nirtfeatures->io_base + NIRTF_MINUTE); - err = sysfs_create_files(&nirtfeatures->acpi_device->dev.kobj, - nirtfeatures_attrs); - if (err != 0) { - nirtfeatures_acpi_remove(device); + err = nirtfeatures_create_leds(nirtfeatures); + if (err) return err; + + if (nirtfeatures->has_wifi) { + err = nirtfeatures_wifi_regulator_init(&device->dev, + nirtfeatures); + if (err) + return err; } - err = nirtfeatures_create_leds(nirtfeatures); - if (err != 0) { - nirtfeatures_acpi_remove(device); + err = sysfs_create_files(&device->dev.kobj, nirtfeatures_attrs); + if (err) return err; - } dev_info(&nirtfeatures->acpi_device->dev, "IO range 0x%04X-0x%04X\n", nirtfeatures->io_base, nirtfeatures->io_base + nirtfeatures->io_size - 1); - if (nirtfeatures->has_wifi) { - err = nirtfeatures_wifi_regulator_init(&device->dev, - nirtfeatures); - if (err != 0) { - nirtfeatures_acpi_remove(device); - return err; - } - } - return 0; } From b19b77564b2477917f38480e4dc9e00630625b19 Mon Sep 17 00:00:00 2001 From: Kyle Roeschley Date: Wed, 14 Mar 2018 18:22:42 -0500 Subject: [PATCH 034/100] nirtfeatures: Add Swordfish backplane ID Add the new Swordfish backplane ID to stop errors on boot. Signed-off-by: Kyle Roeschley Signed-off-by: Brad Mouring Acked-by: Zach Brown Acked-by: Nathan Sullivan Acked-by: Julia Cartwright Natinst-ReviewBoard-ID: 227200 --- drivers/misc/nirtfeatures.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/misc/nirtfeatures.c b/drivers/misc/nirtfeatures.c index fcb6bcdf2ffab..ce35381af5754 100644 --- a/drivers/misc/nirtfeatures.c +++ b/drivers/misc/nirtfeatures.c @@ -47,6 +47,7 @@ #define NIRTF_PLATFORM_MISC_ID_MASK 0x07 #define NIRTF_PLATFORM_MISC_ID_MANHATTAN 0 +#define NIRTF_PLATFORM_MISC_ID_SWORDFISH 1 #define NIRTF_PLATFORM_MISC_ID_FIRE_EAGLE 2 #define NIRTF_PLATFORM_MISC_ID_HAMMERHEAD 4 #define NIRTF_PLATFORM_MISC_ID_WINGHEAD 5 @@ -1398,6 +1399,9 @@ static int nirtfeatures_acpi_add(struct acpi_device *device) case NIRTF_PLATFORM_MISC_ID_FIRE_EAGLE: nirtfeatures->bpstring = "Fire Eagle"; break; + case NIRTF_PLATFORM_MISC_ID_SWORDFISH: + nirtfeatures->bpstring = "Swordfish"; + break; case NIRTF_PLATFORM_MISC_ID_HAMMERHEAD: nirtfeatures->bpstring = "Hammerhead"; break; From 91d93a7e35e00642e3f09a0e55075181692df2b8 Mon Sep 17 00:00:00 2001 From: Kyle Roeschley Date: Wed, 14 Mar 2018 18:23:30 -0500 Subject: [PATCH 035/100] nirtfeatures: Only register bi-color LEDs on supported targets Unlike all previous controllers, Swordfish targets do not have bi-color power and status LEDs. Check our backplane ID and don't register the second color if we're on a Swordfish. Signed-off-by: Kyle Roeschley Signed-off-by: Brad Mouring Acked-by: Zach Brown Acked-by: Nathan Sullivan Acked-by: Julia Cartwright Natinst-ReviewBoard-ID: 227200 Natinst-CAR-ID: 691081 --- drivers/misc/nirtfeatures.c | 130 +++++++++++++++++++++++++----------- 1 file changed, 91 insertions(+), 39 deletions(-) diff --git a/drivers/misc/nirtfeatures.c b/drivers/misc/nirtfeatures.c index ce35381af5754..e3496e2bc405e 100644 --- a/drivers/misc/nirtfeatures.c +++ b/drivers/misc/nirtfeatures.c @@ -125,10 +125,17 @@ struct nirtfeatures { u16 io_size; spinlock_t lock; u8 revision[5]; - const char *bpstring; bool has_wifi; struct regulator_dev *reg_dev; unsigned int irq; + struct nirtfeatures_desc *desc; +}; + +struct nirtfeatures_desc { + unsigned int backplane_id; + const char *name; + struct nirtfeatures_led *leds; + unsigned int num_leds; }; struct nirtfeatures_led { @@ -214,7 +221,7 @@ static ssize_t nirtfeatures_backplane_id_get(struct device *dev, struct acpi_device *acpi_device = to_acpi_device(dev); struct nirtfeatures *nirtfeatures = acpi_device->driver_data; - return sprintf(buf, "%s\n", nirtfeatures->bpstring); + return sprintf(buf, "%s\n", nirtfeatures->desc->name); } static DEVICE_ATTR(backplane_id, S_IRUGO, nirtfeatures_backplane_id_get, NULL); @@ -457,7 +464,7 @@ nirtfeatures_led_brightness_get(struct led_classdev *led_cdev) return (data & led->mask) ? LED_FULL : LED_OFF; } -static struct nirtfeatures_led nirtfeatures_leds_common[] = { +static struct nirtfeatures_led nirtfeatures_leds[] = { { { .name = CONFIG_NI_LED_PREFIX ":status:red", @@ -488,7 +495,67 @@ static struct nirtfeatures_led nirtfeatures_leds_common[] = { }, .address = NIRTF_SYSTEM_LEDS, .mask = NIRTF_SYSTEM_LEDS_POWER_YELLOW, + } +}; + +static struct nirtfeatures_led nirtfeatures_leds_monochrome[] = { + { + { + .name = CONFIG_NI_LED_PREFIX ":status:yellow", + .max_brightness = 0xFFFF, + }, + .address = NIRTF_SYSTEM_LEDS, + .mask = NIRTF_SYSTEM_LEDS_STATUS_YELLOW, + .pattern_hi_addr = NIRTF_STATUS_LED_SHIFT1, + .pattern_lo_addr = NIRTF_STATUS_LED_SHIFT0, }, + { + { + .name = CONFIG_NI_LED_PREFIX ":power:green", + }, + .address = NIRTF_SYSTEM_LEDS, + .mask = NIRTF_SYSTEM_LEDS_POWER_GREEN, + } +}; + +static struct nirtfeatures_desc nirtfeatures_descs[] = { + { + .backplane_id = NIRTF_PLATFORM_MISC_ID_MANHATTAN, + .name = "Manhattan", + .leds = nirtfeatures_leds, + .num_leds = ARRAY_SIZE(nirtfeatures_leds), + }, + { + .backplane_id = NIRTF_PLATFORM_MISC_ID_FIRE_EAGLE, + .name = "Fire Eagle", + .leds = nirtfeatures_leds, + .num_leds = ARRAY_SIZE(nirtfeatures_leds), + }, + { + .backplane_id = NIRTF_PLATFORM_MISC_ID_SWORDFISH, + .name = "Swordfish", + .leds = nirtfeatures_leds_monochrome, + .num_leds = ARRAY_SIZE(nirtfeatures_leds_monochrome), + }, + { + .backplane_id = NIRTF_PLATFORM_MISC_ID_HAMMERHEAD, + .name = "Hammerhead", + .leds = nirtfeatures_leds, + .num_leds = ARRAY_SIZE(nirtfeatures_leds), + }, + { + .backplane_id = NIRTF_PLATFORM_MISC_ID_WINGHEAD, + .name = "Winghead", + .leds = nirtfeatures_leds, + .num_leds = ARRAY_SIZE(nirtfeatures_leds), + } +}; + +static struct nirtfeatures_desc nirtfeatures_desc_unknown = { + .backplane_id = 0xf, + .name = "Unknown", + .leds = nirtfeatures_leds, + .num_leds = ARRAY_SIZE(nirtfeatures_leds), }; /*===================================================================== @@ -907,7 +974,7 @@ static int nirtfeatures_parse_switch_pie(struct nirtfeatures *nirtfeatures, } snprintf(switch_dev->phys_location_string, MAX_NODELEN, "%s/%s/%s", - CONFIG_NI_LED_PREFIX, nirtfeatures->bpstring, pie->name); + CONFIG_NI_LED_PREFIX, nirtfeatures->desc->name, pie->name); switch_dev->cdev->name = switch_dev->name_string; switch_dev->cdev->phys = switch_dev->phys_location_string; @@ -1110,24 +1177,20 @@ static int nirtfeatures_populate_pies(struct nirtfeatures *nirtfeatures) static int nirtfeatures_create_leds(struct nirtfeatures *nirtfeatures) { - int i; - int err; - - for (i = 0; i < ARRAY_SIZE(nirtfeatures_leds_common); ++i) { - - nirtfeatures_leds_common[i].nirtfeatures = nirtfeatures; + struct nirtfeatures_led *leds = nirtfeatures->desc->leds; + int i, err; - if (nirtfeatures_leds_common[i].cdev.max_brightness == 0) - nirtfeatures_leds_common[i].cdev.max_brightness = 1; + for (i = 0; i < nirtfeatures->desc->num_leds; i++) { + leds[i].nirtfeatures = nirtfeatures; - nirtfeatures_leds_common[i].cdev.brightness_set = - nirtfeatures_led_brightness_set; + if (leds[i].cdev.max_brightness == 0) + leds[i].cdev.max_brightness = 1; - nirtfeatures_leds_common[i].cdev.brightness_get = - nirtfeatures_led_brightness_get; + leds[i].cdev.brightness_set = nirtfeatures_led_brightness_set; + leds[i].cdev.brightness_get = nirtfeatures_led_brightness_get; err = devm_led_classdev_register(&nirtfeatures->acpi_device->dev, - &nirtfeatures_leds_common[i].cdev); + &leds[i].cdev); if (err) return err; } @@ -1364,7 +1427,7 @@ static int nirtfeatures_acpi_add(struct acpi_device *device) struct nirtfeatures *nirtfeatures; acpi_status acpi_ret; u8 bpinfo; - int err; + int err, i; nirtfeatures = devm_kzalloc(&device->dev, sizeof(*nirtfeatures), GFP_KERNEL); @@ -1392,28 +1455,17 @@ static int nirtfeatures_acpi_add(struct acpi_device *device) bpinfo &= NIRTF_PLATFORM_MISC_ID_MASK; - switch (bpinfo) { - case NIRTF_PLATFORM_MISC_ID_MANHATTAN: - nirtfeatures->bpstring = "Manhattan"; - break; - case NIRTF_PLATFORM_MISC_ID_FIRE_EAGLE: - nirtfeatures->bpstring = "Fire Eagle"; - break; - case NIRTF_PLATFORM_MISC_ID_SWORDFISH: - nirtfeatures->bpstring = "Swordfish"; - break; - case NIRTF_PLATFORM_MISC_ID_HAMMERHEAD: - nirtfeatures->bpstring = "Hammerhead"; - break; - case NIRTF_PLATFORM_MISC_ID_WINGHEAD: - nirtfeatures->bpstring = "Winghead"; - break; - default: + for (i = 0; i < ARRAY_SIZE(nirtfeatures_descs); i++) { + if (bpinfo == nirtfeatures_descs[i].backplane_id) { + nirtfeatures->desc = &nirtfeatures_descs[i]; + break; + } + } + + if (!nirtfeatures->desc) { dev_err(&nirtfeatures->acpi_device->dev, - "Unrecognized backplane type %u\n", - bpinfo); - nirtfeatures->bpstring = "Unknown"; - break; + "Unrecognized backplane ID %u\n", bpinfo); + nirtfeatures->desc = &nirtfeatures_desc_unknown; } spin_lock_init(&nirtfeatures->lock); From e445df615c06a2c16c772d3688e49fdc891d1da1 Mon Sep 17 00:00:00 2001 From: Gratian Crisan Date: Fri, 20 Aug 2021 15:47:31 -0500 Subject: [PATCH 036/100] nirtfeatures: Automatically select support for NEW_LEDS Prior to commit 7142f92412c1 ("wireless: carl9170: fix LEDS build errors & warnings") support for MAC80211_LEDS, NEW_LEDS and LEDS_CLASS config options was automatically enabled by having CONFIG_CARL9170=m in nati_x86_64_defconfig. The aforementioned commit removed the automatic selection in favor of CARL9170_LEDS config option declaring a dependency on MAC80211_LEDS. This results in linker errors if the nirtfeatures driver is enabled via CONFIG_NI_RT_FEATURES since this driver makes use of functionality provided by the NEW_LEDS and LEDS_CLASS configuration options: LD .tmp_vmlinux.kallsyms1 ld: drivers/misc/nirtfeatures.o: in function `nirtfeatures_parse_led_pie.isra.0': nirtfeatures.c:(.text+0x103b): undefined reference to `devm_led_classdev_register_ext' ld: drivers/misc/nirtfeatures.o: in function `nirtfeatures_acpi_add': nirtfeatures.c:(.text+0x14ad): undefined reference to `devm_led_classdev_register_ext' make: *** [Makefile:1179: vmlinux] Error 1 Automatically select support for NEW_LEDS and by extension LEDS_CLASS if NI_RT_FEATURES is enabled. Signed-off-by: Gratian Crisan --- drivers/misc/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 76727dd1acdb9..a7ee171de3ac5 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -648,6 +648,7 @@ config NI_RT_FEATURES bool "NI 903x/913x support" depends on X86 && ACPI select REGULATOR + select NEW_LEDS help This driver exposes LEDs and other features of NI 903x/913x Real-Time controllers. From d895d6896894c04d954bf336b77bbb492f06d969 Mon Sep 17 00:00:00 2001 From: Kyle Roeschley Date: Fri, 30 Nov 2018 14:34:02 -0600 Subject: [PATCH 037/100] nirtfeatures: Add Dogfish backplane ID and LED info This family uses the same monochrome LEDs as Swordfish. Signed-off-by: Kyle Roeschley Acked-by: Brandon Streiff Acked-by: Gratian Crisan Acked-by: Julia Cartwright Natinst-ReviewBoard-ID: 273119 --- drivers/misc/nirtfeatures.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/misc/nirtfeatures.c b/drivers/misc/nirtfeatures.c index e3496e2bc405e..449efb186f910 100644 --- a/drivers/misc/nirtfeatures.c +++ b/drivers/misc/nirtfeatures.c @@ -49,6 +49,7 @@ #define NIRTF_PLATFORM_MISC_ID_MANHATTAN 0 #define NIRTF_PLATFORM_MISC_ID_SWORDFISH 1 #define NIRTF_PLATFORM_MISC_ID_FIRE_EAGLE 2 +#define NIRTF_PLATFORM_MISC_ID_DOGFISH 3 #define NIRTF_PLATFORM_MISC_ID_HAMMERHEAD 4 #define NIRTF_PLATFORM_MISC_ID_WINGHEAD 5 @@ -537,6 +538,12 @@ static struct nirtfeatures_desc nirtfeatures_descs[] = { .leds = nirtfeatures_leds_monochrome, .num_leds = ARRAY_SIZE(nirtfeatures_leds_monochrome), }, + { + .backplane_id = NIRTF_PLATFORM_MISC_ID_DOGFISH, + .name = "Dogfish", + .leds = nirtfeatures_leds_monochrome, + .num_leds = ARRAY_SIZE(nirtfeatures_leds_monochrome), + }, { .backplane_id = NIRTF_PLATFORM_MISC_ID_HAMMERHEAD, .name = "Hammerhead", From 62785c4798746e5ba8decdbadd58d57e4553814d Mon Sep 17 00:00:00 2001 From: Jeff Westfahl Date: Mon, 16 Dec 2013 10:44:59 -0600 Subject: [PATCH 038/100] niwatchdog: Added NI Watchdog driver Added an NI Watchdog driver. This is an ACPI device that exposes the NI Watchdog hardware interface. Not all of the proposed features of the device work as expected. Development work on this device by the hardware team is currently not a high priority. These issues will be addressed once the hardware team gets back to this device. Signed-off-by: Jeff Westfahl [mpeterse: change return type of niwatchdog_acpi_remove due to 6c0eb5ba3500] Signed-off-by: Mike Petersen --- drivers/misc/Kconfig | 9 ++ drivers/misc/Makefile | 1 + drivers/misc/niwatchdog.c | 252 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 262 insertions(+) create mode 100644 drivers/misc/niwatchdog.c diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index a7ee171de3ac5..2504de4c99b8e 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -666,6 +666,15 @@ config NI_LED_PREFIX If unsure, use the default. +config NI_WATCHDOG + bool "NI Watchdog support for NI 903x/913x" + depends on X86 && ACPI + help + This driver exposes the NI Watchdog feature of NI 903x/913x Real-Time + controllers. + + If unsure, say N (but it's safe to say "Y"). + source "drivers/misc/c2port/Kconfig" source "drivers/misc/eeprom/Kconfig" source "drivers/misc/cb710/Kconfig" diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 21f053b719f3f..2ce11031cd58f 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -76,3 +76,4 @@ obj-y += keba/ obj-y += amd-sbi/ obj-$(CONFIG_MISC_RP1) += rp1/ obj-$(CONFIG_NI_RT_FEATURES) += nirtfeatures.o +obj-$(CONFIG_NI_WATCHDOG) += niwatchdog.o diff --git a/drivers/misc/niwatchdog.c b/drivers/misc/niwatchdog.c new file mode 100644 index 0000000000000..bdd9417311604 --- /dev/null +++ b/drivers/misc/niwatchdog.c @@ -0,0 +1,252 @@ +/* + * Copyright (C) 2013 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 + +#define MODULE_NAME "niwatchdog" + +#define NIWD_CONTROL 0x01 +#define NIWD_COUNTER2 0x02 +#define NIWD_COUNTER1 0x03 +#define NIWD_COUNTER0 0x04 +#define NIWD_SEED2 0x05 +#define NIWD_SEED1 0x06 +#define NIWD_SEED0 0x07 + +#define NIWD_IO_SIZE 0x08 + +#define NIWD_CONTROL_MODE 0x80 +#define NIWD_CONTROL_RESET 0x02 + +struct niwatchdog { + struct acpi_device *acpi_device; + u16 io_base; + u16 io_size; + u32 irq; + spinlock_t lock; +}; + +static ssize_t niwatchdog_wdmode_get(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct acpi_device *acpi_device = to_acpi_device(dev); + struct niwatchdog *niwatchdog = acpi_device->driver_data; + u8 data; + + data = inb(niwatchdog->io_base + NIWD_CONTROL); + + data &= NIWD_CONTROL_MODE; + + return sprintf(buf, "%s\n", data ? "boot" : "user"); +} + +static ssize_t niwatchdog_wdmode_set(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct acpi_device *acpi_device = to_acpi_device(dev); + struct niwatchdog *niwatchdog = acpi_device->driver_data; + u8 data; + + /* you can only switch boot->user */ + if (strcmp(buf, "user")) + return -EINVAL; + + data = NIWD_CONTROL_MODE | NIWD_CONTROL_RESET; + + outb(data, niwatchdog->io_base + NIWD_CONTROL); + + return count; +} + +static DEVICE_ATTR(watchdog_mode, S_IRUSR|S_IWUSR, niwatchdog_wdmode_get, + niwatchdog_wdmode_set); + +static ssize_t niwatchdog_register_dump_get(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct acpi_device *acpi_device = to_acpi_device(dev); + struct niwatchdog *niwatchdog = acpi_device->driver_data; + u8 control, counter2, counter1, counter0; + u8 seed2, seed1, seed0; + + control = inb(niwatchdog->io_base + NIWD_CONTROL); + counter2 = inb(niwatchdog->io_base + NIWD_COUNTER2); + counter1 = inb(niwatchdog->io_base + NIWD_COUNTER1); + counter0 = inb(niwatchdog->io_base + NIWD_COUNTER0); + seed2 = inb(niwatchdog->io_base + NIWD_SEED2); + seed1 = inb(niwatchdog->io_base + NIWD_SEED1); + seed0 = inb(niwatchdog->io_base + NIWD_SEED0); + + return sprintf(buf, + "Control: 0x%02X\n" + "Counter 2: 0x%02X\n" + "Counter 1: 0x%02X\n" + "Counter 0: 0x%02X\n" + "Seed 2: 0x%02X\n" + "Seed 1: 0x%02X\n" + "Seed 0: 0x%02X\n", + control, counter2, counter1, counter0, + seed2, seed1, seed0); +} + +static DEVICE_ATTR(register_dump, S_IRUGO, niwatchdog_register_dump_get, NULL); + +static const struct attribute *niwatchdog_attrs[] = { + &dev_attr_watchdog_mode.attr, + &dev_attr_register_dump.attr, + NULL +}; + +static acpi_status niwatchdog_resources(struct acpi_resource *res, void *data) +{ + struct niwatchdog *niwatchdog = data; + + switch (res->type) { + case ACPI_RESOURCE_TYPE_IO: + if ((niwatchdog->io_base != 0) || + (niwatchdog->io_size != 0)) { + dev_err(&niwatchdog->acpi_device->dev, + "too many IO resources\n"); + return AE_ERROR; + } + + niwatchdog->io_base = res->data.io.minimum; + niwatchdog->io_size = res->data.io.address_length; + + return AE_OK; + + case ACPI_RESOURCE_TYPE_IRQ: + if (niwatchdog->irq != 0) { + dev_err(&niwatchdog->acpi_device->dev, + "too many IRQ resources\n"); + return AE_ERROR; + } + + niwatchdog->irq = res->data.irq.interrupts[0]; + + return AE_OK; + + case ACPI_RESOURCE_TYPE_END_TAG: + return AE_OK; + + default: + dev_err(&niwatchdog->acpi_device->dev, + "unsupported resource type %d\n", + res->type); + return AE_ERROR; + } + + return AE_OK; +} + +static void niwatchdog_acpi_remove(struct acpi_device *device) +{ + struct niwatchdog *niwatchdog = device->driver_data; + + sysfs_remove_files(&niwatchdog->acpi_device->dev.kobj, + niwatchdog_attrs); + + if ((niwatchdog->io_base != 0) && + (niwatchdog->io_size == NIWD_IO_SIZE)) + release_region(niwatchdog->io_base, niwatchdog->io_size); + + device->driver_data = NULL; + + kfree(niwatchdog); +} + +static int niwatchdog_acpi_add(struct acpi_device *device) +{ + struct niwatchdog *niwatchdog; + acpi_status acpi_ret; + int err; + + niwatchdog = kzalloc(sizeof(*niwatchdog), GFP_KERNEL); + + if (!niwatchdog) + return -ENOMEM; + + device->driver_data = niwatchdog; + + niwatchdog->acpi_device = device; + + acpi_ret = acpi_walk_resources(device->handle, METHOD_NAME__CRS, + niwatchdog_resources, niwatchdog); + + if (ACPI_FAILURE(acpi_ret) || + (niwatchdog->io_base == 0) || + (niwatchdog->io_size != NIWD_IO_SIZE) || + (niwatchdog->irq == 0)) { + niwatchdog_acpi_remove(device); + return -ENODEV; + } + + if (!request_region(niwatchdog->io_base, niwatchdog->io_size, + MODULE_NAME)) { + niwatchdog_acpi_remove(device); + return -EBUSY; + } + + err = sysfs_create_files(&niwatchdog->acpi_device->dev.kobj, + niwatchdog_attrs); + if (err) { + niwatchdog_acpi_remove(device); + return err; + } + + spin_lock_init(&niwatchdog->lock); + + dev_info(&niwatchdog->acpi_device->dev, + "IO range 0x%04X-0x%04X, IRQ %d\n", + niwatchdog->io_base, + niwatchdog->io_base + niwatchdog->io_size - 1, niwatchdog->irq); + + return 0; +} + +static const struct acpi_device_id niwatchdog_device_ids[] = { + {"NIC775C", 0}, + {"", 0}, +}; + +static struct acpi_driver niwatchdog_acpi_driver = { + .name = MODULE_NAME, + .ids = niwatchdog_device_ids, + .ops = { + .add = niwatchdog_acpi_add, + .remove = niwatchdog_acpi_remove, + }, +}; + +static int __init niwatchdog_init(void) +{ + return acpi_bus_register_driver(&niwatchdog_acpi_driver); +} + +static void __exit niwatchdog_exit(void) +{ + acpi_bus_unregister_driver(&niwatchdog_acpi_driver); +} + +module_init(niwatchdog_init); +module_exit(niwatchdog_exit); + +MODULE_DEVICE_TABLE(acpi, niwatchdog_device_ids); +MODULE_DESCRIPTION("NI Watchdog"); +MODULE_AUTHOR("Jeff Westfahl "); +MODULE_LICENSE("GPL"); From 922e5cab6fc5c26497274218d72dde1fa5c74b20 Mon Sep 17 00:00:00 2001 From: Jeff Westfahl Date: Wed, 5 Mar 2014 09:50:05 -0600 Subject: [PATCH 039/100] niwatchdog: Added ioctl interface for NI Watchdog Added a new header file with an ioctl interface for NI Watchdog. This file is installed as part of 'make headers_install'. Signed-off-by: Jeff Westfahl [gratian: fix Kbuild conflict, no need to explicitly list headers anymore] Signed-off-by: Gratian Crisan --- include/uapi/linux/niwatchdog.h | 39 +++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 include/uapi/linux/niwatchdog.h diff --git a/include/uapi/linux/niwatchdog.h b/include/uapi/linux/niwatchdog.h new file mode 100644 index 0000000000000..804d45f0243fa --- /dev/null +++ b/include/uapi/linux/niwatchdog.h @@ -0,0 +1,39 @@ +/* + * 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 _LINUX_NIWATCHDOG_H_ +#define _LINUX_NIWATCHDOG_H_ + +#include +#include + +#define NIWATCHDOG_ACTION_INTERRUPT 0 +#define NIWATCHDOG_ACTION_RESET 1 + +#define NIWATCHDOG_STATE_RUNNING 0 +#define NIWATCHDOG_STATE_EXPIRED 1 + +#define NIWATCHDOG_IOCTL_PERIOD_NS _IOR('W', 0, __u32) +#define NIWATCHDOG_IOCTL_MAX_COUNTER _IOR('W', 1, __u32) +#define NIWATCHDOG_IOCTL_COUNTER_SET _IOW('W', 2, __u32) +#define NIWATCHDOG_IOCTL_CHECK_ACTION _IOW('W', 3, __u32) +#define NIWATCHDOG_IOCTL_ADD_ACTION _IOW('W', 4, __u32) +#define NIWATCHDOG_IOCTL_START _IO('W', 5) +#define NIWATCHDOG_IOCTL_PET _IOR('W', 6, __u32) +#define NIWATCHDOG_IOCTL_RESET _IO('W', 7) +#define NIWATCHDOG_IOCTL_COUNTER_GET _IOR('W', 8, __u32) + +#define NIWATCHDOG_NAME "niwatchdog" + +#endif /* _LINUX_NIWATCHDOG_H_ */ From 79a3971cbed81d7b632d57e8e6ba19dc8518f9f9 Mon Sep 17 00:00:00 2001 From: Jeff Westfahl Date: Thu, 6 Mar 2014 11:07:15 -0600 Subject: [PATCH 040/100] niwatchdog: Added NIWATCHDOG_STATE_DISABLED Signed-off-by: Jeff Westfahl --- include/uapi/linux/niwatchdog.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/uapi/linux/niwatchdog.h b/include/uapi/linux/niwatchdog.h index 804d45f0243fa..a5931a4c8a277 100644 --- a/include/uapi/linux/niwatchdog.h +++ b/include/uapi/linux/niwatchdog.h @@ -23,6 +23,7 @@ #define NIWATCHDOG_STATE_RUNNING 0 #define NIWATCHDOG_STATE_EXPIRED 1 +#define NIWATCHDOG_STATE_DISABLED 2 #define NIWATCHDOG_IOCTL_PERIOD_NS _IOR('W', 0, __u32) #define NIWATCHDOG_IOCTL_MAX_COUNTER _IOR('W', 1, __u32) From 77b15b5838f3f29f94f1b62afc9a96d4299a1908 Mon Sep 17 00:00:00 2001 From: Jeff Westfahl Date: Thu, 6 Mar 2014 11:17:36 -0600 Subject: [PATCH 041/100] niwatchdog: Implemented NI Watchdog for NI Linux x64 targets. Signed-off-by: Jeff Westfahl --- drivers/misc/niwatchdog.c | 363 +++++++++++++++++++++++++++++++++++++- 1 file changed, 361 insertions(+), 2 deletions(-) diff --git a/drivers/misc/niwatchdog.c b/drivers/misc/niwatchdog.c index bdd9417311604..0e67f87463aee 100644 --- a/drivers/misc/niwatchdog.c +++ b/drivers/misc/niwatchdog.c @@ -14,6 +14,10 @@ #include #include +#include +#include +#include +#include #define MODULE_NAME "niwatchdog" @@ -27,8 +31,18 @@ #define NIWD_IO_SIZE 0x08 -#define NIWD_CONTROL_MODE 0x80 -#define NIWD_CONTROL_RESET 0x02 +#define NIWD_CONTROL_MODE 0x80 +#define NIWD_CONTROL_PROC_INTERRUPT 0x40 +#define NIWD_CONTROL_PROC_RESET 0x20 +#define NIWD_CONTROL_PET 0x10 +#define NIWD_CONTROL_RUNNING 0x08 +#define NIWD_CONTROL_CAPTURECOUNTER 0x04 +#define NIWD_CONTROL_RESET 0x02 +#define NIWD_CONTROL_ALARM 0x01 + +#define NIWD_PERIOD_NS 30720 +#define NIWD_MAX_COUNTER 0x00FFFFFF + struct niwatchdog { struct acpi_device *acpi_device; @@ -36,6 +50,11 @@ struct niwatchdog { u16 io_size; u32 irq; spinlock_t lock; + struct miscdevice misc_dev; + atomic_t available; + wait_queue_head_t irq_event; + u32 running:1; + u32 expired:1; }; static ssize_t niwatchdog_wdmode_get(struct device *dev, @@ -65,6 +84,12 @@ static ssize_t niwatchdog_wdmode_set(struct device *dev, if (strcmp(buf, "user")) return -EINVAL; + data = inb(niwatchdog->io_base + NIWD_CONTROL); + + /* Check if we're already in user mode. */ + if (!(data & NIWD_CONTROL_MODE)) + return count; + data = NIWD_CONTROL_MODE | NIWD_CONTROL_RESET; outb(data, niwatchdog->io_base + NIWD_CONTROL); @@ -112,6 +137,323 @@ static const struct attribute *niwatchdog_attrs[] = { NULL }; +static int niwatchdog_counter_set(struct niwatchdog *niwatchdog, u32 counter) +{ + int ret; + unsigned long flags; + + spin_lock_irqsave(&niwatchdog->lock, flags); + + /* Prevent changing the counter while the watchdog is running. */ + if (niwatchdog->running) { + ret = -EBUSY; + goto out_unlock; + } + + outb(((0x00FF0000 & counter) >> 16), niwatchdog->io_base + NIWD_SEED2); + outb(((0x0000FF00 & counter) >> 8), niwatchdog->io_base + NIWD_SEED1); + outb((0x000000FF & counter), niwatchdog->io_base + NIWD_SEED0); + + ret = 0; + +out_unlock: + spin_unlock_irqrestore(&niwatchdog->lock, flags); + + return ret; +} + +static int niwatchdog_check_action(u32 action) +{ + int err = 0; + + switch (action) { + case NIWD_CONTROL_PROC_INTERRUPT: + case NIWD_CONTROL_PROC_RESET: + break; + default: + err = -ENOTSUPP; + } + + return err; +} + +static int niwatchdog_add_action(struct niwatchdog *niwatchdog, u32 action) +{ + u8 action_mask; + u8 control; + unsigned long flags; + + if (action == NIWATCHDOG_ACTION_INTERRUPT) + action_mask = NIWD_CONTROL_PROC_INTERRUPT; + else if (action == NIWATCHDOG_ACTION_RESET) + action_mask = NIWD_CONTROL_PROC_RESET; + else + return -ENOTSUPP; + + spin_lock_irqsave(&niwatchdog->lock, flags); + + control = inb(niwatchdog->io_base + NIWD_CONTROL); + control |= action_mask; + outb(control, niwatchdog->io_base + NIWD_CONTROL); + + spin_unlock_irqrestore(&niwatchdog->lock, flags); + + return 0; +} + +static int niwatchdog_start(struct niwatchdog *niwatchdog) +{ + u8 control; + unsigned long flags; + + spin_lock_irqsave(&niwatchdog->lock, flags); + + niwatchdog->running = true; + niwatchdog->expired = false; + + control = inb(niwatchdog->io_base + NIWD_CONTROL); + outb(control | NIWD_CONTROL_RESET, niwatchdog->io_base + NIWD_CONTROL); + outb(control | NIWD_CONTROL_PET, niwatchdog->io_base + NIWD_CONTROL); + + spin_unlock_irqrestore(&niwatchdog->lock, flags); + + return 0; +} + +static int niwatchdog_pet(struct niwatchdog *niwatchdog, u32 *state) +{ + u8 control; + unsigned long flags; + + spin_lock_irqsave(&niwatchdog->lock, flags); + + if (niwatchdog->expired) { + *state = NIWATCHDOG_STATE_EXPIRED; + } else if (!niwatchdog->running) { + *state = NIWATCHDOG_STATE_DISABLED; + } else { + control = inb(niwatchdog->io_base + NIWD_CONTROL); + control |= NIWD_CONTROL_PET; + outb(control, niwatchdog->io_base + NIWD_CONTROL); + + *state = NIWATCHDOG_STATE_RUNNING; + } + + spin_unlock_irqrestore(&niwatchdog->lock, flags); + + return 0; +} + +static int niwatchdog_reset(struct niwatchdog *niwatchdog) +{ + unsigned long flags; + + spin_lock_irqsave(&niwatchdog->lock, flags); + + niwatchdog->running = false; + niwatchdog->expired = false; + + outb(NIWD_CONTROL_RESET, niwatchdog->io_base + NIWD_CONTROL); + + spin_unlock_irqrestore(&niwatchdog->lock, flags); + + return 0; +} + +static int niwatchdog_counter_get(struct niwatchdog *niwatchdog, + u32 *counter) +{ + u8 control; + u8 counter2, counter1, counter0; + unsigned long flags; + + spin_lock_irqsave(&niwatchdog->lock, flags); + + control = inb(niwatchdog->io_base + NIWD_CONTROL); + control |= NIWD_CONTROL_CAPTURECOUNTER; + outb(control, niwatchdog->io_base + NIWD_CONTROL); + + counter2 = inb(niwatchdog->io_base + NIWD_COUNTER2); + counter1 = inb(niwatchdog->io_base + NIWD_COUNTER1); + counter0 = inb(niwatchdog->io_base + NIWD_COUNTER0); + + *counter = (counter2 << 16) | (counter1 << 8) | counter0; + + spin_unlock_irqrestore(&niwatchdog->lock, flags); + + return 0; +} + +static irqreturn_t niwatchdog_irq(int irq, void *data) +{ + struct niwatchdog *niwatchdog = data; + irqreturn_t ret = IRQ_NONE; + u8 control; + unsigned long flags; + + spin_lock_irqsave(&niwatchdog->lock, flags); + + control = inb(niwatchdog->io_base + NIWD_CONTROL); + + if (!(NIWD_CONTROL_ALARM & control)) { + dev_err(&niwatchdog->acpi_device->dev, + "Spurious watchdog interrupt, 0x%02X\n", control); + goto out_unlock; + } + + niwatchdog->running = false; + niwatchdog->expired = true; + + /* Acknowledge the interrupt. */ + control |= NIWD_CONTROL_RESET; + outb(control, niwatchdog->io_base + NIWD_CONTROL); + + /* Signal the watchdog event. */ + wake_up_all(&niwatchdog->irq_event); + + ret = IRQ_HANDLED; + +out_unlock: + spin_unlock_irqrestore(&niwatchdog->lock, flags); + + return ret; +} + +static int niwatchdog_misc_open(struct inode *inode, struct file *file) +{ + struct miscdevice *misc_dev = file->private_data; + struct niwatchdog *niwatchdog = container_of( + misc_dev, struct niwatchdog, misc_dev); + + file->private_data = niwatchdog; + + if (!atomic_dec_and_test(&niwatchdog->available)) { + atomic_inc(&niwatchdog->available); + return -EBUSY; + } + + return request_irq(niwatchdog->irq, niwatchdog_irq, 0, + NIWATCHDOG_NAME, niwatchdog); +} + +static int niwatchdog_misc_release(struct inode *inode, struct file *file) +{ + struct niwatchdog *niwatchdog = file->private_data; + + free_irq(niwatchdog->irq, niwatchdog); + atomic_inc(&niwatchdog->available); + return 0; +} + +static long niwatchdog_misc_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + struct niwatchdog *niwatchdog = file->private_data; + int err; + + switch (cmd) { + case NIWATCHDOG_IOCTL_PERIOD_NS: { + __u32 period = NIWD_PERIOD_NS; + + err = copy_to_user((__u32 *)arg, &period, + sizeof(__u32)); + break; + } + case NIWATCHDOG_IOCTL_MAX_COUNTER: { + __u32 counter = NIWD_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 = niwatchdog_counter_set(niwatchdog, counter); + break; + } + case NIWATCHDOG_IOCTL_CHECK_ACTION: { + __u32 action; + + err = copy_from_user(&action, (__u32 *)arg, + sizeof(__u32)); + if (!err) + err = niwatchdog_check_action(action); + break; + } + case NIWATCHDOG_IOCTL_ADD_ACTION: { + __u32 action; + err = copy_from_user(&action, (__u32 *)arg, + sizeof(__u32)); + if (!err) + err = niwatchdog_add_action(niwatchdog, action); + break; + } + case NIWATCHDOG_IOCTL_START: { + err = niwatchdog_start(niwatchdog); + break; + } + case NIWATCHDOG_IOCTL_PET: { + __u32 state; + + err = niwatchdog_pet(niwatchdog, &state); + if (!err) + err = copy_to_user((__u32 *)arg, &state, + sizeof(__u32)); + break; + } + case NIWATCHDOG_IOCTL_RESET: { + err = niwatchdog_reset(niwatchdog); + break; + } + case NIWATCHDOG_IOCTL_COUNTER_GET: { + __u32 counter; + + err = niwatchdog_counter_get(niwatchdog, &counter); + if (!err) { + err = copy_to_user((__u32 *)arg, &counter, + sizeof(__u32)); + } + break; + } + default: + err = -EINVAL; + break; + }; + + return err; +} + +unsigned int niwatchdog_misc_poll(struct file *file, + struct poll_table_struct *wait) +{ + struct niwatchdog *niwatchdog = file->private_data; + unsigned int mask = 0; + unsigned long flags; + + poll_wait(file, &niwatchdog->irq_event, wait); + + spin_lock_irqsave(&niwatchdog->lock, flags); + + if (niwatchdog->expired) + mask = POLLIN; + + spin_unlock_irqrestore(&niwatchdog->lock, flags); + + return mask; +} + +static const struct file_operations niwatchdog_misc_fops = { + .owner = THIS_MODULE, + .open = niwatchdog_misc_open, + .release = niwatchdog_misc_release, + .unlocked_ioctl = niwatchdog_misc_ioctl, + .poll = niwatchdog_misc_poll, +}; + static acpi_status niwatchdog_resources(struct acpi_resource *res, void *data) { struct niwatchdog *niwatchdog = data; @@ -158,6 +500,8 @@ static void niwatchdog_acpi_remove(struct acpi_device *device) { struct niwatchdog *niwatchdog = device->driver_data; + misc_deregister(&niwatchdog->misc_dev); + sysfs_remove_files(&niwatchdog->acpi_device->dev.kobj, niwatchdog_attrs); @@ -211,6 +555,21 @@ static int niwatchdog_acpi_add(struct acpi_device *device) spin_lock_init(&niwatchdog->lock); + atomic_set(&niwatchdog->available, 1); + init_waitqueue_head(&niwatchdog->irq_event); + niwatchdog->expired = false; + + niwatchdog->misc_dev.minor = MISC_DYNAMIC_MINOR; + niwatchdog->misc_dev.name = NIWATCHDOG_NAME; + niwatchdog->misc_dev.fops = &niwatchdog_misc_fops; + + err = misc_register(&niwatchdog->misc_dev); + + if (err) { + niwatchdog_acpi_remove(device); + return err; + } + dev_info(&niwatchdog->acpi_device->dev, "IO range 0x%04X-0x%04X, IRQ %d\n", niwatchdog->io_base, From 331c439eb083d2c32e10bc686920e0d77e58e670 Mon Sep 17 00:00:00 2001 From: Jeff Westfahl Date: Thu, 10 Apr 2014 16:40:22 -0500 Subject: [PATCH 042/100] niwatchdog: remove register_dump Removed the register_dump sysfs file. The watchdog works well, there's no longer a need for this debugging file. Signed-off-by: Jeff Westfahl --- drivers/misc/niwatchdog.c | 32 -------------------------------- 1 file changed, 32 deletions(-) diff --git a/drivers/misc/niwatchdog.c b/drivers/misc/niwatchdog.c index 0e67f87463aee..b591d5fbe493b 100644 --- a/drivers/misc/niwatchdog.c +++ b/drivers/misc/niwatchdog.c @@ -100,40 +100,8 @@ static ssize_t niwatchdog_wdmode_set(struct device *dev, static DEVICE_ATTR(watchdog_mode, S_IRUSR|S_IWUSR, niwatchdog_wdmode_get, niwatchdog_wdmode_set); -static ssize_t niwatchdog_register_dump_get(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct acpi_device *acpi_device = to_acpi_device(dev); - struct niwatchdog *niwatchdog = acpi_device->driver_data; - u8 control, counter2, counter1, counter0; - u8 seed2, seed1, seed0; - - control = inb(niwatchdog->io_base + NIWD_CONTROL); - counter2 = inb(niwatchdog->io_base + NIWD_COUNTER2); - counter1 = inb(niwatchdog->io_base + NIWD_COUNTER1); - counter0 = inb(niwatchdog->io_base + NIWD_COUNTER0); - seed2 = inb(niwatchdog->io_base + NIWD_SEED2); - seed1 = inb(niwatchdog->io_base + NIWD_SEED1); - seed0 = inb(niwatchdog->io_base + NIWD_SEED0); - - return sprintf(buf, - "Control: 0x%02X\n" - "Counter 2: 0x%02X\n" - "Counter 1: 0x%02X\n" - "Counter 0: 0x%02X\n" - "Seed 2: 0x%02X\n" - "Seed 1: 0x%02X\n" - "Seed 0: 0x%02X\n", - control, counter2, counter1, counter0, - seed2, seed1, seed0); -} - -static DEVICE_ATTR(register_dump, S_IRUGO, niwatchdog_register_dump_get, NULL); - static const struct attribute *niwatchdog_attrs[] = { &dev_attr_watchdog_mode.attr, - &dev_attr_register_dump.attr, NULL }; From 5a9605343378f243b1e1e4ab7599b6806b3cae31 Mon Sep 17 00:00:00 2001 From: Kyle Roeschley Date: Fri, 19 Feb 2016 14:27:22 -0600 Subject: [PATCH 043/100] niwatchdog: Explicitly request threaded interrupt Requesting a threaded interrupt explicity and doing so with a NULL handler/non-NULL thread_fn avoids disabling softirqs while the handler executes. This does require setting IRQF_ONESHOT, which was set automatically when using request_irq before. Signed-off-by: Kyle Roeschley Signed-off-by: Brad Mouring Acked-by: Josh Cartwright Natinst-ReviewBoard-ID: 127047 --- drivers/misc/niwatchdog.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/misc/niwatchdog.c b/drivers/misc/niwatchdog.c index b591d5fbe493b..25114df5c19db 100644 --- a/drivers/misc/niwatchdog.c +++ b/drivers/misc/niwatchdog.c @@ -300,8 +300,8 @@ static int niwatchdog_misc_open(struct inode *inode, struct file *file) return -EBUSY; } - return request_irq(niwatchdog->irq, niwatchdog_irq, 0, - NIWATCHDOG_NAME, niwatchdog); + return request_threaded_irq(niwatchdog->irq, NULL, niwatchdog_irq, + IRQF_ONESHOT, NIWATCHDOG_NAME, niwatchdog); } static int niwatchdog_misc_release(struct inode *inode, struct file *file) From 0d19fd7336199571e4c9d867cd4788286c2ebf0a Mon Sep 17 00:00:00 2001 From: Kyle Roeschley Date: Mon, 7 Aug 2017 15:17:44 -0500 Subject: [PATCH 044/100] niwatchdog: Fix error path in ACPI add Use device-managed resource allocation where possible and clean up correctly in the event of an error during ACPI add. Signed-off-by: Kyle Roeschley Signed-off-by: Brad Mouring Acked-by: Zach Brown Acked-by: James Minor Acked-by: Ovidiu Vancea Acked-by: Julia Cartwright Natinst-ReviewBoard-ID: 196333 [mpeterse: change return type of niwatchdog_acpi_remove due to 6c0eb5ba3500] Signed-off-by: Mike Petersen --- drivers/misc/niwatchdog.c | 94 +++++++++++++-------------------------- 1 file changed, 32 insertions(+), 62 deletions(-) diff --git a/drivers/misc/niwatchdog.c b/drivers/misc/niwatchdog.c index 25114df5c19db..c3e0eeae24c85 100644 --- a/drivers/misc/niwatchdog.c +++ b/drivers/misc/niwatchdog.c @@ -47,7 +47,6 @@ struct niwatchdog { struct acpi_device *acpi_device; u16 io_base; - u16 io_size; u32 irq; spinlock_t lock; struct miscdevice misc_dev; @@ -425,25 +424,35 @@ static const struct file_operations niwatchdog_misc_fops = { static acpi_status niwatchdog_resources(struct acpi_resource *res, void *data) { struct niwatchdog *niwatchdog = data; + struct device *dev = &niwatchdog->acpi_device->dev; + u16 io_size; switch (res->type) { case ACPI_RESOURCE_TYPE_IO: - if ((niwatchdog->io_base != 0) || - (niwatchdog->io_size != 0)) { - dev_err(&niwatchdog->acpi_device->dev, - "too many IO resources\n"); + if (niwatchdog->io_base != 0) { + dev_err(dev, "too many IO resources\n"); return AE_ERROR; } niwatchdog->io_base = res->data.io.minimum; - niwatchdog->io_size = res->data.io.address_length; + io_size = res->data.io.address_length; + + if (io_size < NIWD_IO_SIZE) { + dev_err(dev, "memory region too small\n"); + return AE_ERROR; + } + + if (!devm_request_region(dev, niwatchdog->io_base, io_size, + MODULE_NAME)) { + dev_err(dev, "failed to get memory region\n"); + return AE_ERROR; + } return AE_OK; case ACPI_RESOURCE_TYPE_IRQ: if (niwatchdog->irq != 0) { - dev_err(&niwatchdog->acpi_device->dev, - "too many IRQ resources\n"); + dev_err(dev, "too many IRQ resources\n"); return AE_ERROR; } @@ -455,13 +464,9 @@ static acpi_status niwatchdog_resources(struct acpi_resource *res, void *data) return AE_OK; default: - dev_err(&niwatchdog->acpi_device->dev, - "unsupported resource type %d\n", - res->type); + dev_err(dev, "unsupported resource type %d\n", res->type); return AE_ERROR; } - - return AE_OK; } static void niwatchdog_acpi_remove(struct acpi_device *device) @@ -472,77 +477,53 @@ static void niwatchdog_acpi_remove(struct acpi_device *device) sysfs_remove_files(&niwatchdog->acpi_device->dev.kobj, niwatchdog_attrs); - - if ((niwatchdog->io_base != 0) && - (niwatchdog->io_size == NIWD_IO_SIZE)) - release_region(niwatchdog->io_base, niwatchdog->io_size); - - device->driver_data = NULL; - - kfree(niwatchdog); } static int niwatchdog_acpi_add(struct acpi_device *device) { + struct device *dev = &device->dev; struct niwatchdog *niwatchdog; acpi_status acpi_ret; int err; - niwatchdog = kzalloc(sizeof(*niwatchdog), GFP_KERNEL); - + niwatchdog = devm_kzalloc(dev, sizeof(*niwatchdog), GFP_KERNEL); if (!niwatchdog) return -ENOMEM; device->driver_data = niwatchdog; - niwatchdog->acpi_device = device; acpi_ret = acpi_walk_resources(device->handle, METHOD_NAME__CRS, niwatchdog_resources, niwatchdog); - - if (ACPI_FAILURE(acpi_ret) || - (niwatchdog->io_base == 0) || - (niwatchdog->io_size != NIWD_IO_SIZE) || - (niwatchdog->irq == 0)) { - niwatchdog_acpi_remove(device); + if (ACPI_FAILURE(acpi_ret) || niwatchdog->io_base == 0 || + niwatchdog->irq == 0) { + dev_err(dev, "failed to get resources\n"); return -ENODEV; } - if (!request_region(niwatchdog->io_base, niwatchdog->io_size, - MODULE_NAME)) { - niwatchdog_acpi_remove(device); - return -EBUSY; - } - - err = sysfs_create_files(&niwatchdog->acpi_device->dev.kobj, - niwatchdog_attrs); - if (err) { - niwatchdog_acpi_remove(device); - return err; - } - spin_lock_init(&niwatchdog->lock); atomic_set(&niwatchdog->available, 1); init_waitqueue_head(&niwatchdog->irq_event); niwatchdog->expired = false; + err = sysfs_create_files(&dev->kobj, niwatchdog_attrs); + if (err) { + dev_err(dev, "failed to create sysfs attributes\n"); + return err; + } + niwatchdog->misc_dev.minor = MISC_DYNAMIC_MINOR; niwatchdog->misc_dev.name = NIWATCHDOG_NAME; niwatchdog->misc_dev.fops = &niwatchdog_misc_fops; err = misc_register(&niwatchdog->misc_dev); - if (err) { - niwatchdog_acpi_remove(device); + dev_err(dev, "failed to register misc device\n"); + sysfs_remove_files(&dev->kobj, niwatchdog_attrs); return err; } - dev_info(&niwatchdog->acpi_device->dev, - "IO range 0x%04X-0x%04X, IRQ %d\n", - niwatchdog->io_base, - niwatchdog->io_base + niwatchdog->io_size - 1, niwatchdog->irq); - return 0; } @@ -560,18 +541,7 @@ static struct acpi_driver niwatchdog_acpi_driver = { }, }; -static int __init niwatchdog_init(void) -{ - return acpi_bus_register_driver(&niwatchdog_acpi_driver); -} - -static void __exit niwatchdog_exit(void) -{ - acpi_bus_unregister_driver(&niwatchdog_acpi_driver); -} - -module_init(niwatchdog_init); -module_exit(niwatchdog_exit); +module_acpi_driver(niwatchdog_acpi_driver); MODULE_DEVICE_TABLE(acpi, niwatchdog_device_ids); MODULE_DESCRIPTION("NI Watchdog"); From a83911ad5b33f481e20659471d9909ae860b4138 Mon Sep 17 00:00:00 2001 From: Kyle Roeschley Date: Wed, 2 Aug 2017 13:08:03 -0500 Subject: [PATCH 045/100] niwatchdog: Request IRQ on ACPI add instead of miscdevice open Do what most sane drivers do and request our IRQ on ACPI add 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: Zach Brown Acked-by: James Minor Acked-by: Ovidiu Vancea Acked-by: Julia Cartwright Natinst-CAR-ID: 648185 Natinst-ReviewBoard-ID: 196333 --- drivers/misc/niwatchdog.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/misc/niwatchdog.c b/drivers/misc/niwatchdog.c index c3e0eeae24c85..02aad34a04de9 100644 --- a/drivers/misc/niwatchdog.c +++ b/drivers/misc/niwatchdog.c @@ -299,15 +299,13 @@ static int niwatchdog_misc_open(struct inode *inode, struct file *file) return -EBUSY; } - return request_threaded_irq(niwatchdog->irq, NULL, niwatchdog_irq, - IRQF_ONESHOT, NIWATCHDOG_NAME, niwatchdog); + return 0; } static int niwatchdog_misc_release(struct inode *inode, struct file *file) { struct niwatchdog *niwatchdog = file->private_data; - free_irq(niwatchdog->irq, niwatchdog); atomic_inc(&niwatchdog->available); return 0; } @@ -458,6 +456,13 @@ static acpi_status niwatchdog_resources(struct acpi_resource *res, void *data) niwatchdog->irq = res->data.irq.interrupts[0]; + if (devm_request_threaded_irq(dev, niwatchdog->irq, NULL, + niwatchdog_irq, IRQF_ONESHOT, + NIWATCHDOG_NAME, niwatchdog)) { + dev_err(dev, "failed to get interrupt\n"); + return AE_ERROR; + } + return AE_OK; case ACPI_RESOURCE_TYPE_END_TAG: From 817fdddc7393bd78038536abab2acf08076d76be Mon Sep 17 00:00:00 2001 From: Hui Chun Ong Date: Mon, 6 Feb 2017 23:49:09 +0800 Subject: [PATCH 046/100] watchdog: nic7018_wdt: Add support for trigger pet and trigger assert Add capabilities to use trigger line to reset timer and to assert trigger line upon timeout. The trigger line control and selection is done through sysfs attributes. Signed-off-by: Hui Chun Ong Signed-off-by: Brad Mouring Acked-by: Gratian Crisan Acked-by: Julia Cartwright Natinst-ReviewBoard-ID: 192326 (cherry picked from commit d6351b1a5530fb532e948fec6a8e947cca384880) (cherry picked from commit be8a29797de3c2fc60a44993edc24071da2c7f5f) [gratian: fix trivial conflict with f1c16aa612dc ("watchdog: nic7018_wdt: tidy up ACPI ID table")] Signed-off-by: Gratian Crisan --- drivers/watchdog/nic7018_wdt.c | 168 +++++++++++++++++++++++++++++++++ 1 file changed, 168 insertions(+) diff --git a/drivers/watchdog/nic7018_wdt.c b/drivers/watchdog/nic7018_wdt.c index 44b5298f599ad..fca9149bfc65b 100644 --- a/drivers/watchdog/nic7018_wdt.c +++ b/drivers/watchdog/nic7018_wdt.c @@ -8,8 +8,10 @@ #include #include #include +#include #include #include +#include #include #define LOCK 0xA5 @@ -17,6 +19,8 @@ #define WDT_CTRL_RESET_EN BIT(7) #define WDT_RELOAD_PORT_EN BIT(7) +#define WDT_CTRL_TRIG_POL BIT(4) +#define WDT_RELOAD_TRIG_POL BIT(6) #define WDT_CTRL 1 #define WDT_RELOAD_CTRL 2 @@ -47,6 +51,7 @@ struct nic7018_wdt { u16 io_base; u32 period; struct watchdog_device wdd; + struct mutex lock; }; struct nic7018_config { @@ -166,6 +171,166 @@ static const struct watchdog_ops nic7018_wdd_ops = { .get_timeleft = nic7018_get_timeleft, }; +struct nic7018_attr { + struct device_attribute dev_attr; + u8 offset; + u8 bit; +}; +#define to_nic7018_attr(_attr) \ + container_of((_attr), struct nic7018_attr, dev_attr) + +static ssize_t wdt_attr_show(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct watchdog_device *wdd = dev_get_drvdata(dev); + struct nic7018_wdt *wdt = watchdog_get_drvdata(wdd); + struct nic7018_attr *attr = to_nic7018_attr(da); + u8 control; + + mutex_lock(&wdt->lock); + + control = inb(wdt->io_base + attr->offset); + + mutex_unlock(&wdt->lock); + return sprintf(buf, "%u\n", !!(control & attr->bit)); +} + +static ssize_t wdt_attr_store(struct device *dev, + struct device_attribute *da, + const char *buf, + size_t size) +{ + struct watchdog_device *wdd = dev_get_drvdata(dev); + struct nic7018_wdt *wdt = watchdog_get_drvdata(wdd); + struct nic7018_attr *attr = to_nic7018_attr(da); + unsigned long val; + u8 control; + + int ret = kstrtoul(buf, 10, &val); + + if (ret) + return ret; + + if (val > 1) + return -EINVAL; + + mutex_lock(&wdt->lock); + + control = inb(wdt->io_base + attr->offset); + if (val) + outb(control | attr->bit, wdt->io_base + attr->offset); + else + outb(control & ~attr->bit, wdt->io_base + attr->offset); + + mutex_unlock(&wdt->lock); + return size; +} + +#define WDT_ATTR(_name, _offset, _bit) \ + struct nic7018_attr dev_attr_##_name = { \ + .offset = _offset, \ + .bit = _bit, \ + .dev_attr = \ + __ATTR(_name, S_IWUSR | S_IRUGO, \ + wdt_attr_show, wdt_attr_store), \ + } + +static WDT_ATTR(enable_reset, WDT_CTRL, WDT_CTRL_RESET_EN); +static WDT_ATTR(enable_soft_ping, WDT_RELOAD_CTRL, WDT_RELOAD_PORT_EN); +static WDT_ATTR(trigger_polarity, WDT_CTRL, WDT_CTRL_TRIG_POL); +static WDT_ATTR(keepalive_trigger_polarity, WDT_RELOAD_CTRL, + WDT_RELOAD_TRIG_POL); + +static ssize_t wdt_trig_show(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct watchdog_device *wdd = dev_get_drvdata(dev); + struct nic7018_wdt *wdt = watchdog_get_drvdata(wdd); + struct nic7018_attr *attr = to_nic7018_attr(da); + u8 control; + + mutex_lock(&wdt->lock); + + control = inb(wdt->io_base + attr->offset); + + mutex_unlock(&wdt->lock); + + if (control & 0x0F) + return sprintf(buf, "trig%u\n", (control & 0x0F) - 1); + else + return sprintf(buf, "none\n"); +} + +static ssize_t wdt_trig_store(struct device *dev, + struct device_attribute *da, + const char *buf, + size_t size) +{ + struct watchdog_device *wdd = dev_get_drvdata(dev); + struct nic7018_wdt *wdt = watchdog_get_drvdata(wdd); + struct nic7018_attr *attr = to_nic7018_attr(da); + u8 control; + + char *p = memchr(buf, '\n', size); + size_t count = p ? p - buf : size; + + if (count == 5 && !strncmp(buf, "trig", 4)) { + unsigned long val; + int ret; + + ret = kstrtoul(buf + 4, 10, &val); + if (ret) + return ret; + + if (val > 8) + return -EINVAL; + + mutex_lock(&wdt->lock); + + control = inb(wdt->io_base + attr->offset); + outb((control & 0xF0) | (val + 1), + wdt->io_base + attr->offset); + + mutex_unlock(&wdt->lock); + + } else if (count == 4 && !strncmp(buf, "none", 4)) { + mutex_lock(&wdt->lock); + + control = inb(wdt->io_base + attr->offset); + outb(control & 0xF0, wdt->io_base + attr->offset); + + mutex_unlock(&wdt->lock); + } else { + return -EINVAL; + } + + return size; +} + +#define WDT_TRIG_ATTR(_name, _offset) \ + struct nic7018_attr dev_attr_##_name = { \ + .offset = _offset, \ + .dev_attr = \ + __ATTR(_name, S_IWUSR | S_IRUGO, \ + wdt_trig_show, wdt_trig_store), \ + } + +static WDT_TRIG_ATTR(trigger, WDT_CTRL); +static WDT_TRIG_ATTR(keepalive_trigger, WDT_RELOAD_CTRL); + +static struct attribute *nic7018_wdt_attrs[] = { + &dev_attr_enable_reset.dev_attr.attr, + &dev_attr_enable_soft_ping.dev_attr.attr, + &dev_attr_trigger_polarity.dev_attr.attr, + &dev_attr_keepalive_trigger_polarity.dev_attr.attr, + &dev_attr_trigger.dev_attr.attr, + &dev_attr_keepalive_trigger.dev_attr.attr, + NULL +}; +ATTRIBUTE_GROUPS(nic7018_wdt); + static int nic7018_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -192,6 +357,8 @@ static int nic7018_probe(struct platform_device *pdev) return -EBUSY; } + mutex_init(&wdt->lock); + wdt->io_base = io_rc->start; wdd = &wdt->wdd; wdd->info = &nic7018_wdd_info; @@ -200,6 +367,7 @@ static int nic7018_probe(struct platform_device *pdev) wdd->max_timeout = WDT_MAX_TIMEOUT; wdd->timeout = WDT_DEFAULT_TIMEOUT; wdd->parent = dev; + wdd->groups = nic7018_wdt_groups; watchdog_set_drvdata(wdd, wdt); watchdog_set_nowayout(wdd, nowayout); From 2f631df3524da3a22c11d2872d30d3b44595ee6b Mon Sep 17 00:00:00 2001 From: Hui Chun Ong Date: Sat, 8 Jul 2017 12:33:34 +0800 Subject: [PATCH 047/100] watchdog: nic7018_wdt: Add support for timeout interrupt Add interrupt handling for watchdog timeout. Interrupt control is done through sysfs "enable_interrupt" attribute. uevent is used to signal userspace when interrupt occurred as oppose to using poll due to no support in watchdog core. Signed-off-by: Hui Chun Ong Signed-off-by: Brad Mouring Acked-by: Julia Cartwright Natinst-ReviewBoard-ID: 195479 --- drivers/watchdog/nic7018_wdt.c | 45 +++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/drivers/watchdog/nic7018_wdt.c b/drivers/watchdog/nic7018_wdt.c index fca9149bfc65b..e66f4866f94ff 100644 --- a/drivers/watchdog/nic7018_wdt.c +++ b/drivers/watchdog/nic7018_wdt.c @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -21,7 +22,9 @@ #define WDT_RELOAD_PORT_EN BIT(7) #define WDT_CTRL_TRIG_POL BIT(4) #define WDT_RELOAD_TRIG_POL BIT(6) +#define WDT_CTRL_INTERRUPT_EN BIT(5) +#define WDT_STATUS 0 #define WDT_CTRL 1 #define WDT_RELOAD_CTRL 2 #define WDT_PRESET_PRESCALE 4 @@ -107,6 +110,31 @@ static int nic7018_set_timeout(struct watchdog_device *wdd, return 0; } +static irqreturn_t nic7018_thread_isr(int irq, void *wdt_arg) +{ + struct nic7018_wdt *wdt = wdt_arg; + struct watchdog_device *wdd = &wdt->wdd; + u8 status, control; + + status = inb(wdt->io_base + WDT_STATUS); + + /* IRQ line asserted */ + if (status & 0x20) { + + mutex_lock(&wdt->lock); + + control = inb(wdt->io_base + WDT_CTRL); + /* Disable IRQ line */ + outb(control & ~WDT_CTRL_INTERRUPT_EN, + wdt->io_base + WDT_CTRL); + + mutex_unlock(&wdt->lock); + + kobject_uevent(&wdd->parent->kobj, KOBJ_CHANGE); + } + return IRQ_HANDLED; +} + static int nic7018_start(struct watchdog_device *wdd) { struct nic7018_wdt *wdt = watchdog_get_drvdata(wdd); @@ -241,6 +269,7 @@ static WDT_ATTR(enable_soft_ping, WDT_RELOAD_CTRL, WDT_RELOAD_PORT_EN); static WDT_ATTR(trigger_polarity, WDT_CTRL, WDT_CTRL_TRIG_POL); static WDT_ATTR(keepalive_trigger_polarity, WDT_RELOAD_CTRL, WDT_RELOAD_TRIG_POL); +static WDT_ATTR(enable_interrupt, WDT_CTRL, WDT_CTRL_INTERRUPT_EN); static ssize_t wdt_trig_show(struct device *dev, struct device_attribute *da, @@ -325,6 +354,7 @@ static struct attribute *nic7018_wdt_attrs[] = { &dev_attr_enable_soft_ping.dev_attr.attr, &dev_attr_trigger_polarity.dev_attr.attr, &dev_attr_keepalive_trigger_polarity.dev_attr.attr, + &dev_attr_enable_interrupt.dev_attr.attr, &dev_attr_trigger.dev_attr.attr, &dev_attr_keepalive_trigger.dev_attr.attr, NULL @@ -337,7 +367,7 @@ static int nic7018_probe(struct platform_device *pdev) struct watchdog_device *wdd; struct nic7018_wdt *wdt; struct resource *io_rc; - int ret; + int ret, irq; wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL); if (!wdt) @@ -357,6 +387,10 @@ static int nic7018_probe(struct platform_device *pdev) return -EBUSY; } + irq = platform_get_irq(pdev, 0); + if (!irq) + return -EINVAL; + mutex_init(&wdt->lock); wdt->io_base = io_rc->start; @@ -373,6 +407,15 @@ static int nic7018_probe(struct platform_device *pdev) watchdog_set_nowayout(wdd, nowayout); watchdog_init_timeout(wdd, timeout, dev); + ret = devm_request_threaded_irq(dev, irq, NULL, + nic7018_thread_isr, + IRQF_ONESHOT, + KBUILD_MODNAME, wdt); + if (ret) { + dev_err(dev, "failed to register interrupt handler\n"); + return ret; + } + /* Unlock WDT register */ outb(UNLOCK, wdt->io_base + WDT_REG_LOCK); From 5aca3245b43bc4922e51130aba6c2bce5fb22148 Mon Sep 17 00:00:00 2001 From: James Minor Date: Mon, 16 Mar 2015 17:22:51 -0500 Subject: [PATCH 048/100] cfg80211: wext: Force scans to occur in AP mode When in AP mode, we should force scans to happen from the wext compatibility layer. This won't hurt when in station mode, and only affects the wl12xx driver. This change is to retain parity with NI's shipped 3.2 kernel. It can be dropped when we switch away from using the WEXT interface, and should not be upstreamed. Signed-off-by: James Minor Reviewed-by: Ben Shelton Reviewed-by: Jaeden Amero Natinst-ReviewBoard-ID: 92027 [gratian: fix trivial conflict with f0df91b6a712 ("wifi: cfg80211: hide scan internals")] Signed-off-by: Gratian Crisan --- net/wireless/scan.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/wireless/scan.c b/net/wireless/scan.c index 90a9187a6b135..5fc3199280030 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c @@ -3611,6 +3611,9 @@ int cfg80211_wext_siwscan(struct net_device *dev, /* Set real number of channels specified in creq->req.channels[] */ creq->req.n_channels = i; + /* Force the scan if we are in AP mode */ + creq->req.flags |= NL80211_SCAN_FLAG_AP; + /* translate "Scan for SSID" request */ if (wreq) { if (wrqu->data.flags & IW_SCAN_THIS_ESSID) { From 753b551093f70c9c3ccc40fe2aa053368f94f7fb Mon Sep 17 00:00:00 2001 From: Sundar Subbiah Date: Tue, 2 Apr 2013 15:19:22 -0500 Subject: [PATCH 049/100] wlcore: Depend on WIRELESS_EXT for nitargetcfg This is a hack to get CONFIG_WIRELESS_EXT enabled, since if it is turned on in the defconfig it will not propogate to the .config (as it is not user selectable). Even though the driver does not need it, the current NI user-mode software stacks require this support for scanning and interface enumeration. With this change, it will propogate to the wl12xx driver build (from compat-wireless) and thus include WEXT support in that driver and wireless networking modules. Signed-off-by: Sundar Subbiah Acked-by: James Minor Acked-by: Josh Cartwright Acked-by: Jeff Westfahl Acked-by: Ken Sharp Natinst-ReviewBoard-ID: 37925 --- drivers/net/wireless/ti/wlcore/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/ti/wlcore/Kconfig b/drivers/net/wireless/ti/wlcore/Kconfig index 8094323256fb9..3f652e66e2553 100644 --- a/drivers/net/wireless/ti/wlcore/Kconfig +++ b/drivers/net/wireless/ti/wlcore/Kconfig @@ -3,6 +3,7 @@ config WLCORE tristate "TI wlcore support" depends on MAC80211 select FW_LOADER + select WIRELESS_EXT help This module contains the main code for TI WLAN chips. It abstracts hardware-specific differences among different chipset families. From 54d348f21d539a7bae884827f4ef8d5434cb5b86 Mon Sep 17 00:00:00 2001 From: Nathan Sullivan Date: Thu, 5 Nov 2015 14:53:58 -0600 Subject: [PATCH 050/100] ath6kl: set initial region using DMI info Use the BIOS DMI tables to select an initial region for regulatory info. The region in BIOS will be set in manufacturing based on where the product is to be used. This is intended to facilitate channel and power level selection based on the product's SKU. Signed-off-by: Nathan Sullivan Signed-off-by: James Minor Signed-off-by: Brad Mouring Natinst-CAR-ID: 578408 Natinst-ReviewBoard-ID: 120508 Natinst-ReviewBoard-ID: 130950 Natinst-Trello-ID: https://trello.com/c/xCpOlFJt [bstreiff: remove elvisiii dts changes as part of zynq removal] Signed-off-by: Brandon Streiff [gratian: update Kconfig '---help---' to 'help'] Signed-off-by: Gratian Crisan --- drivers/net/wireless/ath/ath6kl/Kconfig | 9 +++++ drivers/net/wireless/ath/ath6kl/core.c | 50 +++++++++++++++++++++++++ drivers/net/wireless/ath/ath6kl/wmi.c | 6 +++ drivers/net/wireless/ath/ath6kl/wmi.h | 3 ++ 4 files changed, 68 insertions(+) diff --git a/drivers/net/wireless/ath/ath6kl/Kconfig b/drivers/net/wireless/ath/ath6kl/Kconfig index cd96cf8d99409..a9ac19f2c3727 100644 --- a/drivers/net/wireless/ath/ath6kl/Kconfig +++ b/drivers/net/wireless/ath/ath6kl/Kconfig @@ -64,3 +64,12 @@ config ATH6KL_REGDOMAIN are taken into account. If unsure, say N. + +config ATH6KL_NI_BIOS_DOMAIN + bool "Atheros ath6kl DMI regdomain support" + depends on ATH6KL + help + Enabling this will cause the ath6kl driver to load the initial + regdomain from BIOS DMI tables. + + If unsure, say N. diff --git a/drivers/net/wireless/ath/ath6kl/core.c b/drivers/net/wireless/ath/ath6kl/core.c index 830350bda5318..08bd7c9eaa067 100644 --- a/drivers/net/wireless/ath/ath6kl/core.c +++ b/drivers/net/wireless/ath/ath6kl/core.c @@ -21,6 +21,8 @@ #include #include #include +#include +#include #include "debug.h" #include "hif-ops.h" @@ -51,6 +53,31 @@ MODULE_PARM_DESC(heart_beat_poll, "Enable fw error detection periodic polling in msecs - Also set recovery_enable for this to be effective"); +#define WLAN_REGION_ID 161 +#ifdef CONFIG_ATH6KL_NI_BIOS_DOMAIN +struct region_table { + struct dmi_header header; + char padding[3]; + char alpha2[2]; +}; + +static char region[2]; +static void find_region_type(const struct dmi_header *dm, void *private_data) +{ + int *found = (int *)private_data; + + if (dm->type == WLAN_REGION_ID) { + struct region_table *table = + container_of(dm, struct region_table, header); + + ath6kl_dbg(ATH6KL_DBG_TRC, "Region code from BIOS: %c%c\n", + table->alpha2[0], table->alpha2[1]); + memcpy(region, table->alpha2, 2); + *found = 1; + } +} +#endif + void ath6kl_core_tx_complete(struct ath6kl *ar, struct sk_buff *skb) { ath6kl_htc_tx_complete(ar, skb); @@ -69,6 +96,20 @@ int ath6kl_core_init(struct ath6kl *ar, enum ath6kl_htc_type htc_type) struct wireless_dev *wdev; int ret = 0, i; +#ifdef CONFIG_ATH6KL_NI_BIOS_DOMAIN + /* get region code from DMI */ + dmi_walk(find_region_type, &ret); + if (!ret) + return -ENODEV; + + if (!isascii(region[0]) || !isascii(region[1])) + return -EINVAL; + + ath6kl_info("Using region: %c%c\n", + region[0], + region[1]); +#endif + switch (htc_type) { case ATH6KL_HTC_TYPE_MBOX: ath6kl_htc_mbox_attach(ar); @@ -194,6 +235,15 @@ int ath6kl_core_init(struct ath6kl *ar, enum ath6kl_htc_type htc_type) goto err_rxbuf_cleanup; } +#ifdef CONFIG_ATH6KL_NI_BIOS_DOMAIN + /* set region from DMI if it is US */ + if (region[0] == 'U' && region[1] == 'S') { + ret = ath6kl_wmi_set_regdomain_cmd(ar->wmi, region); + if (ret) + goto err_rxbuf_cleanup; + } +#endif + /* give our connected endpoints some buffers */ ath6kl_rx_refill(ar->htc_target, ar->ctrl_ep); ath6kl_rx_refill(ar->htc_target, ar->ac2ep_map[WMM_AC_BE]); diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c index 08a154bce1396..38507f9b03bbc 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.c +++ b/drivers/net/wireless/ath/ath6kl/wmi.c @@ -3294,9 +3294,15 @@ int ath6kl_wmi_set_regdomain_cmd(struct wmi *wmi, const char *alpha2) cmd = (struct wmi_set_regdomain_cmd *) skb->data; memcpy(cmd->iso_name, alpha2, 2); +#ifdef CONFIG_ATH6KL_SILEX_FIRMWARE + return ath6kl_wmi_cmd_send(wmi, 0, skb, + WMI_SET_REGDOMAIN_SILEX_CMDID, + NO_SYNC_WMIFLAG); +#else return ath6kl_wmi_cmd_send(wmi, 0, skb, WMI_SET_REGDOMAIN_CMDID, NO_SYNC_WMIFLAG); +#endif } s32 ath6kl_wmi_get_rate(struct wmi *wmi, s8 rate_index) diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h index 3080d82e25cc2..2ecf80d3989ce 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.h +++ b/drivers/net/wireless/ath/ath6kl/wmi.h @@ -644,6 +644,9 @@ enum wmi_cmd_id { WMI_ENABLE_SCHED_SCAN_CMDID, }; +/* Silex has this command at a different ID */ +#define WMI_SET_REGDOMAIN_SILEX_CMDID 0xf0b0 + enum wmi_mgmt_frame_type { WMI_FRAME_BEACON = 0, WMI_FRAME_PROBE_REQ, From 342fae7c0d8c49993851b68c51ce83ff03e52d6c Mon Sep 17 00:00:00 2001 From: James Minor Date: Wed, 28 Oct 2015 12:16:56 -0500 Subject: [PATCH 051/100] ath6kl: Add Silex firmware capabilities Signed-off-by: James Minor [gratian: update Kconfig '---help---' to 'help'] Signed-off-by: Gratian Crisan --- drivers/net/wireless/ath/ath6kl/Kconfig | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/net/wireless/ath/ath6kl/Kconfig b/drivers/net/wireless/ath/ath6kl/Kconfig index a9ac19f2c3727..89eddce784310 100644 --- a/drivers/net/wireless/ath/ath6kl/Kconfig +++ b/drivers/net/wireless/ath/ath6kl/Kconfig @@ -73,3 +73,12 @@ config ATH6KL_NI_BIOS_DOMAIN regdomain from BIOS DMI tables. If unsure, say N. + +config ATH6KL_SILEX_FIRMWARE + bool "Atheros ath6kl Silex firmware support" + depends on ATH6KL + help + Enabling this will cause the ath6kl driver to use customizations + required by the firmware from Silex. + + If unsure, say N. From 118cb0653d5d5d10aa05347a67942f1894442903 Mon Sep 17 00:00:00 2001 From: Nathan Sullivan Date: Wed, 16 Mar 2016 09:01:15 -0500 Subject: [PATCH 052/100] ath6kl: select board file using DMI info In addition to setting the region on the device, switch board files based on the selected region from BIOS. This allows different boards to load files with different power levels for regulatory purposes. Signed-off-by: Nathan Sullivan Signed-off-by: Brad Mouring Acked-by: Xander Huff Acked-by: James Minor Natinst-CAR-ID: 578408 Natinst-ReviewBoard-ID: 130950 --- drivers/net/wireless/ath/ath6kl/core.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/net/wireless/ath/ath6kl/core.c b/drivers/net/wireless/ath/ath6kl/core.c index 08bd7c9eaa067..52c449e21502c 100644 --- a/drivers/net/wireless/ath/ath6kl/core.c +++ b/drivers/net/wireless/ath/ath6kl/core.c @@ -97,6 +97,7 @@ int ath6kl_core_init(struct ath6kl *ar, enum ath6kl_htc_type htc_type) int ret = 0, i; #ifdef CONFIG_ATH6KL_NI_BIOS_DOMAIN + char *region_board_file = NULL; /* get region code from DMI */ dmi_walk(find_region_type, &ret); if (!ret) @@ -160,6 +161,17 @@ int ath6kl_core_init(struct ath6kl *ar, enum ath6kl_htc_type htc_type) ar->testmode = testmode; +#ifdef CONFIG_ATH6KL_NI_BIOS_DOMAIN + /* ath6kl_init_hw_params() will set the board file name, but we want + * to override it with a region specific board file here. + */ + region_board_file = devm_kzalloc(ar->dev, 64, GFP_KERNEL); + + snprintf(region_board_file, 64, AR6004_HW_3_0_FW_DIR "/bdata%c%c.bin", + region[0], region[1]); + + ar->hw.fw_board = region_board_file; +#endif ret = ath6kl_init_fetch_firmwares(ar); if (ret) goto err_htc_cleanup; From 2d9ef3b53fb9c2e8912735c9c65c73dcdb4e138e Mon Sep 17 00:00:00 2001 From: James Minor Date: Mon, 4 Apr 2016 12:15:18 -0500 Subject: [PATCH 053/100] ath6kl: Add ATH6KL_FW_CAPABILITY_SET_RSN_CAP capabilities Some firmwares offer the ability to directly set the RSN with WMI_SET_RSN_CAP_CMDID instead of using WMI_SET_IE_CMDID. Add the flags and functions to make that work. Signed-off-by: James Minor Signed-off-by: Brad Mouring Natinst-ReviewBoard-ID: 133028 Natinst-CAR-ID: 577496 --- drivers/net/wireless/ath/ath6kl/cfg80211.c | 22 +++++++++++++++------- drivers/net/wireless/ath/ath6kl/core.h | 3 +++ drivers/net/wireless/ath/ath6kl/init.c | 1 + drivers/net/wireless/ath/ath6kl/wmi.c | 18 ++++++++++++++++++ drivers/net/wireless/ath/ath6kl/wmi.h | 6 ++++++ 5 files changed, 43 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index 88f0197fc041a..59542b930992c 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -2937,14 +2937,22 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev, * advertise the same in beacon/probe response. Send * the complete RSN IE capability field to firmware */ - if (!ath6kl_get_rsn_capab(&info->beacon, (u8 *) &rsn_capab) && - test_bit(ATH6KL_FW_CAPABILITY_RSN_CAP_OVERRIDE, - ar->fw_capabilities)) { - res = ath6kl_wmi_set_ie_cmd(ar->wmi, vif->fw_vif_idx, - WLAN_EID_RSN, WMI_RSN_IE_CAPB, - (const u8 *) &rsn_capab, - sizeof(rsn_capab)); + if (!ath6kl_get_rsn_capab(&info->beacon, (u8 *)&rsn_capab)) { vif->rsn_capab = rsn_capab; + res = -EIO; + if (test_bit(ATH6KL_FW_CAPABILITY_RSN_CAP_OVERRIDE, + ar->fw_capabilities)) { + res = ath6kl_wmi_set_ie_cmd(ar->wmi, vif->fw_vif_idx, + WLAN_EID_RSN, + WMI_RSN_IE_CAPB, + (const u8 *)&rsn_capab, + sizeof(rsn_capab)); + } + if (test_bit(ATH6KL_FW_CAPABILITY_SET_RSN_CAP, + ar->fw_capabilities)) { + res = ath6kl_wmi_set_rsn_cmd(ar->wmi, vif->fw_vif_idx, + rsn_capab); + } if (res < 0) return res; } diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h index 77e052336eb5b..96c8ab6f096f7 100644 --- a/drivers/net/wireless/ath/ath6kl/core.h +++ b/drivers/net/wireless/ath/ath6kl/core.h @@ -151,6 +151,9 @@ enum ath6kl_fw_capability { /* firmware doesn't support IP checksumming */ ATH6KL_FW_CAPABILITY_NO_IP_CHECKSUM, + /* firmware supports setting RSN CAP directly */ + ATH6KL_FW_CAPABILITY_SET_RSN_CAP, + /* this needs to be last */ ATH6KL_FW_CAPABILITY_MAX, }; diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c index 782209dcb7825..cf9ba2f91425d 100644 --- a/drivers/net/wireless/ath/ath6kl/init.c +++ b/drivers/net/wireless/ath/ath6kl/init.c @@ -1644,6 +1644,7 @@ static const struct fw_capa_str_map { { ATH6KL_FW_CAPABILITY_MAP_LP_ENDPOINT, "map-lp-endpoint" }, { ATH6KL_FW_CAPABILITY_RATETABLE_MCS15, "ratetable-mcs15" }, { ATH6KL_FW_CAPABILITY_NO_IP_CHECKSUM, "no-ip-checksum" }, + { ATH6KL_FW_CAPABILITY_SET_RSN_CAP, "set-rsn-cap" }, }; static const char *ath6kl_init_get_fw_capa_name(unsigned int id) diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c index 38507f9b03bbc..b483741a53378 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.c +++ b/drivers/net/wireless/ath/ath6kl/wmi.c @@ -3569,6 +3569,24 @@ int ath6kl_wmi_set_appie_cmd(struct wmi *wmi, u8 if_idx, u8 mgmt_frm_type, NO_SYNC_WMIFLAG); } +int ath6kl_wmi_set_rsn_cmd(struct wmi *wmi, u8 if_idx, u16 rsn_capab) +{ + struct sk_buff *skb; + struct wmi_set_rsn_cmd *p; + + skb = ath6kl_wmi_get_new_buf(sizeof(*p)); + if (!skb) + return -ENOMEM; + + ath6kl_info("set_rsn_cmd: rsn_capab=0x%4.4x\n", + rsn_capab); + p = (struct wmi_set_rsn_cmd *)skb->data; + p->rsn_capab = rsn_capab; + + return ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_RSN_CAP_CMDID, + NO_SYNC_WMIFLAG); +} + int ath6kl_wmi_set_ie_cmd(struct wmi *wmi, u8 if_idx, u8 ie_id, u8 ie_field, const u8 *ie_info, u8 ie_len) { diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h index 2ecf80d3989ce..7ebce0b91b2a0 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.h +++ b/drivers/net/wireless/ath/ath6kl/wmi.h @@ -2057,6 +2057,10 @@ struct wmi_set_appie_cmd { u8 ie_info[]; } __packed; +struct wmi_set_rsn_cmd { + u16 rsn_capab; +} __packed; + struct wmi_set_ie_cmd { u8 ie_id; u8 ie_field; /* enum wmi_ie_field_type */ @@ -2691,6 +2695,8 @@ int ath6kl_wmi_set_rx_frame_format_cmd(struct wmi *wmi, u8 if_idx, u8 rx_meta_version, bool rx_dot11_hdr, bool defrag_on_host); +int ath6kl_wmi_set_rsn_cmd(struct wmi *wmi, u8 if_idx, u16 rsn_capab); + int ath6kl_wmi_set_appie_cmd(struct wmi *wmi, u8 if_idx, u8 mgmt_frm_type, const u8 *ie, u8 ie_len); From 0d31cff399c79db0530fbb7b1e1da51765f877ce Mon Sep 17 00:00:00 2001 From: James Minor Date: Mon, 4 Apr 2016 12:17:46 -0500 Subject: [PATCH 054/100] ath6kl: Add Silex enums to set APPIE and RSN CAP Silex uses different command IDs for the commands WMI_SET_APPIE_CMDID and WMI_SET_RSN_CAP_SILEX_CMDID. In case of the Silex firmware, remap them to the correct command ID. Signed-off-by: James Minor Signed-off-by: Brad Mouring Natinst-ReviewBoard-ID: 133028 Natinst-CAR-ID: 577496 --- drivers/net/wireless/ath/ath6kl/wmi.c | 18 +++++++++++++++--- drivers/net/wireless/ath/ath6kl/wmi.h | 2 ++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c index b483741a53378..f3a18204b0790 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.c +++ b/drivers/net/wireless/ath/ath6kl/wmi.c @@ -3565,8 +3565,13 @@ int ath6kl_wmi_set_appie_cmd(struct wmi *wmi, u8 if_idx, u8 mgmt_frm_type, if (ie != NULL && ie_len > 0) memcpy(p->ie_info, ie, ie_len); - return ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_APPIE_CMDID, - NO_SYNC_WMIFLAG); +#ifdef CONFIG_ATH6KL_SILEX_FIRMWARE + return ath6kl_wmi_cmd_send(wmi, if_idx, skb, + WMI_SET_APPIE_SILEX_CMDID, NO_SYNC_WMIFLAG); +#else + return ath6kl_wmi_cmd_send(wmi, if_idx, skb, + WMI_SET_APPIE_CMDID, NO_SYNC_WMIFLAG); +#endif } int ath6kl_wmi_set_rsn_cmd(struct wmi *wmi, u8 if_idx, u16 rsn_capab) @@ -3583,8 +3588,15 @@ int ath6kl_wmi_set_rsn_cmd(struct wmi *wmi, u8 if_idx, u16 rsn_capab) p = (struct wmi_set_rsn_cmd *)skb->data; p->rsn_capab = rsn_capab; - return ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_RSN_CAP_CMDID, +#ifdef CONFIG_ATH6KL_SILEX_FIRMWARE + return ath6kl_wmi_cmd_send(wmi, if_idx, skb, + WMI_SET_RSN_CAP_SILEX_CMDID, + NO_SYNC_WMIFLAG); +#else + return ath6kl_wmi_cmd_send(wmi, if_idx, skb, + WMI_SET_RSN_CAP_CMDID, NO_SYNC_WMIFLAG); +#endif } int ath6kl_wmi_set_ie_cmd(struct wmi *wmi, u8 if_idx, u8 ie_id, u8 ie_field, diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h index 7ebce0b91b2a0..ea6f2730150e1 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.h +++ b/drivers/net/wireless/ath/ath6kl/wmi.h @@ -646,6 +646,8 @@ enum wmi_cmd_id { /* Silex has this command at a different ID */ #define WMI_SET_REGDOMAIN_SILEX_CMDID 0xf0b0 +#define WMI_SET_APPIE_SILEX_CMDID 0x3f +#define WMI_SET_RSN_CAP_SILEX_CMDID 0xf082 enum wmi_mgmt_frame_type { WMI_FRAME_BEACON = 0, From 7a13efe0d6055d9d7bbfebd8052ff058878c6ff2 Mon Sep 17 00:00:00 2001 From: James Minor Date: Thu, 25 Feb 2016 10:18:02 -0600 Subject: [PATCH 055/100] ath6kl: fix firmware race condition by retrying initialization Sometimes the devices will fail to boot the first time, but will work fine when retried. Retry the initialization a few times before failing (and reset the hardware properly when it fails). Signed-off-by: James Minor Signed-off-by: Brad Mouring Natinst-ReviewBoard-ID: 130170 Natinst-CAR-ID: 566029 --- drivers/net/wireless/ath/ath6kl/core.c | 18 +++++++++++++++--- drivers/net/wireless/ath/ath6kl/core.h | 3 +++ drivers/net/wireless/ath/ath6kl/init.c | 2 ++ 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath6kl/core.c b/drivers/net/wireless/ath/ath6kl/core.c index 52c449e21502c..d5d46dc0c8643 100644 --- a/drivers/net/wireless/ath/ath6kl/core.c +++ b/drivers/net/wireless/ath/ath6kl/core.c @@ -38,6 +38,7 @@ static unsigned int ath6kl_p2p; static unsigned int testmode; static unsigned int recovery_enable; static unsigned int heart_beat_poll; +static unsigned int boot_attempts; module_param(debug_mask, uint, 0644); module_param(suspend_mode, uint, 0644); @@ -48,9 +49,11 @@ module_param(ath6kl_p2p, uint, 0644); module_param(testmode, uint, 0644); module_param(recovery_enable, uint, 0644); module_param(heart_beat_poll, uint, 0644); +module_param(boot_attempts, uint, 0644); MODULE_PARM_DESC(recovery_enable, "Enable recovery from firmware error"); MODULE_PARM_DESC(heart_beat_poll, "Enable fw error detection periodic polling in msecs - Also set recovery_enable for this to be effective"); +MODULE_PARM_DESC(boot_attempts, "Number of times to retry booting the firmware"); #define WLAN_REGION_ID 161 @@ -111,6 +114,8 @@ int ath6kl_core_init(struct ath6kl *ar, enum ath6kl_htc_type htc_type) region[1]); #endif + ar->boot_attempts = boot_attempts; + switch (htc_type) { case ATH6KL_HTC_TYPE_MBOX: ath6kl_htc_mbox_attach(ar); @@ -242,11 +247,18 @@ int ath6kl_core_init(struct ath6kl *ar, enum ath6kl_htc_type htc_type) ath6kl_debug_init(ar); ret = ath6kl_init_hw_start(ar); - if (ret) { - ath6kl_err("Failed to start hardware: %d\n", ret); - goto err_rxbuf_cleanup; + while (ret && ar->boot_attempts) { + ath6kl_err("Failed to start hardware: %d (retry %d)\n", + ret, + ar->boot_attempts); + ar->boot_attempts--; + ret = ath6kl_init_hw_start(ar); } + if (ret) + /* Did not boot after several attempts */ + goto err_rxbuf_cleanup; + #ifdef CONFIG_ATH6KL_NI_BIOS_DOMAIN /* set region from DMI if it is US */ if (region[0] == 'U' && region[1] == 'S') { diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h index 96c8ab6f096f7..2c9c0cac314eb 100644 --- a/drivers/net/wireless/ath/ath6kl/core.h +++ b/drivers/net/wireless/ath/ath6kl/core.h @@ -874,6 +874,9 @@ struct ath6kl { u8 disc_timeout; } debug; #endif /* CONFIG_ATH6KL_DEBUG */ + + /* Number of times we have attempted to boot the radio */ + unsigned int boot_attempts; }; static inline struct ath6kl *ath6kl_priv(struct net_device *dev) diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c index cf9ba2f91425d..b98fb5fcab278 100644 --- a/drivers/net/wireless/ath/ath6kl/init.c +++ b/drivers/net/wireless/ath/ath6kl/init.c @@ -1775,6 +1775,8 @@ static int __ath6kl_init_hw_start(struct ath6kl *ar) WMI_TIMEOUT); if (timeleft <= 0) { clear_bit(WMI_READY, &ar->flag); + ath6kl_init_hw_reset(ar); + ath6kl_bmi_reset(ar); ath6kl_err("wmi is not ready or wait was interrupted: %ld\n", timeleft); ret = -EIO; From 7030a10bf5d21cfbfe7b223b609e2e910bfd9e7f Mon Sep 17 00:00:00 2001 From: James Minor Date: Mon, 25 Apr 2016 12:18:10 -0500 Subject: [PATCH 056/100] ath6kl: Retry SDIO function initialization on failure Sometimes the AR6234 gives us a error "ath6kl: Unable to enable sdio func: -62". This indicates that the enable bit for the function did not result in the function's status bit in the SDIO_CCCR_IORx register getting set within a reasonable period of time (like 400ms). The guess at this point is that the radio is coming up in some strange state and the power-on reset did not clean things up as it should have. This occurs about once every thousand or so reboots. Experimentation has shown that resetting the device after this has happened allows the function enable to correctly set the function's bit in the SDIO_CCCR_IORx. This change will reset the AR6234 and try the function enable again if the module parameter boot_attempts is set to >0. This has been tested over several thousand reboots, and the driver will recover correctly when it would have otherwise failed to initialize. Signed-off-by: James Minor Signed-off-by: Brad Mouring Acked-by: Nathan Sullivan Acked-by: Xander Huff Natinst-ReviewBoard-ID: 135864 Natinst-CAR-ID: 579000 --- drivers/net/wireless/ath/ath6kl/core.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/net/wireless/ath/ath6kl/core.c b/drivers/net/wireless/ath/ath6kl/core.c index d5d46dc0c8643..de1ccff4bddf7 100644 --- a/drivers/net/wireless/ath/ath6kl/core.c +++ b/drivers/net/wireless/ath/ath6kl/core.c @@ -142,6 +142,15 @@ int ath6kl_core_init(struct ath6kl *ar, enum ath6kl_htc_type htc_type) * seconds. */ ret = ath6kl_hif_power_on(ar); + while (ret && ar->boot_attempts) { + ath6kl_err("Failed to turn on hardware: %d (retry %d)\n", + ret, + ar->boot_attempts); + ar->boot_attempts--; + ret = ath6kl_hif_power_off(ar); + ret = ath6kl_hif_power_on(ar); + } + if (ret) goto err_bmi_cleanup; From 01c79c5410e640aeb25887255bc62fb654bdeafc Mon Sep 17 00:00:00 2001 From: Wilson Lee Date: Mon, 5 Jun 2017 11:00:51 +0800 Subject: [PATCH 057/100] ni: wifi: ath6kl: Enable BIOS code to load "bdata.XX.bin" board file. Linux upstream had accepted the load of different board file using DTS method with board file name format of "bdata.XX.bin". Hence, we need to modify BIOS code to use same board file name format to match with the upstream code. Signed-off-by: Wilson Lee Signed-off-by: Brad Mouring Acked-by: Keng Soon Cheah Acked-by: Joseph Hershberger Acked-by: Chen Yee Chew Natinst-ReviewBoard-ID: 203623 Perforce-ReviewBoard-ID: 203621 --- drivers/net/wireless/ath/ath6kl/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath6kl/core.c b/drivers/net/wireless/ath/ath6kl/core.c index de1ccff4bddf7..700bdb6b8a3da 100644 --- a/drivers/net/wireless/ath/ath6kl/core.c +++ b/drivers/net/wireless/ath/ath6kl/core.c @@ -181,7 +181,7 @@ int ath6kl_core_init(struct ath6kl *ar, enum ath6kl_htc_type htc_type) */ region_board_file = devm_kzalloc(ar->dev, 64, GFP_KERNEL); - snprintf(region_board_file, 64, AR6004_HW_3_0_FW_DIR "/bdata%c%c.bin", + snprintf(region_board_file, 64, AR6004_HW_3_0_FW_DIR "/bdata.%c%c.bin", region[0], region[1]); ar->hw.fw_board = region_board_file; From 39bec8a0dc73afc2e7288a08b6e0bc382f44f637 Mon Sep 17 00:00:00 2001 From: James Minor Date: Tue, 27 Feb 2018 16:08:49 -0600 Subject: [PATCH 058/100] net: ath6kl: silex: Separate region and board file selection To support the single antenna board files for products with 1 antenna, separate out the selection of the region from the selection of the board file. On OF platforms, there will now be 2 device tree entries: atheros,region-code - The region code (like US) atheros,board-id - The board file code (like 00, 10, etc) In the process, do a small refactor of the CONFIG_ATH6KL_NI_BIOS_DOMAIN case to be more consistent with the device tree case. Signed-off-by: James Minor Signed-off-by: Brad Mouring Acked-by: Nathan Sullivan Acked-by: Kyle Roeschley Natinst-ReviewBoard-ID: 223288 Natinst-CAR-ID: 686866 --- drivers/net/wireless/ath/ath6kl/core.c | 61 ++--------------- drivers/net/wireless/ath/ath6kl/core.h | 4 ++ drivers/net/wireless/ath/ath6kl/init.c | 90 ++++++++++++++++++++++++++ 3 files changed, 98 insertions(+), 57 deletions(-) diff --git a/drivers/net/wireless/ath/ath6kl/core.c b/drivers/net/wireless/ath/ath6kl/core.c index 700bdb6b8a3da..e5a0619e4e066 100644 --- a/drivers/net/wireless/ath/ath6kl/core.c +++ b/drivers/net/wireless/ath/ath6kl/core.c @@ -21,8 +21,6 @@ #include #include #include -#include -#include #include "debug.h" #include "hif-ops.h" @@ -56,31 +54,6 @@ MODULE_PARM_DESC(heart_beat_poll, MODULE_PARM_DESC(boot_attempts, "Number of times to retry booting the firmware"); -#define WLAN_REGION_ID 161 -#ifdef CONFIG_ATH6KL_NI_BIOS_DOMAIN -struct region_table { - struct dmi_header header; - char padding[3]; - char alpha2[2]; -}; - -static char region[2]; -static void find_region_type(const struct dmi_header *dm, void *private_data) -{ - int *found = (int *)private_data; - - if (dm->type == WLAN_REGION_ID) { - struct region_table *table = - container_of(dm, struct region_table, header); - - ath6kl_dbg(ATH6KL_DBG_TRC, "Region code from BIOS: %c%c\n", - table->alpha2[0], table->alpha2[1]); - memcpy(region, table->alpha2, 2); - *found = 1; - } -} -#endif - void ath6kl_core_tx_complete(struct ath6kl *ar, struct sk_buff *skb) { ath6kl_htc_tx_complete(ar, skb); @@ -99,21 +72,6 @@ int ath6kl_core_init(struct ath6kl *ar, enum ath6kl_htc_type htc_type) struct wireless_dev *wdev; int ret = 0, i; -#ifdef CONFIG_ATH6KL_NI_BIOS_DOMAIN - char *region_board_file = NULL; - /* get region code from DMI */ - dmi_walk(find_region_type, &ret); - if (!ret) - return -ENODEV; - - if (!isascii(region[0]) || !isascii(region[1])) - return -EINVAL; - - ath6kl_info("Using region: %c%c\n", - region[0], - region[1]); -#endif - ar->boot_attempts = boot_attempts; switch (htc_type) { @@ -175,17 +133,6 @@ int ath6kl_core_init(struct ath6kl *ar, enum ath6kl_htc_type htc_type) ar->testmode = testmode; -#ifdef CONFIG_ATH6KL_NI_BIOS_DOMAIN - /* ath6kl_init_hw_params() will set the board file name, but we want - * to override it with a region specific board file here. - */ - region_board_file = devm_kzalloc(ar->dev, 64, GFP_KERNEL); - - snprintf(region_board_file, 64, AR6004_HW_3_0_FW_DIR "/bdata.%c%c.bin", - region[0], region[1]); - - ar->hw.fw_board = region_board_file; -#endif ret = ath6kl_init_fetch_firmwares(ar); if (ret) goto err_htc_cleanup; @@ -268,10 +215,10 @@ int ath6kl_core_init(struct ath6kl *ar, enum ath6kl_htc_type htc_type) /* Did not boot after several attempts */ goto err_rxbuf_cleanup; -#ifdef CONFIG_ATH6KL_NI_BIOS_DOMAIN - /* set region from DMI if it is US */ - if (region[0] == 'U' && region[1] == 'S') { - ret = ath6kl_wmi_set_regdomain_cmd(ar->wmi, region); +#ifdef CONFIG_ATH6KL_SILEX_FIRMWARE + /* set US region if this device is a US device (US or 1S) */ + if (ar->region[0] == 'U' && ar->region[1] == 'S') { + ret = ath6kl_wmi_set_regdomain_cmd(ar->wmi, ar->region); if (ret) goto err_rxbuf_cleanup; } diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h index 2c9c0cac314eb..6fdbaf977154d 100644 --- a/drivers/net/wireless/ath/ath6kl/core.h +++ b/drivers/net/wireless/ath/ath6kl/core.h @@ -877,6 +877,10 @@ struct ath6kl { /* Number of times we have attempted to boot the radio */ unsigned int boot_attempts; + +#ifdef CONFIG_ATH6KL_SILEX_FIRMWARE + unsigned char region[2]; +#endif }; static inline struct ath6kl *ath6kl_priv(struct net_device *dev) diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c index b98fb5fcab278..7b5a981570cc8 100644 --- a/drivers/net/wireless/ath/ath6kl/init.c +++ b/drivers/net/wireless/ath/ath6kl/init.c @@ -24,6 +24,8 @@ #include #include #include +#include +#include #include "core.h" #include "cfg80211.h" @@ -32,6 +34,8 @@ #include "hif-ops.h" #include "htc-ops.h" +#define WLAN_REGION_ID 161 + static const struct ath6kl_hw hw_list[] = { { .id = AR6003_HW_2_0_VERSION, @@ -706,6 +710,10 @@ static bool check_device_tree(struct ath6kl *ar) char board_filename[64]; const char *board_id; int ret; +#ifdef CONFIG_ATH6KL_SILEX_FIRMWARE + static const char *region_code_prop = "atheros,region-code"; + const char *region_code; +#endif for_each_compatible_node(node, NULL, "atheros,ath6kl") { board_id = of_get_property(node, board_id_prop, NULL); @@ -724,6 +732,16 @@ static bool check_device_tree(struct ath6kl *ar) board_filename, ret); continue; } +#ifdef CONFIG_ATH6KL_SILEX_FIRMWARE + region_code = of_get_property(node, region_code_prop, NULL); + if (region_code == NULL) { + ath6kl_warn("No \"%s\" property on %s node.\n", + region_code_prop, node->name); + continue; + } + /* Silex firmware needs a region command in some cases */ + memcpy(&ar->region, region_code, 2); +#endif of_node_put(node); return true; } @@ -736,6 +754,73 @@ static bool check_device_tree(struct ath6kl *ar) } #endif /* CONFIG_OF */ +#ifdef CONFIG_ATH6KL_NI_BIOS_DOMAIN +struct region_table { + struct dmi_header header; + char padding[3]; + char alpha2[2]; +}; + +static char region[2]; +static void find_region_type(const struct dmi_header *dm, void *private_data) +{ + int *found = (int *)private_data; + + if (dm->type == WLAN_REGION_ID) { + struct region_table *table = + container_of(dm, struct region_table, header); + + memcpy(region, table->alpha2, 2); + *found = 1; + } +} + +static bool check_ni_bios(struct ath6kl *ar) +{ + char *region_board_file = NULL; + int ret = 0; + + /* get region code from DMI */ + dmi_walk(find_region_type, &ret); + if (!ret) + return -ENODEV; + + if (!isascii(region[0]) || !isascii(region[1])) + return -EINVAL; + + ath6kl_info("Using BIOS region: %c%c\n", + region[0], + region[1]); + +#ifdef CONFIG_ATH6KL_SILEX_FIRMWARE + /* Silex firmware needs a region command in some cases */ + memcpy(&ar->region, region, 2); +#endif + + /* ath6kl_init_hw_params() will set the board file name, but we want + * to override it with a region specific board file here. + */ + region_board_file = devm_kzalloc(ar->dev, 64, GFP_KERNEL); + + snprintf(region_board_file, 64, AR6004_HW_3_0_FW_DIR "/bdata.%c%c.bin", + region[0], region[1]); + + ret = ath6kl_get_fw(ar, region_board_file, &ar->fw_board, + &ar->fw_board_len); + if (ret) { + ath6kl_err("Failed to get BIOS board file %s: %d\n", + region_board_file, ret); + return false; + } + return true; +} +#else +static bool check_ni_bios(struct ath6kl *ar) +{ + return false; +} +#endif /* CONFIG_ATH6KL_NI_BIOS_DOMAIN */ + static int ath6kl_fetch_board_file(struct ath6kl *ar) { const char *filename; @@ -761,6 +846,11 @@ static int ath6kl_fetch_board_file(struct ath6kl *ar) return 0; } + if (check_ni_bios(ar)) { + /* got board file from BIOS */ + return 0; + } + /* there was no proper board file, try to use default instead */ ath6kl_warn("Failed to get board file %s (%d), trying to find default board file.\n", filename, ret); From 82490fc1d56b8dd8530a7483256d4605372fb87d Mon Sep 17 00:00:00 2001 From: Brenda Streiff Date: Thu, 16 Oct 2025 12:16:49 -0500 Subject: [PATCH 059/100] net: dsa: mv88e6xxx: embed rx timestamps into packets Marvell's "Generation 3" and later PTP switches have support for embedding the switch timestamp counter into incoming packets, which eliminates timestamp overwrites/discards due to not being able to read timestamps out over SMI in time when receiving many packets at once. On applicable hardware, we configure the switch to embed the timestamp into the "reserved2" field. (Older switches have to read out the timestamp counter the current way.) We still need to queue the packet for a worker because we need to take the reg lock, but we can simplify down to only needing a single rx queue instead of splitting based on PTP packet type. Signed-off-by: Brenda Streiff --- drivers/net/dsa/mv88e6xxx/hwtstamp.c | 100 ++++++++++++++++++++++++--- 1 file changed, 89 insertions(+), 11 deletions(-) diff --git a/drivers/net/dsa/mv88e6xxx/hwtstamp.c b/drivers/net/dsa/mv88e6xxx/hwtstamp.c index 6e6472a3b75ad..2695c5919a797 100644 --- a/drivers/net/dsa/mv88e6xxx/hwtstamp.c +++ b/drivers/net/dsa/mv88e6xxx/hwtstamp.c @@ -56,6 +56,21 @@ static int mv88e6xxx_ptp_read(struct mv88e6xxx_chip *chip, int addr, return chip->info->ops->avb_ops->ptp_read(chip, addr, data, 1); } +static int mv88e6xxx_can_embed_rxtstamp(struct mv88e6xxx_chip *chip) +{ + switch (chip->info->family) { + /* Families with "Generation 3" and later PTP IP */ + case MV88E6XXX_FAMILY_6320: + case MV88E6XXX_FAMILY_6341: + case MV88E6XXX_FAMILY_6352: + case MV88E6XXX_FAMILY_6390: + case MV88E6XXX_FAMILY_6393: + return true; + default: + return false; + } +} + /* TX_TSTAMP_TIMEOUT: This limits the time spent polling for a TX * timestamp. When working properly, hardware will produce a timestamp * within 1ms. Software may enounter delays due to MDIO contention, so @@ -301,22 +316,71 @@ static void mv88e6xxx_get_rxts(struct mv88e6xxx_chip *chip, } } +static void mv88e6xxx_get_rxts_from_header(struct mv88e6xxx_chip *chip, + struct mv88e6xxx_port_hwtstamp *ps, + struct sk_buff *skb, + struct sk_buff_head *rxq) +{ + struct skb_shared_hwtstamps *shwt; + struct sk_buff_head received; + struct ptp_header *hdr; + unsigned long flags; + unsigned int type; + u64 ns; + + __skb_queue_head_init(&received); + spin_lock_irqsave(&rxq->lock, flags); + skb_queue_splice_tail_init(rxq, &received); + spin_unlock_irqrestore(&rxq->lock, flags); + + for ( ; skb; skb = __skb_dequeue(&received)) { + type = SKB_PTP_TYPE(skb); + hdr = ptp_parse_header(skb, type); + if (hdr) { + /* The hardware was configured to embed the timestamp + * into the reserved field in the incoming packet. + */ + ns = be32_to_cpu(hdr->reserved2); + + /* The hardware, however, did not update any applicable + * checksums (such as for UDP) so reset the reserved + * field to 0 so that it matches the state from when + * the checksum was generated. + */ + hdr->reserved2 = 0; + + mv88e6xxx_reg_lock(chip); + ns = timecounter_cyc2time(&chip->tstamp_tc, ns); + mv88e6xxx_reg_unlock(chip); + shwt = skb_hwtstamps(skb); + memset(shwt, 0, sizeof(*shwt)); + shwt->hwtstamp = ns_to_ktime(ns); + } + netif_rx(skb); + } +} + static void mv88e6xxx_rxtstamp_work(struct mv88e6xxx_chip *chip, struct mv88e6xxx_port_hwtstamp *ps) { const struct mv88e6xxx_ptp_ops *ptp_ops = chip->info->ops->ptp_ops; struct sk_buff *skb; - skb = skb_dequeue(&ps->rx_queue); - - if (skb) - mv88e6xxx_get_rxts(chip, ps, skb, ptp_ops->arr0_sts_reg, - &ps->rx_queue); - - skb = skb_dequeue(&ps->rx_queue2); - if (skb) - mv88e6xxx_get_rxts(chip, ps, skb, ptp_ops->arr1_sts_reg, - &ps->rx_queue2); + if (mv88e6xxx_can_embed_rxtstamp(chip)) { + skb = skb_dequeue(&ps->rx_queue); + if (skb) + mv88e6xxx_get_rxts_from_header(chip, ps, skb, &ps->rx_queue); + } else { + skb = skb_dequeue(&ps->rx_queue); + if (skb) + mv88e6xxx_get_rxts(chip, ps, skb, ptp_ops->arr0_sts_reg, + &ps->rx_queue); + + skb = skb_dequeue(&ps->rx_queue2); + if (skb) + mv88e6xxx_get_rxts(chip, ps, skb, ptp_ops->arr1_sts_reg, + &ps->rx_queue2); + } } static int is_pdelay_resp(const struct ptp_header *hdr) @@ -343,7 +407,7 @@ bool mv88e6xxx_port_rxtstamp(struct dsa_switch *ds, int port, SKB_PTP_TYPE(skb) = type; - if (is_pdelay_resp(hdr)) + if (is_pdelay_resp(hdr) && !mv88e6xxx_can_embed_rxtstamp(chip)) skb_queue_tail(&ps->rx_queue2, skb); else skb_queue_tail(&ps->rx_queue, skb); @@ -529,6 +593,20 @@ int mv88e6352_hwtstamp_port_disable(struct mv88e6xxx_chip *chip, int port) int mv88e6352_hwtstamp_port_enable(struct mv88e6xxx_chip *chip, int port) { + int err; + + if (mv88e6xxx_can_embed_rxtstamp(chip)) { + /* Some versions of the Marvell PTP IP can be configured to + * place timestamps into the 32-bit "reserved" field; this + * avoids the possibility of timestamps being overwritten + * because software hasn't read them in time. + */ + err = mv88e6xxx_port_ptp_write(chip, port, MV88E6XXX_PORT_PTP_CFG2, + MV88E6XXX_PORT_PTP_CFG2_EMBED_ARRIVAL); + if (err) + return err; + } + return mv88e6xxx_port_ptp_write(chip, port, MV88E6XXX_PORT_PTP_CFG0, MV88E6XXX_PORT_PTP_CFG0_DISABLE_TSPEC_MATCH); } From 5bd23240ef5717533be2cfe2720bf42ae4cef155 Mon Sep 17 00:00:00 2001 From: Brenda Streiff Date: Fri, 17 Oct 2025 11:14:24 -0500 Subject: [PATCH 060/100] net: dsa: mv88e6xxx: add 1588-related addresses to ATU as management frames The mv88e6xxx driver uses the hardware's trunking capabilities in order to offload link aggregation. When packets ingress a trunked port, the DSA tag that is added has a trunk ID rather than a port ID. This is undesirable for when doing 1588 timestamping, because timestamping is port-centric, but when we receive a 1588 packet in a LAG, the DSA infrastructure doesn't know which port it came from and just delivers it to the bond/team interface. This behavior can be avoided by marking frames as being "management" in the ATU; therefore, define a set of "extra management DAs" to be configured with priority for every VLAN. This set currently includes destination addresses relevant for L2 and L4 1588. This is not needed for 802.1AS, because 802.1AS packets use a destination address of 01:80:c2:00:00:0e, which is already covered by the rsvd2cpu functionality. Signed-off-by: Brenda Streiff --- drivers/net/dsa/mv88e6xxx/chip.c | 66 ++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c index 09002c853b78e..b27912aa5df62 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.c +++ b/drivers/net/dsa/mv88e6xxx/chip.c @@ -2598,6 +2598,64 @@ static int mv88e6xxx_port_broadcast_sync(struct mv88e6xxx_chip *chip, int port, &ctx); } +/* The rsvd2cpu function can trap frames with destination addresses of + * 01:80:c2:00:00:0x and 01:80:c2:00:00:2x as management, but there are + * other such frames that need to be trapped to the CPU, such as destination + * addresses associated with 1588, that are not in those ranges. + */ + +static const u8 mv88e6xxx_extra_mgmt_da[][ETH_ALEN] = { + /* 1588 layer 2 */ + { 0x01, 0x1b, 0x19, 0x00, 0x00, 0x00 }, + /* 1588 IPv4: 224.0.1.129 */ + { 0x01, 0x00, 0x5e, 0x00, 0x01, 0x81 }, + /* 1588 IPv4 P2P: 224.0.0.107 */ + { 0x01, 0x00, 0x5e, 0x00, 0x00, 0x6b }, + /* 1588 IPv6: ff0e::181 */ + { 0x33, 0x33, 0x00, 0x00, 0x01, 0x81 }, + /* 1588 IPv6 P2P: ff02::6b */ + { 0x33, 0x33, 0x00, 0x00, 0x00, 0x6b }, +}; + +static int mv88e6xxx_port_add_extra_mgmt(struct mv88e6xxx_chip *chip, int port, + u16 vid) +{ + u8 state = MV88E6XXX_G1_ATU_DATA_STATE_MC_STATIC_DA_MGMT_PO; + int i, err; + + for (i = 0; i < ARRAY_SIZE(mv88e6xxx_extra_mgmt_da); i++) { + err = mv88e6xxx_port_db_load_purge(chip, port, + mv88e6xxx_extra_mgmt_da[i], + vid, state); + if (err) + return err; + } + + return 0; +} + +static int mv88e6xxx_extra_mgmt_setup(struct mv88e6xxx_chip *chip, u16 vid) +{ + int port; + int err; + + for (port = 0; port < mv88e6xxx_num_ports(chip); port++) { + struct dsa_port *dp = dsa_to_port(chip->ds, port); + + if (dsa_is_unused_port(chip->ds, port)) + continue; + + if (!dsa_is_cpu_port(chip->ds, port)) + continue; + + err = mv88e6xxx_port_add_extra_mgmt(chip, port, vid); + if (err) + return err; + } + + return 0; +} + static int mv88e6xxx_port_vlan_join(struct mv88e6xxx_chip *chip, int port, u16 vid, u8 member, bool warn) { @@ -2635,6 +2693,10 @@ static int mv88e6xxx_port_vlan_join(struct mv88e6xxx_chip *chip, int port, err = mv88e6xxx_broadcast_setup(chip, vlan.vid); if (err) return err; + + err = mv88e6xxx_extra_mgmt_setup(chip, vlan.vid); + if (err) + return err; } else if (vlan.member[port] != member) { vlan.member[port] = member; @@ -4044,6 +4106,10 @@ static int mv88e6xxx_setup(struct dsa_switch *ds) if (err) goto unlock; + err = mv88e6xxx_extra_mgmt_setup(chip, 0); + if (err) + goto unlock; + err = mv88e6xxx_pot_setup(chip); if (err) goto unlock; From 4ce32a9e6bcb7abea10b3f971f53aa300e71b70e Mon Sep 17 00:00:00 2001 From: Kyle Roeschley Date: Tue, 15 May 2018 13:56:50 -0500 Subject: [PATCH 061/100] mmc: sdhci: Handle tuning error interrupts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Per the §2.2.19 of the SD Host Controller Simplified Specification Version 4.20, the Tuning Error interrupt is set when an unrecoverable error is detected by the host controller in the tuning circuit when not executing the tuning procedure. Handle this interrupt by printing a useful error message and re-tuning (also per the spec). 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: 696866 [gratian: adjust includes for 5857b29b96dc ("mmc: core: Move public functions from host.h to private headers")] Signed-off-by: Gratian Crisan [cvadrevu: resolve conflict with d9ae0aa8ff8fd ("mmc: sdhci: Add support for "Tuning Error" interrupts")] Signed-off-by: Chaitanya Vadrevu --- drivers/mmc/host/sdhci.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index ac7e11f37af71..7ee497da46611 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -32,6 +32,7 @@ #include #include +#include "../core/host.h" #include "sdhci.h" #define DRIVER_NAME "sdhci" @@ -307,7 +308,7 @@ static void sdhci_set_default_irqs(struct sdhci_host *host) if (host->tuning_mode == SDHCI_TUNING_MODE_2 || host->tuning_mode == SDHCI_TUNING_MODE_3) - host->ier |= SDHCI_INT_RETUNE; + host->ier |= SDHCI_INT_RETUNE | SDHCI_INT_TUNING_ERROR; sdhci_writel(host, host->ier, SDHCI_INT_ENABLE); sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); @@ -3632,6 +3633,24 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id) if (intmask & SDHCI_INT_RETUNE) mmc_retune_needed(host->mmc); + if (intmask & SDHCI_INT_TUNING_ERROR) { + u16 ctrl2 = sdhci_readw(host, SDHCI_HOST_CONTROL2); + /* + * Only complain and retune if we're actually using the + * host's tuning circuits. + */ + if (ctrl2 & SDHCI_CTRL_TUNED_CLK) { + sdhci_writew(host, + ctrl2 & ~SDHCI_CTRL_TUNED_CLK, + SDHCI_HOST_CONTROL2); + mmc_retune_recheck(host->mmc); + pr_err("%s: Unrecoverable error in tuning circuit\n", + mmc_hostname(host->mmc)); + } + sdhci_writel(host, SDHCI_INT_TUNING_ERROR, + SDHCI_INT_STATUS); + } + if ((intmask & SDHCI_INT_CARD_INT) && (host->ier & SDHCI_INT_CARD_INT)) { sdhci_enable_sdio_irq_nolock(host, false); @@ -3641,7 +3660,8 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id) intmask &= ~(SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE | SDHCI_INT_CMD_MASK | SDHCI_INT_DATA_MASK | SDHCI_INT_ERROR | SDHCI_INT_BUS_POWER | - SDHCI_INT_RETUNE | SDHCI_INT_CARD_INT); + SDHCI_INT_RETUNE | SDHCI_INT_TUNING_ERROR | + SDHCI_INT_CARD_INT); if (intmask) { unexpected |= intmask; From 68316345b258e41b7bafd0f9b02ab53eccf3ce12 Mon Sep 17 00:00:00 2001 From: Erick Shepherd Date: Wed, 21 Aug 2024 14:33:53 -0500 Subject: [PATCH 062/100] Revert "mmc: sdhci: Add support for "Tuning Error" interrupts" This reverts commit d9ae0aa8ff8fd26c7b7fa3cad04ec54bb3b4b920. It provides similar functionality to our out-of-tree commit 13dc7b7 ("mmc: sdhci: Handle tuning error interrupts"). However it doesn't cover the cases where the "Tuning Error" interrupt is received during sdhci operations that don't have a data transfer associated with them. On our systems this results in a kernel splat: mmc0: Got data interrupt 0x04000000 even though no data operation was in progress. mmc0: sdhci: ============ SDHCI REGISTER DUMP =========== mmc0: sdhci: Sys addr: 0x12a65200 | Version: 0x0000b502 mmc0: sdhci: Blk size: 0x00007040 | Blk cnt: 0x00000001 mmc0: sdhci: Argument: 0x00010000 | Trn mode: 0x00000010 mmc0: sdhci: Present: 0x01ff0000 | Host ctl: 0x00000016 mmc0: sdhci: Power: 0x0000000f | Blk gap: 0x00000000 mmc0: sdhci: Wake-up: 0x00000000 | Clock: 0x00000107 mmc0: sdhci: Timeout: 0x0000000a | Int stat: 0x00000000 mmc0: sdhci: Int enab: 0x03ff008b | Sig enab: 0x03ff008b mmc0: sdhci: ACmd stat: 0x00000000 | Slot int: 0x00000000 mmc0: sdhci: Caps: 0x076864b2 | Caps_1: 0x00000004 mmc0: sdhci: Cmd: 0x00000d1a | Max curr: 0x00000000 mmc0: sdhci: Resp[0]: 0x00400900 | Resp[1]: 0x00000000 mmc0: sdhci: Resp[2]: 0x00000000 | Resp[3]: 0x00000000 mmc0: sdhci: Host ctl2: 0x0000000c mmc0: sdhci: ADMA Err: 0x00000003 | ADMA Ptr: 0x12a65200 mmc0: sdhci: ============================================ I/O error, dev mmcblk0, sector 0 op 0x0:(READ) flags 0x0 phys_seg 1 prio class 2 Buffer I/O error on dev mmcblk0, logical block 0, async page read Revert the upstream commit in favor of our out-of-tree commit until a proper upstream fix is found. See link to ongoing upstream conversation. Natinst-AzDo-ID: 2805437 Link: https://lore.kernel.org/linux-mmc/87jzgur32p.fsf@ni.com [erick: fix conflict when reverting d9ae0aa ("mmc: sdhci.h: Add support for "Tuning Error" interrupts") in favor of our 2c7cba1 ("mmc: sdhci: Handle tuning error interrupts")] Signed-off-by: Erick Shepherd --- drivers/mmc/host/sdhci.c | 10 ++-------- drivers/mmc/host/sdhci.h | 2 +- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 7ee497da46611..379b84f57eb17 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -3475,18 +3475,12 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask) host->data->error = -EILSEQ; if (!mmc_op_tuning(SDHCI_GET_CMD(sdhci_readw(host, SDHCI_COMMAND)))) sdhci_err_stats_inc(host, DAT_CRC); - } else if ((intmask & (SDHCI_INT_DATA_CRC | SDHCI_INT_TUNING_ERROR)) && + } else if ((intmask & SDHCI_INT_DATA_CRC) && SDHCI_GET_CMD(sdhci_readw(host, SDHCI_COMMAND)) != MMC_BUS_TEST_R) { host->data->error = -EILSEQ; if (!mmc_op_tuning(SDHCI_GET_CMD(sdhci_readw(host, SDHCI_COMMAND)))) sdhci_err_stats_inc(host, DAT_CRC); - if (intmask & SDHCI_INT_TUNING_ERROR) { - u16 ctrl2 = sdhci_readw(host, SDHCI_HOST_CONTROL2); - - ctrl2 &= ~SDHCI_CTRL_TUNED_CLK; - sdhci_writew(host, ctrl2, SDHCI_HOST_CONTROL2); - } } else if (intmask & SDHCI_INT_ADMA_ERROR) { pr_err("%s: ADMA error: 0x%08x\n", mmc_hostname(host->mmc), intmask); @@ -4039,7 +4033,7 @@ bool sdhci_cqe_irq(struct sdhci_host *host, u32 intmask, int *cmd_error, } else *cmd_error = 0; - if (intmask & (SDHCI_INT_DATA_END_BIT | SDHCI_INT_DATA_CRC | SDHCI_INT_TUNING_ERROR)) { + if (intmask & (SDHCI_INT_DATA_END_BIT | SDHCI_INT_DATA_CRC)) { *data_error = -EILSEQ; if (!mmc_op_tuning(SDHCI_GET_CMD(sdhci_readw(host, SDHCI_COMMAND)))) sdhci_err_stats_inc(host, DAT_CRC); diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index b6a571d866fa5..3201d21af793a 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -204,7 +204,7 @@ SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL | \ SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_DATA_CRC | \ SDHCI_INT_DATA_END_BIT | SDHCI_INT_ADMA_ERROR | \ - SDHCI_INT_BLK_GAP | SDHCI_INT_TUNING_ERROR) + SDHCI_INT_BLK_GAP) #define SDHCI_INT_ALL_MASK ((unsigned int)-1) #define SDHCI_CQE_INT_ERR_MASK ( \ From aa5a9e3956ea944b2ce546f9716702ab1c83db4d Mon Sep 17 00:00:00 2001 From: Karthik Manamcheri Date: Fri, 14 Mar 2014 13:15:59 -0500 Subject: [PATCH 063/100] 8250: Do not create ttyS* nodes for nonexistant devices This commit is a merge of two upstream-unfriendly commits: commit ba93f2d13b34 ("8250: Make SERIAL_8250_RUNTIME_UARTS work correctly") commit 0d1ed2d7adc1 ("Revert "serial: 8250: Do nothing if nr_uarts=0"") This was an attempt to resolve an architectural oddity in the 8250 core code, which was that, by design, it will create a static (build- or cmdline-specified) number of ttyS* devices, which is at odds with how most other Linux kernel drivers work. The original commit messages did not accurately describe the problem, so this is a merge-and-replace in order to get a better commit description. So, without further ado: The current state of affairs is as follows: There exists two build-time constants. - CONFIG_SERIAL_8250_NR_UARTS: the build-time max number of 8250 UARTs. - CONFIG_SERIAL_8250_RUNTIME_UARTS: the boot-time number of 8250 UARTs. (confusingly, this is also the default setting of 8250.nr_uarts) The way that the 8250 driver handles creation of ttyS* device is that, at initialize time, we create min(8250.nr_uarts, NR_UARTS) ttyS* devices up-front, and when a UART is registered, serial8250_find_match_or_unused will either merge it in under an existing ttyS* or find an unused one. There also exists code in the 8250 driver to automatically enumerate the UARTs specified in the SERIAL_PORT_DFNS table; these are the "well-known" ports at 0x3F8/0x2F8/0x3E8/0x2E8 from the IBM PC platform, and they are added this way because they predate the use of ACPI tables for enumeration. (Oh, and also you can point the ttyS* devices to completely different addresses from userspace via TIOCSSERIAL.) This has two ramifications for NI devices: 1) There is a limit on number of UARTs with 8250_core; this is a noteworthy problem when you are also a vendor of multiport serial cards, such as the PXIe-8430/16. However, the user experience of increasing the limit with a generic platform kernel is also bad; if, as a distro, we release a kernel with a default limit of 128, then users that have PXI systems that don't have any multiport serial cards will still be presented with devices named ttyS0 through ttyS127, even though most of them are just "empty" slots that are not backed by real devices. 2) ttyS0 through ttyS3 will always be given the addresses for the "legacy" serial ports, even if on-board controller ports are at different addresses. This is the case on several NI controllers; for example, on some sbRIO products [1] the UARTs are at 0x3F8, 0x350, 0x360, etc. However, because the legacy ports get first-dibs, those ports will be ttyS0, ttyS4, ttyS5, ... because the legacy 0x2f8/0x3E8/0x2E8 get S1-S3. Our initial attempt at resolving this was to redefine 8250.nr_uarts to mean "the number of automatically-created UART entries" and define it to be 0 (because we neither want the legacy ports nor the extra "empty" ports). On NI platforms, all serial ports are described in the ACPI table, so legacy enumeration is neither necessary nor desirable. However, this approach got soundly rejected upstream because it "caused existing kernel configurations to act differently from before" [2]. We're not alone in finding the upstream behavior to be counterintuitive; I have found at least two other attempts [3, 4] to resolve it with similar pushback of the form "this breaks existing users". A "proper" upstreamable solution probably needs two parts, with the default settings such that the current behavior is retained but can be opted-out (via Kconfig and/or kernel cmdline). - a config token for "don't create a bunch of empty devices" (1) - a config token for "don't add legacy ports, let ACPI handle it" (2) Until that arrives, we're stuck keeping this around, because we're _also_ stuck with not wanting to renumber ttyS* devices from the way we've shipped them. [1] https://github.com/ni/meta-nilrt/blob/8106f31da6980ee4ee94fa0e03b991479d9aa43e/recipes-kernel/kernel-tests/kernel-tests-files/test_kernel_serial_devices.sh#L127 [2] https://lore.kernel.org/lkml/20130603213754.GA15479@kroah.com/ [3] https://lore.kernel.org/linux-serial/1420513785-23660-1-git-send-email-peter@hurleysoftware.com/ [4] https://lore.kernel.org/linux-serial/20221025073944.102437-1-martin@geanix.com/ [SBOs from initial patches] Natinst-CAR-ID: 634278 Signed-off-by: Karthik Manamcheri Signed-off-by: Richard Tollerton Signed-off-by: Brad Mouring Natinst-ReviewBoard-ID: 183619 Upstream-Status: Denied [rejected upstream] Natinst-AzDO-ID: 2133864 Signed-off-by: Brenda Streiff [mpeterse: resolved trivial conflict with refactoring loop body to a function] Signed-off-by: Mike Petersen [cvadrevu: resolved conflict with ffd8e8bd26e94 ("serial: 8250: Extract platform driver")] Signed-off-by: Chaitanya Vadrevu --- drivers/tty/serial/8250/8250_core.c | 13 +++++-------- drivers/tty/serial/8250/8250_platform.c | 7 ++----- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c index a820f5cda7e70..2b6a7d76c4e29 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c @@ -492,7 +492,7 @@ static int univ8250_console_match(struct console *co, char *name, int idx, return -ENODEV; /* try to match the port specified on the command line */ - for (i = 0; i < nr_uarts; i++) { + for (i = 0; i < UART_NR; i++) { struct uart_port *port = &serial8250_ports[i].port; if (port->iotype != iotype) @@ -529,9 +529,6 @@ static struct console univ8250_console = { static int __init univ8250_console_init(void) { - if (nr_uarts == 0) - return -ENODEV; - serial8250_isa_init_ports(); register_console(&univ8250_console); return 0; @@ -562,7 +559,7 @@ int __init early_serial_setup(struct uart_port *port) { struct uart_port *p; - if (port->line >= ARRAY_SIZE(serial8250_ports) || nr_uarts == 0) + if (port->line >= ARRAY_SIZE(serial8250_ports)) return -ENODEV; serial8250_isa_init_ports(); @@ -658,7 +655,7 @@ static struct uart_8250_port *serial8250_find_match_or_unused(const struct uart_ /* * First, find a port entry which matches. */ - for (i = 0; i < nr_uarts; i++) + for (i = 0; i < UART_NR; i++) if (uart_match_port(&serial8250_ports[i].port, port)) return &serial8250_ports[i]; @@ -672,7 +669,7 @@ static struct uart_8250_port *serial8250_find_match_or_unused(const struct uart_ * free entry. We look for one which hasn't been previously * used (indicated by zero iobase). */ - for (i = 0; i < nr_uarts; i++) + for (i = 0; i < UART_NR; i++) if (serial8250_ports[i].port.type == PORT_UNKNOWN && serial8250_ports[i].port.iobase == 0) return &serial8250_ports[i]; @@ -681,7 +678,7 @@ static struct uart_8250_port *serial8250_find_match_or_unused(const struct uart_ * That also failed. Last resort is to find any entry which * doesn't have a real port associated with it. */ - for (i = 0; i < nr_uarts; i++) + for (i = 0; i < UART_NR; i++) if (serial8250_ports[i].port.type == PORT_UNKNOWN) return &serial8250_ports[i]; diff --git a/drivers/tty/serial/8250/8250_platform.c b/drivers/tty/serial/8250/8250_platform.c index fe7ec440ffa58..864751b10a202 100644 --- a/drivers/tty/serial/8250/8250_platform.c +++ b/drivers/tty/serial/8250/8250_platform.c @@ -70,7 +70,7 @@ static void __init __serial8250_isa_init_ports(void) * default to CONFIG_SERIAL_8250_RUNTIME_UARTS. Note that we do not * need to increase nr_uarts when setting up the initial ISA ports. */ - for (i = 0; i < nr_uarts; i++) + for (i = 0; i < UART_NR; i++) serial8250_setup_port(i); /* chain base port ops to support Remote Supervisor Adapter */ @@ -237,7 +237,7 @@ static void serial8250_remove(struct platform_device *dev) { int i; - for (i = 0; i < nr_uarts; i++) { + for (i = 0; i < UART_NR; i++) { struct uart_8250_port *up = serial8250_get_port(i); if (up->port.dev == &dev->dev) @@ -300,9 +300,6 @@ static int __init serial8250_init(void) { int ret; - if (nr_uarts == 0) - return -ENODEV; - serial8250_isa_init_ports(); pr_info("Serial: 8250/16550 driver, %d ports, IRQ sharing %s\n", From 2490a08bcdec8431c78e00935a2c7555e7f5c648 Mon Sep 17 00:00:00 2001 From: Kevin Lim Date: Thu, 13 Feb 2025 10:17:35 +0800 Subject: [PATCH 064/100] serial: core: create anonymous parent device Use platform_device_register_simple to create a parent device if parent device pointer is null. Signed-off-by: Kevin Lim [gratian: fix trivial conflict with e52ed2dd8287 ("tty: serial_core: use more guard(mutex)")] Signed-off-by: Gratian Crisan --- drivers/tty/serial/serial_core.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 26db27d06a865..a01dd38539753 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -31,6 +31,7 @@ #include #include +#include #include "serial_base.h" @@ -3312,6 +3313,20 @@ int serial_core_register_port(struct uart_driver *drv, struct uart_port *port) */ port->flags |= UPF_DEAD; + if (port->dev == NULL) { + static unsigned int next_port_number; + char port_name[21]; + struct platform_device *pdev; + + snprintf(port_name, sizeof(port_name), "anon_port_%u", next_port_number++); + pdev = platform_device_register_simple(port_name, -1, NULL, 0); + + if (PTR_ERR_OR_ZERO(pdev)) + return -EINVAL; + + port->dev = &pdev->dev; + } + /* Inititalize a serial core controller device if needed */ ctrl_dev = serial_core_ctrl_find(drv, port->dev, port->ctrl_id); if (!ctrl_dev) { @@ -3346,6 +3361,9 @@ int serial_core_register_port(struct uart_driver *drv, struct uart_port *port) err_unregister_ctrl_dev: serial_base_ctrl_device_remove(new_ctrl_dev); + if (strncmp(to_platform_device(port->dev)->name, "anon_port", 9) == 0) + platform_device_del(to_platform_device(port->dev)); + return ret; } @@ -3373,6 +3391,9 @@ void serial_core_unregister_port(struct uart_driver *drv, struct uart_port *port if (!serial_core_ctrl_find(drv, phys_dev, ctrl_id)) serial_base_ctrl_device_remove(ctrl_dev); + if (strncmp(to_platform_device(phys_dev)->name, "anon_port", 9) == 0) + platform_device_del(to_platform_device(phys_dev)); + mutex_unlock(&port_mutex); } From ec0e06b821f4c8d9298c653c33b1ce7194ab7630 Mon Sep 17 00:00:00 2001 From: Kevin Lim Date: Wed, 12 Mar 2025 11:28:03 +0800 Subject: [PATCH 065/100] serial: core: add checking for platform device Commit 978ca75850f2 ("serial: core: create anonymous parent device") introduced a NULL pointer dereference when attempting to access the platform_device structure of the parent. This commit adds a check for parent's device type before getting its platform_device structure. Fixes: 978ca75850f2 ("serial: core: create anonymous parent device") Signed-off-by: Kevin Lim (cherry picked from commit 5238c99f6f46637508ce5c1d26387f010cec73f2) Signed-off-by: Chaitanya Vadrevu --- drivers/tty/serial/serial_core.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index a01dd38539753..3d136fac631b4 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -46,6 +46,10 @@ static DEFINE_MUTEX(port_mutex); */ static struct lock_class_key port_lock_key; +static struct device_type anon_dev_type = { + .name = "anon_port", +}; + #define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8) /* @@ -3304,6 +3308,7 @@ int serial_core_register_port(struct uart_driver *drv, struct uart_port *port) { struct serial_ctrl_device *ctrl_dev, *new_ctrl_dev = NULL; int ret; + bool is_parent_anon_port = false; guard(mutex)(&port_mutex); @@ -3325,6 +3330,8 @@ int serial_core_register_port(struct uart_driver *drv, struct uart_port *port) return -EINVAL; port->dev = &pdev->dev; + port->dev->type = &anon_dev_type; + is_parent_anon_port = true; } /* Inititalize a serial core controller device if needed */ @@ -3361,7 +3368,7 @@ int serial_core_register_port(struct uart_driver *drv, struct uart_port *port) err_unregister_ctrl_dev: serial_base_ctrl_device_remove(new_ctrl_dev); - if (strncmp(to_platform_device(port->dev)->name, "anon_port", 9) == 0) + if (is_parent_anon_port) platform_device_del(to_platform_device(port->dev)); return ret; @@ -3391,7 +3398,7 @@ void serial_core_unregister_port(struct uart_driver *drv, struct uart_port *port if (!serial_core_ctrl_find(drv, phys_dev, ctrl_id)) serial_base_ctrl_device_remove(ctrl_dev); - if (strncmp(to_platform_device(phys_dev)->name, "anon_port", 9) == 0) + if (phys_dev->type == &anon_dev_type) platform_device_del(to_platform_device(phys_dev)); mutex_unlock(&port_mutex); From d8c92644d5de06efb45693b813eb193927c8e205 Mon Sep 17 00:00:00 2001 From: Brenda Streiff Date: Thu, 19 Jan 2023 14:42:02 -0600 Subject: [PATCH 066/100] dt-bindings: serial: ni,ni16650: add bindings Add bindings for the NI 16550 UART. Signed-off-by: Brenda Streiff Cc: Gratian Crisan Cc: Jason Smith --- .../bindings/serial/ni,ni16550.yaml | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 Documentation/devicetree/bindings/serial/ni,ni16550.yaml diff --git a/Documentation/devicetree/bindings/serial/ni,ni16550.yaml b/Documentation/devicetree/bindings/serial/ni,ni16550.yaml new file mode 100644 index 0000000000000..72ab125dd8922 --- /dev/null +++ b/Documentation/devicetree/bindings/serial/ni,ni16550.yaml @@ -0,0 +1,51 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/serial/ni,ni16550.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: NI 16550 asynchronous serial interface (UART) + +maintainers: + - Brenda Streiff + +allOf: + - $ref: serial.yaml# + +properties: + compatible: + const: ni,ni16550 + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + maxItems: 1 + + ni,serial-port-mode: + description: Indicates whether this is an RS-232 or RS-485 serial port. + $ref: /schemas/types.yaml#/definitions/string + enum: [ RS-232, RS-485 ] + default: RS-485 + +required: + - compatible + - reg + - interrupts + +unevaluatedProperties: false + +examples: + - | + #include + serial@80000000 { + compatible = "ni,ni16550"; + reg = <0x80000000 0x8>; + interrupts = <0 30 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk_uart>; + ni,serial-port-mode = "RS-232"; + }; +... From 5911414bf44736bcaae95229b272d212d2f72108 Mon Sep 17 00:00:00 2001 From: Chaitanya Vadrevu Date: Thu, 27 Feb 2025 14:14:24 -0600 Subject: [PATCH 067/100] serial: 8250: Add device tree support Signed-off-by: Chaitanya Vadrevu [gratian: resolved minor conflicts] Signed-off-by: Gratian Crisan --- drivers/tty/serial/8250/8250_ni.c | 27 ++++++++++++++++++++------- drivers/tty/serial/8250/Kconfig | 2 +- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/drivers/tty/serial/8250/8250_ni.c b/drivers/tty/serial/8250/8250_ni.c index cb5b42b3609c9..b77dbcbdef303 100644 --- a/drivers/tty/serial/8250/8250_ni.c +++ b/drivers/tty/serial/8250/8250_ni.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -327,7 +328,8 @@ static int ni16550_probe(struct platform_device *pdev) /* * Declaration of the base clock frequency can come from one of: * - static declaration in this driver (for older ACPI IDs) - * - a "clock-frequency" ACPI + * - a "clock-frequency" ACPI or OF device property + * - an associated OF clock definition */ uart->port.uartclk = info->uartclk; @@ -353,14 +355,16 @@ static int ni16550_probe(struct platform_device *pdev) /* * The determination of whether or not this is an RS-485 or RS-232 port - * can come from the PMR (if present), otherwise we're solely an RS-485 - * port. + * can come from a device property (if present), or it can come from + * the PMR (if present), and otherwise we're solely an RS-485 port. * - * This is a device-specific property, and there are old devices in the - * field using "transceiver" as an ACPI property, so we have to check - * for that as well. + * This is a device-specific property, and thus has a vendor-prefixed + * "ni,serial-port-mode" form as a devicetree binding. However, there + * are old devices in the field using "transceiver" as an ACPI device + * property, so we have to check for that as well. */ - if (!device_property_read_string(dev, "transceiver", &portmode)) { + if (!device_property_read_string(dev, "ni,serial-port-mode", &portmode) || + !device_property_read_string(dev, "transceiver", &portmode)) { rs232_property = strncmp(portmode, "RS-232", 6) == 0; dev_dbg(dev, "port is in %s mode (via device property)\n", @@ -400,6 +404,14 @@ static void ni16550_remove(struct platform_device *pdev) serial8250_unregister_port(data->line); } +static const struct ni16550_device_info ni16550_default = { }; + +static const struct of_device_id ni16550_of_match[] = { + { .compatible = "ni,ni16550", .data = &ni16550_default }, + { }, +}; +MODULE_DEVICE_TABLE(of, ni16550_of_match); + /* NI 16550 RS-485 Interface */ static const struct ni16550_device_info nic7750 = { .uartclk = 33333333, @@ -437,6 +449,7 @@ MODULE_DEVICE_TABLE(acpi, ni16550_acpi_match); static struct platform_driver ni16550_driver = { .driver = { .name = "ni16550", + .of_match_table = ni16550_of_match, .acpi_match_table = ni16550_acpi_match, }, .probe = ni16550_probe, diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig index f64ef0819cd4e..cbc7de76a04c9 100644 --- a/drivers/tty/serial/8250/Kconfig +++ b/drivers/tty/serial/8250/Kconfig @@ -572,7 +572,7 @@ config SERIAL_8250_BCM7271 config SERIAL_8250_NI tristate "NI 16550 based serial port" depends on SERIAL_8250 - depends on X86 || COMPILE_TEST + depends on X86 || (ARCH_ZYNQ && OF) || COMPILE_TEST help This driver supports the integrated serial ports on National Instruments (NI) controller hardware. This is required for all NI From 324e9a86ca9018484f601b33980cd4860f1fb383 Mon Sep 17 00:00:00 2001 From: Gratian Crisan Date: Fri, 13 Jun 2014 11:03:29 -0500 Subject: [PATCH 068/100] devicetree: Create initial NI Zynq base device tree include file and overlays Create a common device tree include file for NI Zynq based products. Create initial overlays for Zynq based target variants. Signed-off-by: Gratian Crisan Signed-off-by: Josh Cartwright (cherry picked from commit c01c07f53b544def769b5f6a40fe61a8366c2097) Signed-off-by: deooi --- arch/arm/boot/dts/ni-793x.dts | 106 +++++++++++ arch/arm/boot/dts/ni-dosequis.dts | 136 ++++++++++++++ arch/arm/boot/dts/ni-myrio.dts | 93 ++++++++++ arch/arm/boot/dts/ni-roborio.dts | 191 ++++++++++++++++++++ arch/arm/boot/dts/ni-sbrio-9607.dts | 233 ++++++++++++++++++++++++ arch/arm/boot/dts/ni-sbrio-9627.dts | 247 +++++++++++++++++++++++++ arch/arm/boot/dts/ni-sbrio-9637.dts | 137 ++++++++++++++ arch/arm/boot/dts/ni-solbetter.dts | 191 ++++++++++++++++++++ arch/arm/boot/dts/ni-solenetexp.dts | 106 +++++++++++ arch/arm/boot/dts/ni-solgood.dts | 124 +++++++++++++ arch/arm/boot/dts/ni-tecate.dts | 153 ++++++++++++++++ arch/arm/boot/dts/ni-zynq.dtsi | 269 ++++++++++++++++++++++++++++ 12 files changed, 1986 insertions(+) create mode 100644 arch/arm/boot/dts/ni-793x.dts create mode 100644 arch/arm/boot/dts/ni-dosequis.dts create mode 100644 arch/arm/boot/dts/ni-myrio.dts create mode 100644 arch/arm/boot/dts/ni-roborio.dts create mode 100644 arch/arm/boot/dts/ni-sbrio-9607.dts create mode 100644 arch/arm/boot/dts/ni-sbrio-9627.dts create mode 100644 arch/arm/boot/dts/ni-sbrio-9637.dts create mode 100644 arch/arm/boot/dts/ni-solbetter.dts create mode 100644 arch/arm/boot/dts/ni-solenetexp.dts create mode 100644 arch/arm/boot/dts/ni-solgood.dts create mode 100644 arch/arm/boot/dts/ni-tecate.dts create mode 100644 arch/arm/boot/dts/ni-zynq.dtsi diff --git a/arch/arm/boot/dts/ni-793x.dts b/arch/arm/boot/dts/ni-793x.dts new file mode 100644 index 0000000000000..74e373ccad154 --- /dev/null +++ b/arch/arm/boot/dts/ni-793x.dts @@ -0,0 +1,106 @@ +/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/ni-dosequis.dts b/arch/arm/boot/dts/ni-dosequis.dts new file mode 100644 index 0000000000000..ea43df8ff569a --- /dev/null +++ b/arch/arm/boot/dts/ni-dosequis.dts @@ -0,0 +1,136 @@ +/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/ni-myrio.dts b/arch/arm/boot/dts/ni-myrio.dts new file mode 100644 index 0000000000000..cd944323a6cda --- /dev/null +++ b/arch/arm/boot/dts/ni-myrio.dts @@ -0,0 +1,93 @@ +/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/ni-roborio.dts b/arch/arm/boot/dts/ni-roborio.dts new file mode 100644 index 0000000000000..d41d9ba1f3bbe --- /dev/null +++ b/arch/arm/boot/dts/ni-roborio.dts @@ -0,0 +1,191 @@ +/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/ni-sbrio-9607.dts b/arch/arm/boot/dts/ni-sbrio-9607.dts new file mode 100644 index 0000000000000..e582fca748bf3 --- /dev/null +++ b/arch/arm/boot/dts/ni-sbrio-9607.dts @@ -0,0 +1,233 @@ +/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/ni-sbrio-9627.dts b/arch/arm/boot/dts/ni-sbrio-9627.dts new file mode 100644 index 0000000000000..435a6169e0604 --- /dev/null +++ b/arch/arm/boot/dts/ni-sbrio-9627.dts @@ -0,0 +1,247 @@ +/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/ni-sbrio-9637.dts b/arch/arm/boot/dts/ni-sbrio-9637.dts new file mode 100644 index 0000000000000..7626db67b8073 --- /dev/null +++ b/arch/arm/boot/dts/ni-sbrio-9637.dts @@ -0,0 +1,137 @@ +/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/ni-solbetter.dts b/arch/arm/boot/dts/ni-solbetter.dts new file mode 100644 index 0000000000000..b8315f0fe7506 --- /dev/null +++ b/arch/arm/boot/dts/ni-solbetter.dts @@ -0,0 +1,191 @@ +/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/ni-solenetexp.dts b/arch/arm/boot/dts/ni-solenetexp.dts new file mode 100644 index 0000000000000..a495ca23e8861 --- /dev/null +++ b/arch/arm/boot/dts/ni-solenetexp.dts @@ -0,0 +1,106 @@ +/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/ni-solgood.dts b/arch/arm/boot/dts/ni-solgood.dts new file mode 100644 index 0000000000000..4b25334247076 --- /dev/null +++ b/arch/arm/boot/dts/ni-solgood.dts @@ -0,0 +1,124 @@ +/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/ni-tecate.dts b/arch/arm/boot/dts/ni-tecate.dts new file mode 100644 index 0000000000000..15124e4b12cad --- /dev/null +++ b/arch/arm/boot/dts/ni-tecate.dts @@ -0,0 +1,153 @@ +/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>; +}; diff --git a/arch/arm/boot/dts/ni-zynq.dtsi b/arch/arm/boot/dts/ni-zynq.dtsi new file mode 100644 index 0000000000000..3cdbf768a0032 --- /dev/null +++ b/arch/arm/boot/dts/ni-zynq.dtsi @@ -0,0 +1,269 @@ +/include/ "zynq-7000.dtsi" + +/ { + model = "NI Zynq-based Target"; + compatible = "ni,zynq", "xlnx,zynq-7000"; + + /* Populated by the bootloader */ + memory@0 { + device_type = "memory"; + reg = <0 0>; + }; + chosen { }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + compatible = "arm,cortex-a9"; + device_type = "cpu"; + reg = <0>; + clocks = <&clkc 3>; + }; + + cpu@1 { + compatible = "arm,cortex-a9"; + device_type = "cpu"; + reg = <1>; + clocks = <&clkc 3>; + }; + }; + + amba@0 { + ni_uart0: serial@80000000 { + device_type = "serial"; + compatible = "ni16550-fifo128", "ns16550a"; + status = "disabled"; + reg = <0x80000000 0x8>; + interrupts = <0 30 4>; + clock-frequency = <58824000>; + /* Populated by the bootloader */ + /* current-speed = <0>; */ + }; + + ni_uart1: serial@80000010 { + device_type = "serial"; + compatible = "ni16550-fifo128", "ns16550a"; + status = "disabled"; + reg = <0x80000010 0x8>; + interrupts = <0 31 4>; + clock-frequency = <58824000>; + }; + + ni_uart2: serial@80000020 { + device_type = "serial"; + compatible = "ni16550-fifo128", "ns16550a"; + status = "disabled"; + reg = <0x80000020 0x8>; + interrupts = <0 32 4>; + clock-frequency = <58824000>; + }; + + ni_uart3: serial@80000030 { + device_type = "serial"; + compatible = "ni16550-fifo128", "ns16550a"; + status = "disabled"; + reg = <0x80000030 0x8>; + interrupts = <0 33 0>; + clock-frequency = <58824000>; + }; + + ni_uart4: serial@80000040 { + device_type = "serial"; + compatible = "ni16550-fifo128", "ns16550a"; + status = "disabled"; + reg = <0x80000040 0x8>; + interrupts = <0 34 0>; + clock-frequency = <58824000>; + }; + + ni_uart5: serial@80000050 { + device_type = "serial"; + compatible = "ni16550-fifo128", "ns16550a"; + status = "disabled"; + reg = <0x80000050 0x8>; + interrupts = <0 35 0>; + clock-frequency = <58824000>; + }; + + ni_uart6: serial@80000060 { + device_type = "serial"; + compatible = "ni16550-fifo128", "ns16550a"; + status = "disabled"; + reg = <0x80000060 0x8>; + interrupts = <0 36 0>; + clock-frequency = <58824000>; + }; + + ni_uart7: serial@80000070 { + device_type = "serial"; + compatible = "ni16550-fifo128", "ns16550a"; + status = "disabled"; + reg = <0x80000070 0x8>; + interrupts = <0 52 0>; + clock-frequency = <58824000>; + }; + + ni_uart8: serial@80000080 { + device_type = "serial"; + compatible = "ni16550-fifo128", "ns16550a"; + status = "disabled"; + reg = <0x80000080 0x8>; + interrupts = <0 53 0>; + clock-frequency = <58824000>; + }; + + can0: can@e0008000 { + compatible = "xlnx,zynq-can-1.00.a"; + status = "disabled"; + reg = <0xe0008000 0x1000>; + interrupts = <0 28 4>; + }; + + can1: can@e0009000 { + compatible = "xlnx,zynq-can-1.00.a"; + status = "disabled"; + reg = <0xe0009000 0x1000>; + interrupts = <0 51 4>; + }; + + fpgaperipheral@f8007000 { + compatible = "fpgaperipheral"; + reg = <0xf8007000 0x100>; + }; + + smcc@e000e000 { + #address-cells = <1>; + #size-cells = <1>; + arm,addr25 = <0x0>; + arm,nor-chip-sel0 = <0x0>; + arm,nor-chip-sel1 = <0x0>; + arm,sram-chip-sel0 = <0x0>; + arm,sram-chip-sel1 = <0x0>; + clock-names = "memclk", "aclk"; + clocks = <&clkc 11>, <&clkc 44>; + compatible = "arm,pl353-smc-r2p1"; + interrupts = <0 18 4>; + ranges ; + reg = <0xe000e000 0x1000>; + nand@e1000000 { + compatible = "arm,pl353-nand-r2p1"; + reg = <0xe1000000 0x1000000>; + bank-width = <1>; /* 8-bit width */ + xlnx,nand-width = <0x8>; + + /* SLCR SMC_CLK_CTRL value, 83MHz clock, 12ns cycle time */ + /* in cycles */ + xlnx,onfi-mode0 = <0x0001021 4 3 2 7 4 10 10>; + + /* SLCR SMC_CLK_CTRL value, 166MHz clock, 6ns cycle time */ + /* in cycles */ + xlnx,onfi-mode1 = <0x0000821 4 2 2 7 4 10 10>; + xlnx,onfi-mode2 = <0x0000821 4 2 2 5 3 8 7>; + xlnx,onfi-mode3 = <0x0000821 4 2 2 5 2 7 6>; + xlnx,onfi-mode4 = <0x0000821 4 2 2 4 2 6 5>; + xlnx,onfi-mode5 = <0x0000821 4 2 2 3 2 5 4>; + + #address-cells = <1>; + #size-cells = <1>; + }; + }; + + usb0: usb@e0002000 { + compatible = "xlnx,zynq-usb-1.00.a"; + status = "disabled"; + reg = <0xe0002000 0x1000>; + interrupts = <0 21 4>; + clocks = <&clkc 28>; + phy_type = "ulpi"; + }; + + usb1: usb@e0003000 { + compatible = "xlnx,zynq-usb-1.00.a"; + status = "disabled"; + reg = <0xe0003000 0x1000>; + interrupts = <0 44 4>; + clocks = <&clkc 29>; + phy_type = "ulpi"; + }; + + gpio: gpio@e000a000 { + compatible = "xlnx,zynq-gpio-1.0"; + reg = <0xe000a000 0x1000>; + #interrupt-cells = <0x2>; + interrupt-controller; + interrupts = <0 20 4>; + clocks = <&clkc 42>; + #gpio-cells = <2>; + gpio-controller; + }; + + i2c0: i2c@e0004000 { + compatible = "cdns,i2c-r1p10"; + reg = <0xE0004000 0x1000>; + interrupts = <0 25 4>; + bus-id = <0>; + clocks = <&clkc 38>; + clock-frequency = <400000>; + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + nicpld@40 { + compatible = "ni,cpld"; + reg = <0x40>; + }; + + ds3231_rtc@68 { + compatible = "ds3232"; + status = "disabled"; + reg = <0x68>; + }; + }; + + i2c1: i2c@e0005000 { + compatible = "cdns,i2c-r1p10"; + status = "disabled"; + reg = <0xe0005000 0x1000>; + interrupts = <0 48 4>; + bus-id = <1>; + clocks = <&clkc 39>; + clock-frequency = <400000>; + #address-cells = <1>; + #size-cells = <0>; + } ; + + i2c2: i2c@81000000 { + compatible = "xlnx,xps-iic-2.00.a"; + status = "disabled"; + reg = <0x81000000 0x1000>; + interrupts = <0 33 4>; + bus-id = <2>; + #address-cells = <1>; + #size-cells = <0>; + }; + + spi0: spi@e0006000 { + compatible = "cdns,spi-r1p6"; + status = "disabled"; + reg = <0xe0006000 0x1000>; + interrupts = <0 26 4>; + clock-names = "ref_clk", "pclk"; + clocks = <&clkc 25>, <&clkc 34>; + #address-cells = <1>; + #size-cells = <0>; + }; + + spi1: spi@e0007000 { + compatible = "cdns,spi-r1p6"; + status = "disabled"; + reg = <0xe0007000 0x1000>; + interrupts = <0 49 4>; + clock-names = "ref_clk", "pclk"; + clocks = <&clkc 26>, <&clkc 35>; + #address-cells = <1>; + #size-cells = <0>; + }; + }; +}; From 232695c307664650bf74d4b934d2c2a01ee76f56 Mon Sep 17 00:00:00 2001 From: Nathan Sullivan Date: Wed, 19 Aug 2015 18:00:16 -0500 Subject: [PATCH 069/100] devicetree: Update NI device trees for chipidea The chipidea USB controller driver requires a phy in the tree, so add one for all NI Zynq devices. Remove USB items from the ni-zynq tree include since they are now in zynq-7000.dtsi. Signed-off-by: Nathan Sullivan Acked-by: Josh Cartwright Acked-by: Jaeden Amero Natinst-ReviewBoard-ID: 108233 (cherry picked from commit 24943ed08d5d558409a0c1856793a5d22a2a0367) Signed-off-by: deooi --- arch/arm/boot/dts/ni-zynq.dtsi | 36 +++++++++++++++++----------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/arch/arm/boot/dts/ni-zynq.dtsi b/arch/arm/boot/dts/ni-zynq.dtsi index 3cdbf768a0032..5b347e6814348 100644 --- a/arch/arm/boot/dts/ni-zynq.dtsi +++ b/arch/arm/boot/dts/ni-zynq.dtsi @@ -11,6 +11,16 @@ }; chosen { }; + usb_phy0: phy0 { + compatible = "usb-nop-xceiv"; + #phy-cells = <0>; + }; + + usb_phy1: phy1 { + compatible = "usb-nop-xceiv"; + #phy-cells = <0>; + }; + cpus { #address-cells = <1>; #size-cells = <0>; @@ -170,24 +180,6 @@ }; }; - usb0: usb@e0002000 { - compatible = "xlnx,zynq-usb-1.00.a"; - status = "disabled"; - reg = <0xe0002000 0x1000>; - interrupts = <0 21 4>; - clocks = <&clkc 28>; - phy_type = "ulpi"; - }; - - usb1: usb@e0003000 { - compatible = "xlnx,zynq-usb-1.00.a"; - status = "disabled"; - reg = <0xe0003000 0x1000>; - interrupts = <0 44 4>; - clocks = <&clkc 29>; - phy_type = "ulpi"; - }; - gpio: gpio@e000a000 { compatible = "xlnx,zynq-gpio-1.0"; reg = <0xe000a000 0x1000>; @@ -265,5 +257,13 @@ #address-cells = <1>; #size-cells = <0>; }; + + usb0: usb@e0002000 { + usb-phy = <&usb_phy0>; + }; + + usb1: usb@e0003000 { + usb-phy = <&usb_phy1>; + }; }; }; From 11e9b2aba95601df496c02ba537906aeda955134 Mon Sep 17 00:00:00 2001 From: Nathan Sullivan Date: Mon, 28 Sep 2015 12:53:35 -0500 Subject: [PATCH 070/100] nizynq: Enable pl310 prefetch Signed-off-by: Nathan Sullivan Acked-by: Josh Cartwright Acked-by: Jaeden Amero Natinst-ReviewBoard-ID: 108233 (cherry picked from commit fe67634bbb41fa0be2c2a1fea9046bb1c5da1546) Signed-off-by: deooi --- arch/arm/boot/dts/ni-zynq.dtsi | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/arm/boot/dts/ni-zynq.dtsi b/arch/arm/boot/dts/ni-zynq.dtsi index 5b347e6814348..8f6b06dc748a9 100644 --- a/arch/arm/boot/dts/ni-zynq.dtsi +++ b/arch/arm/boot/dts/ni-zynq.dtsi @@ -266,4 +266,10 @@ usb-phy = <&usb_phy1>; }; }; + +}; + +&L2 { + prefetch-data = <1>; + prefetch-instr = <1>; }; From 3b3e9ab4fbf8b4a2d44a9046e4da5677e8340602 Mon Sep 17 00:00:00 2001 From: Brad Mouring Date: Mon, 22 Feb 2016 15:40:35 -0600 Subject: [PATCH 071/100] ni-zynq.dtsi: Disable PL310 power options Since NI controllers care more about determinism than power savings, disable PM options that hinder the former at the expense of the latter. Signed-off-by: Brad Mouring Acked-by: Josh Cartwright Natinst-ReviewBoard-ID: 127729 Natinst-CAR-ID: 568817 (cherry picked from commit 8400eae10d4113f4494ab9d61fc45763a7cfb79d) Signed-off-by: deooi --- arch/arm/boot/dts/ni-zynq.dtsi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/boot/dts/ni-zynq.dtsi b/arch/arm/boot/dts/ni-zynq.dtsi index 8f6b06dc748a9..4324e67f461a3 100644 --- a/arch/arm/boot/dts/ni-zynq.dtsi +++ b/arch/arm/boot/dts/ni-zynq.dtsi @@ -272,4 +272,6 @@ &L2 { prefetch-data = <1>; prefetch-instr = <1>; + arm,dynamic-clock-gating = <0>; + arm,standby-mode = <0>; }; From bb101d70924b4018123900ca9f93e65df066d57d Mon Sep 17 00:00:00 2001 From: Brandon Streiff Date: Thu, 5 May 2016 17:30:09 -0500 Subject: [PATCH 072/100] ni-bluefin: add device tree Device tree for Bluefin devices as of Rev A. Signed-off-by: Brandon Streiff Acked-by: Nathan Sullivan Natinst-ReviewBoard-ID: 158229 (cherry picked from commit c0feb6bc830a506728bd3f42050d1dd71d3f383a) Signed-off-by: deooi --- arch/arm/boot/dts/ni-bluefin.dts | 93 ++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 arch/arm/boot/dts/ni-bluefin.dts diff --git a/arch/arm/boot/dts/ni-bluefin.dts b/arch/arm/boot/dts/ni-bluefin.dts new file mode 100644 index 0000000000000..fa569f8ab5521 --- /dev/null +++ b/arch/arm/boot/dts/ni-bluefin.dts @@ -0,0 +1,93 @@ +/dts-v1/; +/include/ "ni-zynq.dtsi" + +/* NIDEVCODE 78C7 */ +/* NIDEVCODE 78B9 */ + +/ { + model = "NI Bluefin"; + compatible = "ni,zynq", "xlnx,zynq-7000"; + + amba@0 { + i2c0: i2c@e0004000 { + /* Override ni-zynq.dtsi; we do not have a CPLD at 0x40. */ + nicpld@40 { + status = "disabled"; + }; + + tmp451@4C { + compatible = "ti,tmp451"; + reg = <0x4C>; + vcc-supply = <®ulator_vccpint>; + }; + }; + }; + + leds { + compatible = "gpio-leds"; + + /* LED_STATUSy on GPIO46 */ + status { + label = "nilrt:status:yellow"; + gpios = <&gpio 46 0>; + default-state = "on"; + }; + + /* LED_ACTIVEg on GPIO47 */ + active { + label = "nilrt:active:green"; + gpios = <&gpio 47 0>; + default-state = "off"; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + + /* Reset switch is on GPIO48 */ + reset_sw@0 { + label = "reset_sw"; + gpios = <&gpio 48 1 /* GPIO_ACTIVE_LOW */>; + linux,code = <408>; /* KEY_RESTART */ + gpio-key,wakeup; + }; + }; + + gpio_restart { + compatible = "gpio-restart"; + + /* ~PS_FORCE_RESET is on GPIO44 */ + gpios = <&gpio 44 1 /* GPIO_ACTIVE_LOW */>; + priority = <200>; + }; +}; + +&gem0 { + status = "okay"; + emio-speed-gpios = <0>, + <&gpio 54 0>; + + #address-cells = <0x1>; + #size-cells = <0x0>; + + fixed-link { + speed = <1000>; + full-duplex; + }; +}; + +&uart1 { + status = "okay"; +}; + +&usb0 { + status = "okay"; + dr_mode = "host"; +}; + +&watchdog0 { + status = "okay"; + reset-on-timeout; +}; From 6343d78ab82c08d55d0daa1af1ff52439cb6437d Mon Sep 17 00:00:00 2001 From: Brandon Streiff Date: Thu, 12 Jan 2017 14:10:50 -0600 Subject: [PATCH 073/100] ni-bluefin: set phy address for fixed-link This keeps us for having to scan for it. Signed-off-by: Brandon Streiff Natinst-ReviewBoard-ID: 168093 (cherry picked from commit 56f25b5cdfcfc533e8786bc788707becddda79c2) Signed-off-by: deooi --- arch/arm/boot/dts/ni-bluefin.dts | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/boot/dts/ni-bluefin.dts b/arch/arm/boot/dts/ni-bluefin.dts index fa569f8ab5521..19f9ef5ab6614 100644 --- a/arch/arm/boot/dts/ni-bluefin.dts +++ b/arch/arm/boot/dts/ni-bluefin.dts @@ -75,6 +75,7 @@ fixed-link { speed = <1000>; full-duplex; + reg = <0>; }; }; From 9cf4ef4a010146bb058a103cce97909a0f5a3b69 Mon Sep 17 00:00:00 2001 From: deooi Date: Fri, 17 Jan 2025 15:40:47 +0800 Subject: [PATCH 074/100] devicetree: Move xilinx device trees to the xilinx directory This change is needed to keep up with the latest file directory. Signed-off-by: deooi --- arch/arm/boot/dts/{ => xilinx}/ni-793x.dts | 0 arch/arm/boot/dts/{ => xilinx}/ni-bluefin.dts | 0 arch/arm/boot/dts/{ => xilinx}/ni-dosequis.dts | 0 arch/arm/boot/dts/{ => xilinx}/ni-myrio.dts | 0 arch/arm/boot/dts/{ => xilinx}/ni-roborio.dts | 0 arch/arm/boot/dts/{ => xilinx}/ni-sbrio-9607.dts | 0 arch/arm/boot/dts/{ => xilinx}/ni-sbrio-9627.dts | 0 arch/arm/boot/dts/{ => xilinx}/ni-sbrio-9637.dts | 0 arch/arm/boot/dts/{ => xilinx}/ni-solbetter.dts | 0 arch/arm/boot/dts/{ => xilinx}/ni-solenetexp.dts | 0 arch/arm/boot/dts/{ => xilinx}/ni-solgood.dts | 0 arch/arm/boot/dts/{ => xilinx}/ni-tecate.dts | 0 arch/arm/boot/dts/{ => xilinx}/ni-zynq.dtsi | 0 13 files changed, 0 insertions(+), 0 deletions(-) rename arch/arm/boot/dts/{ => xilinx}/ni-793x.dts (100%) rename arch/arm/boot/dts/{ => xilinx}/ni-bluefin.dts (100%) rename arch/arm/boot/dts/{ => xilinx}/ni-dosequis.dts (100%) rename arch/arm/boot/dts/{ => xilinx}/ni-myrio.dts (100%) rename arch/arm/boot/dts/{ => xilinx}/ni-roborio.dts (100%) rename arch/arm/boot/dts/{ => xilinx}/ni-sbrio-9607.dts (100%) rename arch/arm/boot/dts/{ => xilinx}/ni-sbrio-9627.dts (100%) rename arch/arm/boot/dts/{ => xilinx}/ni-sbrio-9637.dts (100%) rename arch/arm/boot/dts/{ => xilinx}/ni-solbetter.dts (100%) rename arch/arm/boot/dts/{ => xilinx}/ni-solenetexp.dts (100%) rename arch/arm/boot/dts/{ => xilinx}/ni-solgood.dts (100%) rename arch/arm/boot/dts/{ => xilinx}/ni-tecate.dts (100%) rename arch/arm/boot/dts/{ => xilinx}/ni-zynq.dtsi (100%) diff --git a/arch/arm/boot/dts/ni-793x.dts b/arch/arm/boot/dts/xilinx/ni-793x.dts similarity index 100% rename from arch/arm/boot/dts/ni-793x.dts rename to arch/arm/boot/dts/xilinx/ni-793x.dts diff --git a/arch/arm/boot/dts/ni-bluefin.dts b/arch/arm/boot/dts/xilinx/ni-bluefin.dts similarity index 100% rename from arch/arm/boot/dts/ni-bluefin.dts rename to arch/arm/boot/dts/xilinx/ni-bluefin.dts diff --git a/arch/arm/boot/dts/ni-dosequis.dts b/arch/arm/boot/dts/xilinx/ni-dosequis.dts similarity index 100% rename from arch/arm/boot/dts/ni-dosequis.dts rename to arch/arm/boot/dts/xilinx/ni-dosequis.dts diff --git a/arch/arm/boot/dts/ni-myrio.dts b/arch/arm/boot/dts/xilinx/ni-myrio.dts similarity index 100% rename from arch/arm/boot/dts/ni-myrio.dts rename to arch/arm/boot/dts/xilinx/ni-myrio.dts diff --git a/arch/arm/boot/dts/ni-roborio.dts b/arch/arm/boot/dts/xilinx/ni-roborio.dts similarity index 100% rename from arch/arm/boot/dts/ni-roborio.dts rename to arch/arm/boot/dts/xilinx/ni-roborio.dts diff --git a/arch/arm/boot/dts/ni-sbrio-9607.dts b/arch/arm/boot/dts/xilinx/ni-sbrio-9607.dts similarity index 100% rename from arch/arm/boot/dts/ni-sbrio-9607.dts rename to arch/arm/boot/dts/xilinx/ni-sbrio-9607.dts diff --git a/arch/arm/boot/dts/ni-sbrio-9627.dts b/arch/arm/boot/dts/xilinx/ni-sbrio-9627.dts similarity index 100% rename from arch/arm/boot/dts/ni-sbrio-9627.dts rename to arch/arm/boot/dts/xilinx/ni-sbrio-9627.dts diff --git a/arch/arm/boot/dts/ni-sbrio-9637.dts b/arch/arm/boot/dts/xilinx/ni-sbrio-9637.dts similarity index 100% rename from arch/arm/boot/dts/ni-sbrio-9637.dts rename to arch/arm/boot/dts/xilinx/ni-sbrio-9637.dts diff --git a/arch/arm/boot/dts/ni-solbetter.dts b/arch/arm/boot/dts/xilinx/ni-solbetter.dts similarity index 100% rename from arch/arm/boot/dts/ni-solbetter.dts rename to arch/arm/boot/dts/xilinx/ni-solbetter.dts diff --git a/arch/arm/boot/dts/ni-solenetexp.dts b/arch/arm/boot/dts/xilinx/ni-solenetexp.dts similarity index 100% rename from arch/arm/boot/dts/ni-solenetexp.dts rename to arch/arm/boot/dts/xilinx/ni-solenetexp.dts diff --git a/arch/arm/boot/dts/ni-solgood.dts b/arch/arm/boot/dts/xilinx/ni-solgood.dts similarity index 100% rename from arch/arm/boot/dts/ni-solgood.dts rename to arch/arm/boot/dts/xilinx/ni-solgood.dts diff --git a/arch/arm/boot/dts/ni-tecate.dts b/arch/arm/boot/dts/xilinx/ni-tecate.dts similarity index 100% rename from arch/arm/boot/dts/ni-tecate.dts rename to arch/arm/boot/dts/xilinx/ni-tecate.dts diff --git a/arch/arm/boot/dts/ni-zynq.dtsi b/arch/arm/boot/dts/xilinx/ni-zynq.dtsi similarity index 100% rename from arch/arm/boot/dts/ni-zynq.dtsi rename to arch/arm/boot/dts/xilinx/ni-zynq.dtsi From 74561fd411d37ddbb83cf7bd8815eb74d26be593 Mon Sep 17 00:00:00 2001 From: Hatsy Rei Date: Tue, 4 Feb 2025 21:12:33 -0800 Subject: [PATCH 075/100] ARM: dts: ni-zynq: Drop obsolete bindings Drop device tree bindings which are already declared in zynq-7000.dtsi. This includes CPU, CAN, FPGA, PL353 SMC, NAND, GPIO, I2C and SPI bindings. 'fpgaperipheral' node, now 'devcfg' in zynq-7000.dtsi describes the Xilinx Zynq FPGA Manager. Signed-off-by: Hatsy Rei --- arch/arm/boot/dts/xilinx/ni-zynq.dtsi | 133 +------------------------- 1 file changed, 1 insertion(+), 132 deletions(-) diff --git a/arch/arm/boot/dts/xilinx/ni-zynq.dtsi b/arch/arm/boot/dts/xilinx/ni-zynq.dtsi index 4324e67f461a3..295d1bf31f798 100644 --- a/arch/arm/boot/dts/xilinx/ni-zynq.dtsi +++ b/arch/arm/boot/dts/xilinx/ni-zynq.dtsi @@ -21,26 +21,7 @@ #phy-cells = <0>; }; - cpus { - #address-cells = <1>; - #size-cells = <0>; - - cpu@0 { - compatible = "arm,cortex-a9"; - device_type = "cpu"; - reg = <0>; - clocks = <&clkc 3>; - }; - - cpu@1 { - compatible = "arm,cortex-a9"; - device_type = "cpu"; - reg = <1>; - clocks = <&clkc 3>; - }; - }; - - amba@0 { + amba: axi { ni_uart0: serial@80000000 { device_type = "serial"; compatible = "ni16550-fifo128", "ns16550a"; @@ -124,84 +105,7 @@ clock-frequency = <58824000>; }; - can0: can@e0008000 { - compatible = "xlnx,zynq-can-1.00.a"; - status = "disabled"; - reg = <0xe0008000 0x1000>; - interrupts = <0 28 4>; - }; - - can1: can@e0009000 { - compatible = "xlnx,zynq-can-1.00.a"; - status = "disabled"; - reg = <0xe0009000 0x1000>; - interrupts = <0 51 4>; - }; - - fpgaperipheral@f8007000 { - compatible = "fpgaperipheral"; - reg = <0xf8007000 0x100>; - }; - - smcc@e000e000 { - #address-cells = <1>; - #size-cells = <1>; - arm,addr25 = <0x0>; - arm,nor-chip-sel0 = <0x0>; - arm,nor-chip-sel1 = <0x0>; - arm,sram-chip-sel0 = <0x0>; - arm,sram-chip-sel1 = <0x0>; - clock-names = "memclk", "aclk"; - clocks = <&clkc 11>, <&clkc 44>; - compatible = "arm,pl353-smc-r2p1"; - interrupts = <0 18 4>; - ranges ; - reg = <0xe000e000 0x1000>; - nand@e1000000 { - compatible = "arm,pl353-nand-r2p1"; - reg = <0xe1000000 0x1000000>; - bank-width = <1>; /* 8-bit width */ - xlnx,nand-width = <0x8>; - - /* SLCR SMC_CLK_CTRL value, 83MHz clock, 12ns cycle time */ - /* in cycles */ - xlnx,onfi-mode0 = <0x0001021 4 3 2 7 4 10 10>; - - /* SLCR SMC_CLK_CTRL value, 166MHz clock, 6ns cycle time */ - /* in cycles */ - xlnx,onfi-mode1 = <0x0000821 4 2 2 7 4 10 10>; - xlnx,onfi-mode2 = <0x0000821 4 2 2 5 3 8 7>; - xlnx,onfi-mode3 = <0x0000821 4 2 2 5 2 7 6>; - xlnx,onfi-mode4 = <0x0000821 4 2 2 4 2 6 5>; - xlnx,onfi-mode5 = <0x0000821 4 2 2 3 2 5 4>; - - #address-cells = <1>; - #size-cells = <1>; - }; - }; - - gpio: gpio@e000a000 { - compatible = "xlnx,zynq-gpio-1.0"; - reg = <0xe000a000 0x1000>; - #interrupt-cells = <0x2>; - interrupt-controller; - interrupts = <0 20 4>; - clocks = <&clkc 42>; - #gpio-cells = <2>; - gpio-controller; - }; - i2c0: i2c@e0004000 { - compatible = "cdns,i2c-r1p10"; - reg = <0xE0004000 0x1000>; - interrupts = <0 25 4>; - bus-id = <0>; - clocks = <&clkc 38>; - clock-frequency = <400000>; - #address-cells = <1>; - #size-cells = <0>; - status = "okay"; - nicpld@40 { compatible = "ni,cpld"; reg = <0x40>; @@ -214,18 +118,6 @@ }; }; - i2c1: i2c@e0005000 { - compatible = "cdns,i2c-r1p10"; - status = "disabled"; - reg = <0xe0005000 0x1000>; - interrupts = <0 48 4>; - bus-id = <1>; - clocks = <&clkc 39>; - clock-frequency = <400000>; - #address-cells = <1>; - #size-cells = <0>; - } ; - i2c2: i2c@81000000 { compatible = "xlnx,xps-iic-2.00.a"; status = "disabled"; @@ -236,28 +128,6 @@ #size-cells = <0>; }; - spi0: spi@e0006000 { - compatible = "cdns,spi-r1p6"; - status = "disabled"; - reg = <0xe0006000 0x1000>; - interrupts = <0 26 4>; - clock-names = "ref_clk", "pclk"; - clocks = <&clkc 25>, <&clkc 34>; - #address-cells = <1>; - #size-cells = <0>; - }; - - spi1: spi@e0007000 { - compatible = "cdns,spi-r1p6"; - status = "disabled"; - reg = <0xe0007000 0x1000>; - interrupts = <0 49 4>; - clock-names = "ref_clk", "pclk"; - clocks = <&clkc 26>, <&clkc 35>; - #address-cells = <1>; - #size-cells = <0>; - }; - usb0: usb@e0002000 { usb-phy = <&usb_phy0>; }; @@ -266,7 +136,6 @@ usb-phy = <&usb_phy1>; }; }; - }; &L2 { From bd1169de6fe946f15bc873cdbcd59ae91ecfaa1f Mon Sep 17 00:00:00 2001 From: Hatsy Rei Date: Tue, 4 Feb 2025 21:30:42 -0800 Subject: [PATCH 076/100] ARM: dts: ni-zynq: Enable zynq-7000 SMC, NAND nodes Enable PL353 SMC and NAND device tree nodes declared in zynq-7000.dtsi. Indicate via 'nand-on-flash-bbt' property that bad block table is stored on the nand flash, and 'nand-ecc-mode' property that on-die ECC is used. Signed-off-by: Hatsy Rei --- arch/arm/boot/dts/xilinx/ni-zynq.dtsi | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/arch/arm/boot/dts/xilinx/ni-zynq.dtsi b/arch/arm/boot/dts/xilinx/ni-zynq.dtsi index 295d1bf31f798..9cf6ccc57dd37 100644 --- a/arch/arm/boot/dts/xilinx/ni-zynq.dtsi +++ b/arch/arm/boot/dts/xilinx/ni-zynq.dtsi @@ -138,6 +138,20 @@ }; }; +&smcc { + status = "okay"; +}; + +&nfc0 { + status = "okay"; + + nand@0 { + reg = <0>; + nand-on-flash-bbt; + nand-ecc-mode = "on-die"; + }; +}; + &L2 { prefetch-data = <1>; prefetch-instr = <1>; From 8ebd27f75a524c07d619967a25bcadee80d81918 Mon Sep 17 00:00:00 2001 From: Hatsy Rei Date: Tue, 4 Feb 2025 21:54:37 -0800 Subject: [PATCH 077/100] ARM: dts: ni-zynq: Extend I2C, USB nodes via phandle Avoid redeclaring these nodes and just extend them via phandles. Signed-off-by: Hatsy Rei --- arch/arm/boot/dts/xilinx/ni-zynq.dtsi | 38 +++++++++++++-------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/arch/arm/boot/dts/xilinx/ni-zynq.dtsi b/arch/arm/boot/dts/xilinx/ni-zynq.dtsi index 9cf6ccc57dd37..302a81ef1c2c0 100644 --- a/arch/arm/boot/dts/xilinx/ni-zynq.dtsi +++ b/arch/arm/boot/dts/xilinx/ni-zynq.dtsi @@ -105,19 +105,6 @@ clock-frequency = <58824000>; }; - i2c0: i2c@e0004000 { - nicpld@40 { - compatible = "ni,cpld"; - reg = <0x40>; - }; - - ds3231_rtc@68 { - compatible = "ds3232"; - status = "disabled"; - reg = <0x68>; - }; - }; - i2c2: i2c@81000000 { compatible = "xlnx,xps-iic-2.00.a"; status = "disabled"; @@ -127,17 +114,30 @@ #address-cells = <1>; #size-cells = <0>; }; + }; +}; - usb0: usb@e0002000 { - usb-phy = <&usb_phy0>; - }; +&i2c0 { + nicpld@40 { + compatible = "ni,cpld"; + reg = <0x40>; + }; - usb1: usb@e0003000 { - usb-phy = <&usb_phy1>; - }; + ds3231_rtc@68 { + compatible = "ds3232"; + status = "disabled"; + reg = <0x68>; }; }; +&usb0 { + usb-phy = <&usb_phy0>; +}; + +&usb1 { + usb-phy = <&usb_phy1>; +}; + &smcc { status = "okay"; }; From a280627db0285962f24473113e0a2dbe8b9de318 Mon Sep 17 00:00:00 2001 From: Hatsy Rei Date: Tue, 4 Feb 2025 22:20:53 -0800 Subject: [PATCH 078/100] ARM: dts: ni-bluefin: Update AMBA and GPIO bindings zynq-7000.dtsi contains updated AMBA and GPIO device tree node phandles. Adopt these changes by referencing i2c0 phandle instead of amba node for overriding i2c bindings, and refer to gpio0 phandle instead of gpio. Signed-off-by: Hatsy Rei --- arch/arm/boot/dts/xilinx/ni-bluefin.dts | 38 ++++++++++++------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/arch/arm/boot/dts/xilinx/ni-bluefin.dts b/arch/arm/boot/dts/xilinx/ni-bluefin.dts index 19f9ef5ab6614..05d4b0ef837f9 100644 --- a/arch/arm/boot/dts/xilinx/ni-bluefin.dts +++ b/arch/arm/boot/dts/xilinx/ni-bluefin.dts @@ -8,35 +8,20 @@ model = "NI Bluefin"; compatible = "ni,zynq", "xlnx,zynq-7000"; - amba@0 { - i2c0: i2c@e0004000 { - /* Override ni-zynq.dtsi; we do not have a CPLD at 0x40. */ - nicpld@40 { - status = "disabled"; - }; - - tmp451@4C { - compatible = "ti,tmp451"; - reg = <0x4C>; - vcc-supply = <®ulator_vccpint>; - }; - }; - }; - leds { compatible = "gpio-leds"; /* LED_STATUSy on GPIO46 */ status { label = "nilrt:status:yellow"; - gpios = <&gpio 46 0>; + gpios = <&gpio0 46 0>; default-state = "on"; }; /* LED_ACTIVEg on GPIO47 */ active { label = "nilrt:active:green"; - gpios = <&gpio 47 0>; + gpios = <&gpio0 47 0>; default-state = "off"; }; }; @@ -49,7 +34,7 @@ /* Reset switch is on GPIO48 */ reset_sw@0 { label = "reset_sw"; - gpios = <&gpio 48 1 /* GPIO_ACTIVE_LOW */>; + gpios = <&gpio0 48 1 /* GPIO_ACTIVE_LOW */>; linux,code = <408>; /* KEY_RESTART */ gpio-key,wakeup; }; @@ -59,15 +44,28 @@ compatible = "gpio-restart"; /* ~PS_FORCE_RESET is on GPIO44 */ - gpios = <&gpio 44 1 /* GPIO_ACTIVE_LOW */>; + gpios = <&gpio0 44 1 /* GPIO_ACTIVE_LOW */>; priority = <200>; }; }; +&i2c0 { + /* Override ni-zynq.dtsi; we do not have a CPLD at 0x40. */ + nicpld@40 { + status = "disabled"; + }; + + tmp451@4C { + compatible = "ti,tmp451"; + reg = <0x4C>; + vcc-supply = <®ulator_vccpint>; + }; +}; + &gem0 { status = "okay"; emio-speed-gpios = <0>, - <&gpio 54 0>; + <&gpio0 54 0>; #address-cells = <0x1>; #size-cells = <0x0>; From d5d844e3aa3df1096fd58648ad9ef84a36ce27ba Mon Sep 17 00:00:00 2001 From: HatsyRei Date: Mon, 10 Feb 2025 20:20:08 +0800 Subject: [PATCH 079/100] ARM: dts: ni-zynq: Update NI 16550 bindings Update 'compatible' property to match what is expected by the latest NI 16550 UART Driver. Signed-off-by: HatsyRei --- arch/arm/boot/dts/xilinx/ni-zynq.dtsi | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/arch/arm/boot/dts/xilinx/ni-zynq.dtsi b/arch/arm/boot/dts/xilinx/ni-zynq.dtsi index 302a81ef1c2c0..086e17729433b 100644 --- a/arch/arm/boot/dts/xilinx/ni-zynq.dtsi +++ b/arch/arm/boot/dts/xilinx/ni-zynq.dtsi @@ -24,7 +24,7 @@ amba: axi { ni_uart0: serial@80000000 { device_type = "serial"; - compatible = "ni16550-fifo128", "ns16550a"; + compatible = "ni,ni16550"; status = "disabled"; reg = <0x80000000 0x8>; interrupts = <0 30 4>; @@ -35,7 +35,7 @@ ni_uart1: serial@80000010 { device_type = "serial"; - compatible = "ni16550-fifo128", "ns16550a"; + compatible = "ni,ni16550"; status = "disabled"; reg = <0x80000010 0x8>; interrupts = <0 31 4>; @@ -44,7 +44,7 @@ ni_uart2: serial@80000020 { device_type = "serial"; - compatible = "ni16550-fifo128", "ns16550a"; + compatible = "ni,ni16550"; status = "disabled"; reg = <0x80000020 0x8>; interrupts = <0 32 4>; @@ -53,7 +53,7 @@ ni_uart3: serial@80000030 { device_type = "serial"; - compatible = "ni16550-fifo128", "ns16550a"; + compatible = "ni,ni16550"; status = "disabled"; reg = <0x80000030 0x8>; interrupts = <0 33 0>; @@ -62,7 +62,7 @@ ni_uart4: serial@80000040 { device_type = "serial"; - compatible = "ni16550-fifo128", "ns16550a"; + compatible = "ni,ni16550"; status = "disabled"; reg = <0x80000040 0x8>; interrupts = <0 34 0>; @@ -71,7 +71,7 @@ ni_uart5: serial@80000050 { device_type = "serial"; - compatible = "ni16550-fifo128", "ns16550a"; + compatible = "ni,ni16550"; status = "disabled"; reg = <0x80000050 0x8>; interrupts = <0 35 0>; @@ -80,7 +80,7 @@ ni_uart6: serial@80000060 { device_type = "serial"; - compatible = "ni16550-fifo128", "ns16550a"; + compatible = "ni,ni16550"; status = "disabled"; reg = <0x80000060 0x8>; interrupts = <0 36 0>; @@ -89,7 +89,7 @@ ni_uart7: serial@80000070 { device_type = "serial"; - compatible = "ni16550-fifo128", "ns16550a"; + compatible = "ni,ni16550"; status = "disabled"; reg = <0x80000070 0x8>; interrupts = <0 52 0>; @@ -98,7 +98,7 @@ ni_uart8: serial@80000080 { device_type = "serial"; - compatible = "ni16550-fifo128", "ns16550a"; + compatible = "ni,ni16550"; status = "disabled"; reg = <0x80000080 0x8>; interrupts = <0 53 0>; From 70a8df7b8d0b32eee52b1d3eae81bcbd837929ab Mon Sep 17 00:00:00 2001 From: Brandon Streiff Date: Wed, 7 Nov 2018 15:55:22 -0600 Subject: [PATCH 080/100] ni-coralreef: add device tree Copied largely from ni-bluefin.dts, but with more DSA ports and USB gone. Updated port order such that "sw0" lines up with "Port 0" etc. Updated status LED to be a bicolour blue and yellow LED, not green. Signed-off-by: Brandon Streiff Acked-by: Kyle Roeschley Acked-by: Erik Hons Acked-by: Haris Okanovic Natinst-ReviewBoard-ID: 310589 (cherry picked from commit 3b0fa2ef78f243388422be91088b40aaf54737ab) Natinst-ReviewBoard-ID: 320599 (cherry picked from commit ff0acb430ba683dfc81e28671a936a80dbb10c3e) Natinst-ReviewBoard-ID: 325354 (cherry picked from commit 83855f3a30b90a5f7a1f2be025f447a24a32822f) Signed-off-by: deooi (cherry picked from commit dd4b3811951ae2816f374024f0ec33b9542c63f7) Signed-off-by: Gratian Crisan --- arch/arm/boot/dts/ni-coralreef.dts | 129 +++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 arch/arm/boot/dts/ni-coralreef.dts diff --git a/arch/arm/boot/dts/ni-coralreef.dts b/arch/arm/boot/dts/ni-coralreef.dts new file mode 100644 index 0000000000000..64ebf0175fd5b --- /dev/null +++ b/arch/arm/boot/dts/ni-coralreef.dts @@ -0,0 +1,129 @@ +/dts-v1/; +/include/ "ni-zynq.dtsi" + +/* NIDEVCODE 7A4B */ + +/ { + model = "NI Coral Reef"; + compatible = "ni,zynq", "xlnx,zynq-7000"; + + amba@0 { + i2c0: i2c@e0004000 { + /* Override ni-zynq.dtsi; we do not have a CPLD at 0x40. */ + nicpld@40 { + status = "disabled"; + }; + + tmp451@4C { + compatible = "ti,tmp451"; + reg = <0x4C>; + vcc-supply = <®ulator_vccpint>; + }; + }; + }; + + leds { + compatible = "gpio-leds"; + + /* LED_STATUSy on GPIO46 */ + status { + label = "nilrt:status:yellow"; + gpios = <&gpio 46 0>; + default-state = "on"; + }; + + /* LED_POWERb on GPIO47 */ + active { + label = "nilrt:status:blue"; + gpios = <&gpio 47 0>; + default-state = "off"; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + + /* Reset switch is on GPIO48 */ + reset_sw@0 { + label = "reset_sw"; + gpios = <&gpio 48 1 /* GPIO_ACTIVE_LOW */>; + linux,code = <408>; /* KEY_RESTART */ + gpio-key,wakeup; + }; + }; + + gpio_restart { + compatible = "gpio-restart"; + + /* ~PS_FORCE_RESET is on GPIO44 */ + gpios = <&gpio 44 1 /* GPIO_ACTIVE_LOW */>; + priority = <200>; + }; + + dsa@0 { + compatible = "marvell,dsa"; + #address-cells = <2>; + #size-cells = <0>; + + dsa,ethernet = <&gem0>; + dsa,mii-bus = <&gem0>; + + switch@0 { + #address-cells = <1>; + #size-cells = <0>; + /* MDIO addr 0x0 (single-chip addressing), switch 0 */ + reg = <0 0>; + + port@0 { + reg = <0x0>; + label = "cpu"; + }; + + port@1 { + reg = <0x1>; + label = "sw3"; + }; + + port@2 { + reg = <0x2>; + label = "sw2"; + }; + + port@3 { + reg = <0x3>; + label = "sw1"; + }; + + port@4 { + reg = <0x4>; + label = "sw0"; + }; + }; + }; +}; + +&gem0 { + status = "okay"; + emio-speed-gpios = <0>, + <&gpio 54 0>; + + #address-cells = <0x1>; + #size-cells = <0x0>; + + fixed-link { + speed = <1000>; + full-duplex; + reg = <0>; + }; +}; + +&uart1 { + status = "okay"; +}; + +&watchdog0 { + status = "okay"; + reset-on-timeout; +}; From 77d9a728d0b316c495a36230cfdd0f4cc7ad84a1 Mon Sep 17 00:00:00 2001 From: deooi Date: Thu, 13 Mar 2025 15:25:28 +0800 Subject: [PATCH 081/100] ni-coralreef: Move device tree to xilinx folder Move ni-coralreef.dts to the xilinx folder together with the other xilinx devices. Signed-off-by: deooi (cherry picked from commit 4822c16b7f7337f07eac610e165ec1a8c2eff076) Signed-off-by: Gratian Crisan --- arch/arm/boot/dts/{ => xilinx}/ni-coralreef.dts | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename arch/arm/boot/dts/{ => xilinx}/ni-coralreef.dts (100%) diff --git a/arch/arm/boot/dts/ni-coralreef.dts b/arch/arm/boot/dts/xilinx/ni-coralreef.dts similarity index 100% rename from arch/arm/boot/dts/ni-coralreef.dts rename to arch/arm/boot/dts/xilinx/ni-coralreef.dts From 6e377876fbd8edcd4bbcfd6a42a4ab4523e4aa76 Mon Sep 17 00:00:00 2001 From: deooi Date: Thu, 13 Mar 2025 16:16:14 +0800 Subject: [PATCH 082/100] ARM: dts: ni-coralreef: Update AMBA and GPIO bindings zynq-7000.dtsi contains updated AMBA and GPIO device tree node phandles. Adopt these changes by referencing i2c0 phandle instead of amba node for overriding i2c bindings, and refer to gpio0 phandle instead of gpio. Signed-off-by: deooi (cherry picked from commit 1e2fe29ac1aca837cd239d6ccbd5dda76d30f5ed) Signed-off-by: Gratian Crisan --- arch/arm/boot/dts/xilinx/ni-coralreef.dts | 38 +++++++++++------------ 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/arch/arm/boot/dts/xilinx/ni-coralreef.dts b/arch/arm/boot/dts/xilinx/ni-coralreef.dts index 64ebf0175fd5b..e38a307f11d1c 100644 --- a/arch/arm/boot/dts/xilinx/ni-coralreef.dts +++ b/arch/arm/boot/dts/xilinx/ni-coralreef.dts @@ -7,35 +7,20 @@ model = "NI Coral Reef"; compatible = "ni,zynq", "xlnx,zynq-7000"; - amba@0 { - i2c0: i2c@e0004000 { - /* Override ni-zynq.dtsi; we do not have a CPLD at 0x40. */ - nicpld@40 { - status = "disabled"; - }; - - tmp451@4C { - compatible = "ti,tmp451"; - reg = <0x4C>; - vcc-supply = <®ulator_vccpint>; - }; - }; - }; - leds { compatible = "gpio-leds"; /* LED_STATUSy on GPIO46 */ status { label = "nilrt:status:yellow"; - gpios = <&gpio 46 0>; + gpios = <&gpio0 46 0>; default-state = "on"; }; /* LED_POWERb on GPIO47 */ active { label = "nilrt:status:blue"; - gpios = <&gpio 47 0>; + gpios = <&gpio0 47 0>; default-state = "off"; }; }; @@ -48,7 +33,7 @@ /* Reset switch is on GPIO48 */ reset_sw@0 { label = "reset_sw"; - gpios = <&gpio 48 1 /* GPIO_ACTIVE_LOW */>; + gpios = <&gpio0 48 1 /* GPIO_ACTIVE_LOW */>; linux,code = <408>; /* KEY_RESTART */ gpio-key,wakeup; }; @@ -58,7 +43,7 @@ compatible = "gpio-restart"; /* ~PS_FORCE_RESET is on GPIO44 */ - gpios = <&gpio 44 1 /* GPIO_ACTIVE_LOW */>; + gpios = <&gpio0 44 1 /* GPIO_ACTIVE_LOW */>; priority = <200>; }; @@ -104,10 +89,23 @@ }; }; +&i2c0 { + /* Override ni-zynq.dtsi; we do not have a CPLD at 0x40. */ + nicpld@40 { + status = "disabled"; + }; + + tmp451@4C { + compatible = "ti,tmp451"; + reg = <0x4C>; + vcc-supply = <®ulator_vccpint>; + }; +}; + &gem0 { status = "okay"; emio-speed-gpios = <0>, - <&gpio 54 0>; + <&gpio0 54 0>; #address-cells = <0x1>; #size-cells = <0x0>; From fba1fbba2519071bccdecea80f30195652c9814e Mon Sep 17 00:00:00 2001 From: HatsyRei Date: Wed, 19 Mar 2025 10:43:40 +0800 Subject: [PATCH 083/100] ARM: dts: ni-bluefin: Add Marvell ethernet switch bindings Add appropriate device tree bindings to enable probe and configuration of Marvell 88E6341 'Topaz' ethernet switch on Bluefin hardware. Signed-off-by: HatsyRei (cherry picked from commit 26ab2af9040268a54f41ed4bacd8b36a2488c260) Signed-off-by: Gratian Crisan --- arch/arm/boot/dts/xilinx/ni-bluefin.dts | 52 +++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 3 deletions(-) diff --git a/arch/arm/boot/dts/xilinx/ni-bluefin.dts b/arch/arm/boot/dts/xilinx/ni-bluefin.dts index 05d4b0ef837f9..5a8e835ea2f71 100644 --- a/arch/arm/boot/dts/xilinx/ni-bluefin.dts +++ b/arch/arm/boot/dts/xilinx/ni-bluefin.dts @@ -64,9 +64,6 @@ &gem0 { status = "okay"; - emio-speed-gpios = <0>, - <&gpio0 54 0>; - #address-cells = <0x1>; #size-cells = <0x0>; @@ -75,6 +72,55 @@ full-duplex; reg = <0>; }; + + mdio0: mdio { + status = "okay"; + }; +}; + +&mdio0 { + #address-cells = <1>; + #size-cells = <0>; + + switch: switch@0 { + compatible = "marvell,mv88e6085"; + reg = <0x0>; + status = "okay"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + label = "cpu"; + phy-mode = "rgmii-id"; + ethernet = <&gem0>; + fixed-link { + speed = <1000>; + full-duplex; + }; + }; + + port@1 { + reg = <1>; + label = "sw0"; + fixed-link { + speed = <1000>; + full-duplex; + }; + }; + + port@2 { + reg = <2>; + label = "sw1"; + fixed-link { + speed = <1000>; + full-duplex; + }; + }; + }; + }; }; &uart1 { From 9a641e155b907a0937629eca4e747675d13409bf Mon Sep 17 00:00:00 2001 From: HatsyRei Date: Mon, 24 Mar 2025 15:29:22 +0800 Subject: [PATCH 084/100] ARM: dts: ni-zynq: Enable I2C Bus by default Enable I2C bus 0 by default for NI Zynq-based devices. Signed-off-by: HatsyRei (cherry picked from commit 935ab94f0212d2a72312d45f6c8003c2a7734d94) Signed-off-by: Gratian Crisan --- 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 086e17729433b..e1575daaab98d 100644 --- a/arch/arm/boot/dts/xilinx/ni-zynq.dtsi +++ b/arch/arm/boot/dts/xilinx/ni-zynq.dtsi @@ -118,6 +118,8 @@ }; &i2c0 { + status = "okay"; + nicpld@40 { compatible = "ni,cpld"; reg = <0x40>; From 35b467b658c3fd8007df1152512e3acdeef2e8f8 Mon Sep 17 00:00:00 2001 From: HatsyRei Date: Wed, 26 Mar 2025 15:40:45 +0800 Subject: [PATCH 085/100] ARM: dts: ni-bluefin: Specify mv88e6341 switch PHYs Marvell 88E6341 'Topaz' ethernet switch on Bluefin hardware has 6 ports, of which port 1 to 4 PHYs are mapped at SMI addresses from 0x11 to 0x14. Specify and bind them to the exposed ports on Bluefin devices. Signed-off-by: HatsyRei (cherry picked from commit 068c97593a4879202f66a063d04d057313b3aa5b) Signed-off-by: Gratian Crisan --- arch/arm/boot/dts/xilinx/ni-bluefin.dts | 28 ++++++++++++++++++------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/arch/arm/boot/dts/xilinx/ni-bluefin.dts b/arch/arm/boot/dts/xilinx/ni-bluefin.dts index 5a8e835ea2f71..05be6fe3fd902 100644 --- a/arch/arm/boot/dts/xilinx/ni-bluefin.dts +++ b/arch/arm/boot/dts/xilinx/ni-bluefin.dts @@ -105,19 +105,31 @@ port@1 { reg = <1>; label = "sw0"; - fixed-link { - speed = <1000>; - full-duplex; - }; + phy-handle = <&swphy1>; }; port@2 { reg = <2>; label = "sw1"; - fixed-link { - speed = <1000>; - full-duplex; - }; + phy-handle = <&swphy2>; + }; + }; + + mdio { + swphy1: ethernet-phy@11 { + reg = <0x11>; + }; + + swphy2: ethernet-phy@12 { + reg = <0x12>; + }; + + swphy3: ethernet-phy@13 { + reg = <0x13>; + }; + + swphy4: ethernet-phy@14 { + reg = <0x14>; }; }; }; From 25449e696936b098949db039ac59153f098417d5 Mon Sep 17 00:00:00 2001 From: Sien Date: Wed, 1 Jun 2016 09:57:13 -0500 Subject: [PATCH 086/100] ARM: ni-slsc-12001.dts: Add device tree for SLSC Migrated no-slsc-12001.dts related changes from branch dev/slsc/1.0/4.1 to ni/linux repo branch nilrt/master/6.6. The commits: 33bb24ec422d56e nati_slsc_dts: Add device tree for SLSC bd53913ffd7ca2c nati_slsc_dts: Correct SPI settings on device tree 9cf417b917ca50c nati_slsc_dts: fix IRQ for spi7/8 4a9c9dedc9c57d1 nati_slsc_dts: Add SLSC FPGA to Device Tree 05d7cb71400076f nati_slsc_dts: Remove trailing whitespace 85377cbaf33a07c nati_slsc_dts: Correct device info in device tree 489cdc8c332e7f6 nati_slsc_dts: pull in Tecate dts for 4.1 Linux kernel 3dac1d2e2886d11 nati_slsc_dts: Remove unused devices in dts 4740c7033c40894 nati_slsc_dts: Use spidev as compatible type in dts 297230220f55b18 nati_slsc_12001_dts: Rename dts file with model name 31600f928cd20af nati_slsc_12001_dts: Fix the format of the dts e3a89e6e7022b6e nati_slsc_12001_dts: set SLSC FPGA compatible id to ni,slscfpga a5f550aed87eb66 nati_slsc_12001_dts: Add AD7291 ADC to device tree b662f5d16e2e2f4 nati_slsc_12001_dts: Enforce level trigger for slscfpga IRQ 5fd9c31cd9ac578 nati_slsc_12001_dts: Reduce SPI max frequency m25p80 device Additional: removed execute permissions of ni-slsc-12001.dts file. added SPDX-License-Identifier on top of the file. Signed-off-by: Sien Signed-off-by: George Huang Signed-off-by: Kae Woei Kang (cherry picked from commit 844dac49a22d230415e02f95c46a5e8dd3d997bd) Signed-off-by: Gratian Crisan --- arch/arm/boot/dts/ni-slsc-12001.dts | 550 ++++++++++++++++++++++++++++ 1 file changed, 550 insertions(+) create mode 100644 arch/arm/boot/dts/ni-slsc-12001.dts diff --git a/arch/arm/boot/dts/ni-slsc-12001.dts b/arch/arm/boot/dts/ni-slsc-12001.dts new file mode 100644 index 0000000000000..98b46e0d37f24 --- /dev/null +++ b/arch/arm/boot/dts/ni-slsc-12001.dts @@ -0,0 +1,550 @@ +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; +/include/ "ni-zynq.dtsi" + +/* NIDEVCODE 78AA */ + +/ { + model = "NI SLSC-12001"; + compatible = "ni,zynq", "xlnx,zynq-7000"; + + aliases { + spi1 = &spiController1; + spi2 = &spiController2; + spi3 = &spiController3; + spi4 = &spiController4; + spi5 = &spiController5; + spi6 = &spiController6; + spi7 = &spiController7; + spi8 = &spiController8; + spi9 = &spiController9; + spi10 = &spiController10; + spi11 = &spiController11; + spi12 = &spiController12; + }; + + amba@0 { + + gpio: gpio@e000a000 { + /* You can specify GPIO settings here: + * + * gpioN-label String label. + * gpioN-direction "input" or "output". + * gpioN-settings "output" - specifies the GPIO state as "high" + * or "low". + * "input" - specifies GPIO interrupt settings as + * "none", "level-low", "level-high", + * "edge-falling", "edge-rising", or + * "edge-both". + */ + + /* GPIO1 (MIO1) */ + gpio1-label = "eth0_phy_interrupt"; + gpio1-direction = "input"; + gpio1-settings = "level-low"; + + /* GPIO15 (MIO15) */ + gpio15-label = "wdt_interrupt"; + gpio15-direction = "input"; + gpio15-settings = "edge-falling"; + + /* GPIO54 (EMIO0) */ + gpio54-label = "eth0_link_speed"; + gpio54-direction = "output"; + gpio54-settings = "low"; + + /* GPIO55 (EMIO1) */ + gpio55-label = "eth1_link_speed_1000"; + gpio55-direction = "output"; + gpio55-settings = "low"; + + /* GPIO56 (EMIO2) */ + gpio56-label = "eth1_link_speed_100"; + gpio56-direction = "output"; + gpio56-settings = "low"; + + /* GPIO57 (EMIO3) */ + gpio57-label = "eth1_phy_interrupt"; + gpio57-direction = "input"; + gpio57-settings = "level-low"; + }; + + 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"; + }; + }; + + i2c1: i2c@e0005000 { + status = "okay"; + + ad7291_adc@2c { + compatible = "ad7291"; + status = "okay"; + reg = <0x2C>; + }; + } ; + + spiController1: spi@0x80001000 { + compatible = "cdns,spi-r1p6"; + status = "okay"; + reg = <0x80001000 0x1000>; + interrupts = <0 31 4>; + clock-names = "ref_clk", "pclk"; + clocks = <&clkc 25>, <&clkc 34>; + #address-cells = <1>; + #size-cells = <0>; + + + m25p80@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "m25p80","jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <1000000>; + + partition@0 { + label = "slsc_slot1"; + reg = <0x0 0x100000>; + }; + }; + + + spidev@1 { + compatible ="spidev"; + spi-max-frequency = <1000000>; + reg = <1>; + }; + }; + + + spiController2: spi@0x80002000 { + compatible = "cdns,spi-r1p6"; + status = "okay"; + reg = <0x80002000 0x1000>; + interrupts = <0 32 4>; + clock-names = "ref_clk", "pclk"; + clocks = <&clkc 25>, <&clkc 34>; + #address-cells = <1>; + #size-cells = <0>; + + m25p80@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "m25p80","jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <1000000>; + + partition@0 { + label = "slsc_slot2"; + reg = <0x0 0x100000>; + }; + }; + + + spidev@1 { + compatible = "spidev"; + spi-max-frequency = <1000000>; + reg = <1>; + }; + }; + + + spiController3: spi@0x80003000 { + compatible = "cdns,spi-r1p6"; + status = "okay"; + reg = <0x80003000 0x1000>; + interrupts = <0 33 4>; + clock-names = "ref_clk", "pclk"; + clocks = <&clkc 25>, <&clkc 34>; + #address-cells = <1>; + #size-cells = <0>; + + m25p80@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "m25p80","jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <1000000>; + + partition@0 { + label = "slsc_slot3"; + reg = <0x0 0x100000>; + }; + }; + + + spidev@1 { + compatible = "spidev"; + spi-max-frequency = <1000000>; + reg = <1>; + }; + }; + + + spiController4: spi@0x80004000 { + compatible = "cdns,spi-r1p6"; + status = "okay"; + reg = <0x80004000 0x1000>; + interrupts = <0 34 4>; + clock-names = "ref_clk", "pclk"; + clocks = <&clkc 25>, <&clkc 34>; + #address-cells = <1>; + #size-cells = <0>; + + m25p80@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "m25p80","jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <1000000>; + + partition@0 { + label = "slsc_slot4"; + reg = <0x0 0x100000>; + }; + }; + + + spidev@1 { + compatible = "spidev"; + spi-max-frequency = <1000000>; + reg = <1>; + }; + }; + + + spiController5: spi@0x80005000 { + compatible = "cdns,spi-r1p6"; + status = "okay"; + reg = <0x80005000 0x1000>; + interrupts = <0 35 4>; + clock-names = "ref_clk", "pclk"; + clocks = <&clkc 25>, <&clkc 34>; + #address-cells = <1>; + #size-cells = <0>; + + m25p80@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "m25p80","jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <1000000>; + + partition@0 { + label = "slsc_slot5"; + reg = <0x0 0x100000>; + }; + }; + + + spidev@1 { + compatible = "spidev"; + spi-max-frequency = <1000000>; + reg = <1>; + }; + }; + + spiController6: spi@0x80006000 { + compatible = "cdns,spi-r1p6"; + status = "okay"; + reg = <0x80006000 0x1000>; + interrupts = <0 36 4>; + clock-names = "ref_clk", "pclk"; + clocks = <&clkc 25>, <&clkc 34>; + #address-cells = <1>; + #size-cells = <0>; + + m25p80@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "m25p80","jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <1000000>; + + partition@0 { + label = "slsc_slot6"; + reg = <0x0 0x100000>; + }; + }; + + + spidev@1 { + compatible = "spidev"; + spi-max-frequency = <1000000>; + reg = <1>; + }; + }; + + spiController7: spi@0x80007000 { + compatible = "cdns,spi-r1p6"; + status = "okay"; + reg = <0x80007000 0x1000>; + interrupts = <0 52 4>; + clock-names = "ref_clk", "pclk"; + clocks = <&clkc 25>, <&clkc 34>; + #address-cells = <1>; + #size-cells = <0>; + + m25p80@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "m25p80","jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <1000000>; + + partition@0 { + label = "slsc_slot7"; + reg = <0x0 0x100000>; + }; + }; + + + spidev@1 { + compatible = "spidev"; + spi-max-frequency = <1000000>; + reg = <1>; + }; + }; + + spiController8: spi@0x80008000 { + compatible = "cdns,spi-r1p6"; + status = "okay"; + reg = <0x80008000 0x1000>; + interrupts = <0 53 4>; + clock-names = "ref_clk", "pclk"; + clocks = <&clkc 25>, <&clkc 34>; + #address-cells = <1>; + #size-cells = <0>; + + m25p80@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "m25p80","jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <1000000>; + + partition@0 { + label = "slsc_slot8"; + reg = <0x0 0x100000>; + }; + }; + + + spidev@1 { + compatible = "spidev"; + spi-max-frequency = <1000000>; + reg = <1>; + }; + }; + + spiController9: spi@0x80009000 { + compatible = "cdns,spi-r1p6"; + status = "okay"; + reg = <0x80009000 0x1000>; + interrupts = <0 54 4>; + clock-names = "ref_clk", "pclk"; + clocks = <&clkc 25>, <&clkc 34>; + #address-cells = <1>; + #size-cells = <0>; + + m25p80@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "m25p80","jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <1000000>; + + partition@0 { + label = "slsc_slot9"; + reg = <0x0 0x100000>; + }; + }; + + + spidev@1 { + compatible = "spidev"; + spi-max-frequency = <1000000>; + reg = <1>; + }; + }; + + spiController10: spi@0x8000A000 { + compatible = "cdns,spi-r1p6"; + status = "okay"; + reg = <0x8000A000 0x1000>; + interrupts = <0 55 4>; + clock-names = "ref_clk", "pclk"; + clocks = <&clkc 25>, <&clkc 34>; + #address-cells = <1>; + #size-cells = <0>; + + m25p80@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "m25p80","jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <1000000>; + + partition@0 { + label = "slsc_slot10"; + reg = <0x0 0x100000>; + }; + }; + + + spidev@1 { + compatible = "spidev"; + spi-max-frequency = <1000000>; + reg = <1>; + }; + }; + + + spiController11: spi@0x8000B000 { + compatible = "cdns,spi-r1p6"; + status = "okay"; + reg = <0x8000B000 0x1000>; + interrupts = <0 56 4>; + clock-names = "ref_clk", "pclk"; + clocks = <&clkc 25>, <&clkc 34>; + #address-cells = <1>; + #size-cells = <0>; + + m25p80@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "m25p80","jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <1000000>; + + partition@0 { + label = "slsc_slot11"; + reg = <0x0 0x100000>; + }; + }; + + + spidev@1 { + compatible = "spidev"; + spi-max-frequency = <1000000>; + reg = <1>; + }; + }; + + + spiController12: spi@0x8000C000 { + compatible = "cdns,spi-r1p6"; + status = "okay"; + reg = <0x8000C000 0x1000>; + interrupts = <0 57 4>; + clock-names = "ref_clk", "pclk"; + clocks = <&clkc 25>, <&clkc 34>; + #address-cells = <1>; + #size-cells = <0>; + + m25p80@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "m25p80","jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <1000000>; + + partition@0 { + label = "slsc_slot12"; + reg = <0x0 0x100000>; + }; + }; + + + spidev@1 { + compatible = "spidev"; + spi-max-frequency = <1000000>; + reg = <1>; + }; + }; + + slscfpga@80000000 { + compatible = "ni,slscfpga"; + reg = <0x80000000 0x30000>; + interrupts = <0 29 4>; + }; + + }; + + +}; + +&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"; +}; + +&usb1 { + status = "okay"; + dr_mode = "host"; +}; + +&clkc { + /* Enable fclk0 for eth0 and eth1, fclk1 for serial. */ + fclk-enable = <0x3>; +}; From 3d423041d24b686ead799b3cde65be816be02af3 Mon Sep 17 00:00:00 2001 From: Kae Woei Kang Date: Thu, 24 Apr 2025 14:35:38 +0800 Subject: [PATCH 087/100] ARM: ni-slsc-12001.dts: Update i2c bindings zynq-700.dtsi contains i2c0 and i2c1 device tree node phandles. Referencing i2c0 and i2c1 phandle for overriding i2c bindings. Signed-off-by: Kae Woei Kang (cherry picked from commit 2733e42bd43e7e70392c623393f8deb122354ba7) Signed-off-by: Gratian Crisan --- .../boot/dts/{ => xilinx}/ni-slsc-12001.dts | 86 ++++++++++--------- 1 file changed, 44 insertions(+), 42 deletions(-) rename arch/arm/boot/dts/{ => xilinx}/ni-slsc-12001.dts (93%) diff --git a/arch/arm/boot/dts/ni-slsc-12001.dts b/arch/arm/boot/dts/xilinx/ni-slsc-12001.dts similarity index 93% rename from arch/arm/boot/dts/ni-slsc-12001.dts rename to arch/arm/boot/dts/xilinx/ni-slsc-12001.dts index 98b46e0d37f24..40d7b7a5a3d81 100644 --- a/arch/arm/boot/dts/ni-slsc-12001.dts +++ b/arch/arm/boot/dts/xilinx/ni-slsc-12001.dts @@ -69,48 +69,6 @@ gpio57-settings = "level-low"; }; - 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"; - }; - }; - - i2c1: i2c@e0005000 { - status = "okay"; - - ad7291_adc@2c { - compatible = "ad7291"; - status = "okay"; - reg = <0x2C>; - }; - } ; - spiController1: spi@0x80001000 { compatible = "cdns,spi-r1p6"; status = "okay"; @@ -530,6 +488,50 @@ }; }; +&i2c0 { + /* Override ni-zynq.dtsi */ + 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"; + }; +}; + +&i2c1 { + /* Override ni-zynq.dtsi */ + status = "okay"; + + ad7291_adc@2c { + compatible = "ad7291"; + status = "okay"; + reg = <0x2C>; + }; +}; + &sdhci0 { status = "okay"; }; From 310de431afdcef670de163385e589376d1f0c72b Mon Sep 17 00:00:00 2001 From: deooi Date: Mon, 5 Jan 2026 16:18:32 +0800 Subject: [PATCH 088/100] ni-bluefin: enable mv88e6xxx PHY interrupts The mv88e6xxx driver gained support for PHY interrupt handling in newer kernels (6.12), whereas older kernels (e.g. 4.1) only supported polling over the MDIO bus. On ni-bluefin, the PHY interrupt lines have always been physically connected on the board but were not described or used previously due to the lack of driver support. Enabling PHY interrupts in the device tree allows the driver to rely on interrupt-driven link and status updates instead of frequent MDIO polling. This significantly reduces MDIO bus traffic and contention. Reducing MDIO contention is required to free up bus bandwidth, allowing the system to sustain higher sampling rates without MDIO-related interference. Signed-off-by: deooi --- arch/arm/boot/dts/xilinx/ni-bluefin.dts | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/arch/arm/boot/dts/xilinx/ni-bluefin.dts b/arch/arm/boot/dts/xilinx/ni-bluefin.dts index 05be6fe3fd902..9cb5339debbf5 100644 --- a/arch/arm/boot/dts/xilinx/ni-bluefin.dts +++ b/arch/arm/boot/dts/xilinx/ni-bluefin.dts @@ -1,4 +1,5 @@ /dts-v1/; +#include /include/ "ni-zynq.dtsi" /* NIDEVCODE 78C7 */ @@ -86,6 +87,10 @@ compatible = "marvell,mv88e6085"; reg = <0x0>; status = "okay"; + interrupt-parent = <&intc>; + interrupts = <45 IRQ_TYPE_LEVEL_LOW>; + interrupt-controller; + #interrupt-cells = <2>; ports { #address-cells = <1>; @@ -123,14 +128,6 @@ swphy2: ethernet-phy@12 { reg = <0x12>; }; - - swphy3: ethernet-phy@13 { - reg = <0x13>; - }; - - swphy4: ethernet-phy@14 { - reg = <0x14>; - }; }; }; }; From b2f495c2c0f5ecd783e285d374f707f842ba7f25 Mon Sep 17 00:00:00 2001 From: Gratian Crisan Date: Wed, 15 Apr 2026 16:48:49 -0500 Subject: [PATCH 089/100] ARM: dts: ni-slsc-12001: Enable system watchdog Use the phandle reference @watchdog0 to add reset-on-timeout property to cadence watchdog. This will allow the system to reboot when it hangs for more than 10 sec. Signed-off-by: George Huang Acked-by: Brad Mouring Acked-by: Brad Keryan Acked-by: Josh Cartwright Acked-by: Gratian Crisan Natinst-ReviewBoard-ID 149067 Signed-off-by: Kae Woei Kang (cherry picked from commit b814f58c39857571537366802eda188f73b03083) Signed-off-by: Gratian Crisan [gratian: split dts changes from into a separate commit and reword] Signed-off-by: Gratian Crisan --- arch/arm/boot/dts/xilinx/ni-slsc-12001.dts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm/boot/dts/xilinx/ni-slsc-12001.dts b/arch/arm/boot/dts/xilinx/ni-slsc-12001.dts index 40d7b7a5a3d81..a1d2e4b26849b 100644 --- a/arch/arm/boot/dts/xilinx/ni-slsc-12001.dts +++ b/arch/arm/boot/dts/xilinx/ni-slsc-12001.dts @@ -459,6 +459,10 @@ }; +&watchdog0 { + reset-on-timeout; +}; + &gem0 { status = "okay"; From 83c77c1c57f08e0d8efff643f2722baee2a75467 Mon Sep 17 00:00:00 2001 From: deooi Date: Mon, 13 Apr 2026 11:22:55 +0800 Subject: [PATCH 090/100] dts: Add ni-bluefinlc device tree Device tree for Bluefin LC devices are for Low-cost Ethernet cDAQ-9183 and cDAQ-9187. The changes here is to update the model name, NIDEVCODE and removal of dsa switch port 2 (sw1) since Bluefin LC devices only have a single ethernet port. Otherwise, the rest of the device tree remains the same as Bluefin. Signed-off-by: deooi --- arch/arm/boot/dts/xilinx/ni-bluefinlc.dts | 138 ++++++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 arch/arm/boot/dts/xilinx/ni-bluefinlc.dts diff --git a/arch/arm/boot/dts/xilinx/ni-bluefinlc.dts b/arch/arm/boot/dts/xilinx/ni-bluefinlc.dts new file mode 100644 index 0000000000000..65a4040f1a396 --- /dev/null +++ b/arch/arm/boot/dts/xilinx/ni-bluefinlc.dts @@ -0,0 +1,138 @@ +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; +#include +/include/ "ni-zynq.dtsi" + +/* NIDEVCODE 7B37 */ +/* NIDEVCODE 7B38 */ + +/ { + model = "NI Bluefin LC"; + compatible = "ni,zynq", "xlnx,zynq-7000"; + + leds { + compatible = "gpio-leds"; + + /* LED_STATUSy on GPIO46 */ + status { + label = "nilrt:status:yellow"; + gpios = <&gpio0 46 0>; + default-state = "on"; + }; + + /* LED_ACTIVEg on GPIO47 */ + active { + label = "nilrt:active:green"; + gpios = <&gpio0 47 0>; + default-state = "off"; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + + /* Reset switch is on GPIO48 */ + reset_sw@0 { + label = "reset_sw"; + gpios = <&gpio0 48 1 /* GPIO_ACTIVE_LOW */>; + linux,code = <408>; /* KEY_RESTART */ + wakeup-source; + }; + }; + + gpio_restart { + compatible = "gpio-restart"; + + /* ~PS_FORCE_RESET is on GPIO44 */ + gpios = <&gpio0 44 1 /* GPIO_ACTIVE_LOW */>; + priority = <200>; + }; +}; + +&i2c0 { + /* Override ni-zynq.dtsi; we do not have a CPLD at 0x40. */ + nicpld@40 { + status = "disabled"; + }; + + tmp451@4c { + compatible = "ti,tmp451"; + reg = <0x4c>; + vcc-supply = <®ulator_vccpint>; + }; +}; + +&gem0 { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + + fixed-link { + speed = <1000>; + full-duplex; + reg = <0>; + }; + + mdio0: mdio { + status = "okay"; + }; +}; + +&mdio0 { + #address-cells = <1>; + #size-cells = <0>; + + switch: switch@0 { + compatible = "marvell,mv88e6085"; + reg = <0>; + status = "okay"; + interrupt-parent = <&intc>; + interrupts = <45 IRQ_TYPE_LEVEL_LOW>; + interrupt-controller; + #interrupt-cells = <2>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + label = "cpu"; + phy-mode = "rgmii-id"; + ethernet = <&gem0>; + fixed-link { + speed = <1000>; + full-duplex; + }; + }; + + port@1 { + reg = <1>; + label = "sw0"; + phy-handle = <&swphy1>; + }; + }; + + mdio { + swphy1: ethernet-phy@11 { + reg = <0x11>; + }; + }; + }; +}; + +&uart1 { + status = "okay"; +}; + +&usb0 { + status = "okay"; + dr_mode = "host"; +}; + +&watchdog0 { + status = "okay"; + reset-on-timeout; +}; From 3dffc9f9d921e81d909850e9fbc15f1a583cc93f Mon Sep 17 00:00:00 2001 From: Jeff Westfahl Date: Fri, 10 May 2013 17:18:01 -0500 Subject: [PATCH 091/100] mtd: Introduce CONFIG_MTD_RESERVE_END Add a new config parameter CONFIG_MTD_RESERVE_END. This is used with command line partition parsing to reserve space at the end of a partition defined with a size of '-', which indicates it should use all remaining space. Signed-off-by: Jeff Westfahl (cherry picked from commit 68ca9523c2d424d8bb3f71feb244464a1c6d49c9) Signed-off-by: Hatsy Rei --- drivers/mtd/parsers/Kconfig | 24 ++++++++++++++++++++++++ drivers/mtd/parsers/cmdlinepart.c | 3 ++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/parsers/Kconfig b/drivers/mtd/parsers/Kconfig index da03ab6efe04c..93d4d3fcb786a 100644 --- a/drivers/mtd/parsers/Kconfig +++ b/drivers/mtd/parsers/Kconfig @@ -62,6 +62,30 @@ config MTD_CMDLINE_PARTS If unsure, say 'N'. +config MTD_RESERVE_END + int "Reserved space at the end of an all remaining space partition" + depends on MTD_CMDLINE_PARTS = "y" + default 0 + help + Specify an amount of reserved space at the end of the last MTD + partition when the size is specified with '-' to denote all + remaining space. + + This can be useful if, for example, the BBT is stored at the end + of the flash, and you don't want those blocks counted as part of + the last MTD partition. This is less heavyweight than reserving + the BBT blocks with a separate MTD partition. The BBT marks its + own blocks as bad blocks, which prevents an MTD driver such as + UBI from getting an accurate count of the actual bad blocks in + the MTD partition that contains the BBT. + + The value is specified in bytes. As an example, a typical BBT + reserves four erase blocks, and a typical erase block size is + 128kB. To reserve that much space at the end of the flash, the + value for this config option would be 524288. + + If unsure, use the default value of zero. + config MTD_OF_PARTS tristate "OpenFirmware (device tree) partitioning parser" default y diff --git a/drivers/mtd/parsers/cmdlinepart.c b/drivers/mtd/parsers/cmdlinepart.c index 504e5fa2b45b0..b77a40158970c 100644 --- a/drivers/mtd/parsers/cmdlinepart.c +++ b/drivers/mtd/parsers/cmdlinepart.c @@ -357,7 +357,8 @@ static int parse_cmdline_partitions(struct mtd_info *master, offset = part->parts[i].offset; if (part->parts[i].size == SIZE_REMAINING) - part->parts[i].size = master->size - offset; + part->parts[i].size = master->size - offset - + CONFIG_MTD_RESERVE_END; if (offset + part->parts[i].size > master->size) { pr_warn("%s: partitioning exceeds flash size, truncating\n", From 33e9681d3c94837376d781d9977b1c8d57d0bd36 Mon Sep 17 00:00:00 2001 From: Gratian Crisan Date: Thu, 25 Sep 2014 15:18:43 -0500 Subject: [PATCH 092/100] mtd: nand: xilinx: Rename the pl353 NAND driver to match bootloader The Zynq static memory controller is based on ARM PL353. The following commit [3fa059cfa4b105f09752a4eb7480d122dd5e796b nand: pl353: Renamed zynq_nand driver as pl353_nand] renamed the driver to "pl353-nand" to match the hardware. This creates problems on shipping hardware due to a mismatch between what u-boot expects (via bootargs/mtdparts) and the kernel driver name. This commit reverts the NAND driver name to the old "xilinx_nand" in order to preserve compatibility. Signed-off-by: Gratian Crisan Acked-by: Joseph Hershberger Acked-by: Terry Wilcox Natinst-ReviewBoard-ID: 79256 (cherry picked from commit df465252df84668ac5318fe6394eca5e3fe38426) Signed-off-by: Hatsy Rei --- drivers/mtd/nand/raw/pl35x-nand-controller.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/nand/raw/pl35x-nand-controller.c b/drivers/mtd/nand/raw/pl35x-nand-controller.c index 11bd90e3f18cb..22cadc73f82ad 100644 --- a/drivers/mtd/nand/raw/pl35x-nand-controller.c +++ b/drivers/mtd/nand/raw/pl35x-nand-controller.c @@ -28,7 +28,7 @@ #include #include -#define PL35X_NANDC_DRIVER_NAME "pl35x-nand-controller" +#define PL35X_NANDC_DRIVER_NAME "xilinx_nand" /* SMC controller status register (RO) */ #define PL35X_SMC_MEMC_STATUS 0x0 From d254b666b4af88319ed63dd309932ec32cb71dcb Mon Sep 17 00:00:00 2001 From: HatsyRei Date: Tue, 4 Mar 2025 14:20:43 +0800 Subject: [PATCH 093/100] mtd: Create gluebi mtdblocks if CONFIG_FTL is not enabled Upstream commit a43bdc376dea ("mtd: Fix gluebi NULL pointer dereference caused by ftl notifier") fixed a NULL pointer dereference, which can be caused by FTL notifier accessing 'gluebi->desc' in gluebi_read, by completely preventing gluebi from creating mtdblock devices. This creates a problem as existing systems may expect mtdblocks emulated on top of UBI to exist. As a workaround, this commit prevents gluebi mtdblock device creation only if CONFIG_FTL is enabled. Signed-off-by: HatsyRei [gratian: reword to match commit quoting kernel standard] Signed-off-by: Gratian Crisan (cherry picked from commit 1d286b174c9a3db2df36cdd8d6bd4c3766c4da65) Signed-off-by: Chaitanya Vadrevu --- drivers/mtd/mtd_blkdevs.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c index 28e09d0804405..3622f98b25052 100644 --- a/drivers/mtd/mtd_blkdevs.c +++ b/drivers/mtd/mtd_blkdevs.c @@ -457,7 +457,8 @@ static void blktrans_notify_add(struct mtd_info *mtd) { struct mtd_blktrans_ops *tr; - if (mtd->type == MTD_ABSENT || mtd->type == MTD_UBIVOLUME) + if (mtd->type == MTD_ABSENT || + (IS_ENABLED(CONFIG_FTL) && mtd->type == MTD_UBIVOLUME)) return; list_for_each_entry(tr, &blktrans_majors, list) @@ -497,7 +498,8 @@ int register_mtd_blktrans(struct mtd_blktrans_ops *tr) mutex_lock(&mtd_table_mutex); list_add(&tr->list, &blktrans_majors); mtd_for_each_device(mtd) - if (mtd->type != MTD_ABSENT && mtd->type != MTD_UBIVOLUME) + if (mtd->type != MTD_ABSENT && + !(IS_ENABLED(CONFIG_FTL) && mtd->type == MTD_UBIVOLUME)) tr->add_mtd(tr, mtd); mutex_unlock(&mtd_table_mutex); return 0; From 0d7f1f917430599dfe0721f37dda9389f0d34113 Mon Sep 17 00:00:00 2001 From: deooi Date: Fri, 14 Mar 2025 14:46:08 +0800 Subject: [PATCH 094/100] pl35x-nand-controller: Enable dynamic clk rate setting NI Zynq based devices require different clk frequencies to be set at different timing modes. Enable the memclk rate to be set according to the specifications in the device tree. If the device tree does not have this memclk-timing-frequency property specified, the driver proceeds as usual. Signed-off-by: deooi (cherry picked from commit ea79ee45f097cc1490a31a6cebc4f05ea6fa5c3e) Signed-off-by: Gratian Crisan --- arch/arm/boot/dts/xilinx/ni-zynq.dtsi | 10 +++++ drivers/mtd/nand/raw/pl35x-nand-controller.c | 41 ++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/arch/arm/boot/dts/xilinx/ni-zynq.dtsi b/arch/arm/boot/dts/xilinx/ni-zynq.dtsi index e1575daaab98d..d694aedc9c5d6 100644 --- a/arch/arm/boot/dts/xilinx/ni-zynq.dtsi +++ b/arch/arm/boot/dts/xilinx/ni-zynq.dtsi @@ -142,6 +142,16 @@ &smcc { status = "okay"; + /* + * NI Zynq based devices require different memclk frequency + * for different timing modes + */ + memclk-timing-frequency = <0 83333333>, + <1 166666666>, + <2 166666666>, + <3 166666666>, + <4 166666666>, + <5 166666666>; }; &nfc0 { diff --git a/drivers/mtd/nand/raw/pl35x-nand-controller.c b/drivers/mtd/nand/raw/pl35x-nand-controller.c index 22cadc73f82ad..4bb628022ad74 100644 --- a/drivers/mtd/nand/raw/pl35x-nand-controller.c +++ b/drivers/mtd/nand/raw/pl35x-nand-controller.c @@ -781,6 +781,28 @@ static int pl35x_nfc_exec_op(struct nand_chip *chip, op, check_only); } +static unsigned long of_get_memclk_freq(const struct device_node *np, const int timing_mode) +{ + int memclk_frequency, i, total_elements; + u32 memclk_mode; + + total_elements = of_property_count_u32_elems(np, "memclk-timing-frequency"); + if (total_elements <= 0) + return 0; + + for (i = 0; i < total_elements; i = i+2) { + of_property_read_u32_index(np, "memclk-timing-frequency", i, &memclk_mode); + if (memclk_mode == timing_mode) { + of_property_read_u32_index(np, "memclk-timing-frequency", + i+1, &memclk_frequency); + return memclk_frequency; + } + } + + pr_err("Failed to find matching memclk timing mode %d\n", timing_mode); + return 0; +} + static int pl35x_nfc_setup_interface(struct nand_chip *chip, int cs, const struct nand_interface_config *conf) { @@ -790,6 +812,8 @@ static int pl35x_nfc_setup_interface(struct nand_chip *chip, int cs, const struct nand_sdr_timings *sdr; unsigned int period_ns, val; struct clk *mclk; + unsigned long memclk_of_timing_freq; + int ret = 0; sdr = nand_get_sdr_timings(conf); if (IS_ERR(sdr)) @@ -801,6 +825,23 @@ static int pl35x_nfc_setup_interface(struct nand_chip *chip, int cs, return PTR_ERR(mclk); } + /* + * NI Zynq based devices require different rates for different timing modes + * so we need to set the rate according to the timing modes + */ + memclk_of_timing_freq = of_get_memclk_freq( + nfc->dev->parent->of_node, + conf->timings.mode); + + if (memclk_of_timing_freq) { + ret = clk_set_rate(mclk, memclk_of_timing_freq); + if (ret) { + pr_err("Failed to set memclk timing frequency to %lu\n", + memclk_of_timing_freq); + return ret; + } + } + /* * SDR timings are given in pico-seconds while NFC timings must be * expressed in NAND controller clock cycles. We use the TO_CYCLE() From d7195293b3f1526a84cde21f789821fdc57ed3e1 Mon Sep 17 00:00:00 2001 From: Haris Okanovic Date: Wed, 7 Sep 2016 11:16:52 -0500 Subject: [PATCH 095/100] pl353_nand: Add module params to disable subpage read and write Add `enable_subpage_read` and `enable_subpage_write` load-time options to toggle subpage read/write operations on pl353 chips. Both options are enabled by default, and may be toggled in the boot loader. Signed-off-by: Haris Okanovic Acked-by: Gratian Crisan Acked-by: Jeff Westfahl Natinst-CAR-ID: 599280 Natinst-ReviewBoard-ID: 151758 (cherry picked from commit 311a5711cfdbfa20e3f4ec2dbd429f96b9f76c2f) (cherry picked from commit f261b4b6df120eda51a83a876448bcfc14919eab) Signed-off-by: HatsyRei (cherry picked from commit 118d09c47934983a23c15e803dcf337c8e663b31) Signed-off-by: HatsyRei --- drivers/mtd/nand/raw/pl35x-nand-controller.c | 24 ++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/drivers/mtd/nand/raw/pl35x-nand-controller.c b/drivers/mtd/nand/raw/pl35x-nand-controller.c index 4bb628022ad74..17eeffa99f4c5 100644 --- a/drivers/mtd/nand/raw/pl35x-nand-controller.c +++ b/drivers/mtd/nand/raw/pl35x-nand-controller.c @@ -144,6 +144,14 @@ struct pl35x_nandc { u8 *ecc_buf; }; +static bool enable_subpage_read = 1; +module_param(enable_subpage_read, bool, 0444); +MODULE_PARM_DESC(enable_subpage_read, "Load-time parameter to toggle subpage reads on supported nand chips. Enabled by default."); + +static bool enable_subpage_write = 1; +module_param(enable_subpage_write, bool, 0444); +MODULE_PARM_DESC(enable_subpage_write, "Load-time parameter to toggle subpage writes on supported nand chips. Enabled by default."); + static inline struct pl35x_nandc *to_pl35x_nandc(struct nand_controller *ctrl) { return container_of(ctrl, struct pl35x_nandc, controller); @@ -977,6 +985,21 @@ static int pl35x_nand_init_hw_ecc_controller(struct pl35x_nandc *nfc, return ret; } +static void pl35x_nand_setup_ondie_ecc(struct nand_chip *chip) +{ + /* NAND with on-die ECC supports subpage reads */ + if (enable_subpage_read) + chip->options |= NAND_SUBPAGE_READ; + else + chip->options &= ~(NAND_SUBPAGE_READ); + + /* NAND with on-die ECC may support subpage writes */ + if (enable_subpage_write) + chip->options &= ~(NAND_NO_SUBPAGE_WRITE); + else + chip->options |= NAND_NO_SUBPAGE_WRITE; +} + static int pl35x_nand_attach_chip(struct nand_chip *chip) { const struct nand_ecc_props *requirements = @@ -1011,6 +1034,7 @@ static int pl35x_nand_attach_chip(struct nand_chip *chip) switch (chip->ecc.engine_type) { case NAND_ECC_ENGINE_TYPE_ON_DIE: + pl35x_nand_setup_ondie_ecc(chip); /* Keep these legacy BBT descriptors for ON_DIE situations */ chip->bbt_td = &bbt_main_descr; chip->bbt_md = &bbt_mirror_descr; From bb54077858d6e7e8c70e828ff4ef24b3e051e2cc Mon Sep 17 00:00:00 2001 From: HatsyRei Date: Tue, 22 Apr 2025 14:59:11 +0800 Subject: [PATCH 096/100] mtd: nand_micron: Enable subpage operations Existing devices which utilize Micron NAND may contain partitions formatted with subpages. Support this use case by implementing hooks for subpage read and write in Micron NAND driver. Signed-off-by: HatsyRei (cherry picked from commit bc5d81525799d4ff42b5f40b89368778a1a648c8) Signed-off-by: HatsyRei --- drivers/mtd/nand/raw/nand_micron.c | 51 ++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/drivers/mtd/nand/raw/nand_micron.c b/drivers/mtd/nand/raw/nand_micron.c index c0192881906b8..3af30d4eae149 100644 --- a/drivers/mtd/nand/raw/nand_micron.c +++ b/drivers/mtd/nand/raw/nand_micron.c @@ -365,6 +365,46 @@ micron_nand_read_page_on_die_ecc(struct nand_chip *chip, uint8_t *buf, return ret ? ret : max_bitflips; } +static int +micron_nand_read_subpage_on_die_ecc(struct nand_chip *chip, uint32_t data_offs, + uint32_t readlen, uint8_t *bufpoi, int page) +{ + struct mtd_info *mtd = nand_to_mtd(chip); + u8 status; + int ret, max_bitflips = 0; + + ret = micron_nand_on_die_ecc_setup(chip, true); + if (ret) + return ret; + + ret = nand_status_op(chip, &status); + if (ret) + goto out; + + ret = nand_read_page_op(chip, page, data_offs, + bufpoi + data_offs, readlen); + if (ret) + goto out; + + ret = nand_status_op(chip, &status); + if (ret) + goto out; + + if (status & NAND_STATUS_FAIL) { + /* uncorrected */ + mtd->ecc_stats.failed++; + } else if (status & NAND_ECC_STATUS_WRITE_RECOMMENDED) { + /* corrected */ + max_bitflips = mtd->bitflip_threshold; + mtd->ecc_stats.corrected += max_bitflips; + } + +out: + micron_nand_on_die_ecc_setup(chip, false); + + return ret ? ret : max_bitflips; +} + static int micron_nand_write_page_on_die_ecc(struct nand_chip *chip, const uint8_t *buf, int oob_required, int page) @@ -381,6 +421,15 @@ micron_nand_write_page_on_die_ecc(struct nand_chip *chip, const uint8_t *buf, return ret; } +static int +micron_nand_write_subpage_on_die_ecc(struct nand_chip *chip, + uint32_t offset, uint32_t data_len, + const uint8_t *data_buf, + int oob_required, int page) +{ + return micron_nand_write_page_on_die_ecc(chip, data_buf, oob_required, page); +} + enum { /* The NAND flash doesn't support on-die ECC */ MICRON_ON_DIE_UNSUPPORTED, @@ -550,7 +599,9 @@ static int micron_nand_init(struct nand_chip *chip) chip->ecc.strength = requirements->strength; chip->ecc.algo = NAND_ECC_ALGO_BCH; chip->ecc.read_page = micron_nand_read_page_on_die_ecc; + chip->ecc.read_subpage = micron_nand_read_subpage_on_die_ecc; chip->ecc.write_page = micron_nand_write_page_on_die_ecc; + chip->ecc.write_subpage = micron_nand_write_subpage_on_die_ecc; if (ondie == MICRON_ON_DIE_MANDATORY) { chip->ecc.read_page_raw = nand_read_page_raw_notsupp; From b80ea604a675f00b56ba11f4c29607732885b09a Mon Sep 17 00:00:00 2001 From: Chaitanya Vadrevu Date: Thu, 6 Mar 2025 18:06:50 -0600 Subject: [PATCH 097/100] nati_zynq_defconfig: defconfig for NI Zynq-based targets [cvadrevu: squash all defconfig commits accumulated up to 6.6.77-rt50 and regenerate for 6.12.16-rt9] Signed-off-by: Chaitanya Vadrevu [gratian: regenerate for 6.18.13-rt4] Signed-off-by: Gratian Crisan --- arch/arm/configs/nati_zynq_defconfig | 313 +++++++++++++++++++++++++++ 1 file changed, 313 insertions(+) create mode 100644 arch/arm/configs/nati_zynq_defconfig diff --git a/arch/arm/configs/nati_zynq_defconfig b/arch/arm/configs/nati_zynq_defconfig new file mode 100644 index 0000000000000..9f1004d03889a --- /dev/null +++ b/arch/arm/configs/nati_zynq_defconfig @@ -0,0 +1,313 @@ +CONFIG_LOCALVERSION="-ni" +CONFIG_SYSVIPC=y +CONFIG_AUDIT=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_CGROUPS=y +CONFIG_CPUSETS=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSFS_SYSCALL=y +CONFIG_PERF_EVENTS=y +CONFIG_ARCH_ZYNQ=y +CONFIG_ARM_ERRATA_754322=y +CONFIG_ARM_ERRATA_764369=y +CONFIG_ARM_ERRATA_775420=y +CONFIG_SMP=y +CONFIG_HIGHMEM=y +CONFIG_CMDLINE="console=ttyPS0,115200n8 root=/dev/ram rw initrd=0x00800000,16M earlyprintk mtdparts=physmap-flash.0:512K(nor-fsbl),512K(nor-u-boot),5M(nor-linux),9M(nor-user),1M(nor-scratch),-(nor-rootfs)" +CONFIG_VFP=y +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_COMPACTION is not set +CONFIG_CMA=y +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_MULTIPATH=y +CONFIG_IP_ROUTE_VERBOSE=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_RARP=y +CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE_DEMUX=m +CONFIG_NET_IPGRE=m +CONFIG_NET_IPGRE_BROADCAST=y +CONFIG_IP_MROUTE=y +CONFIG_IP_MROUTE_MULTIPLE_TABLES=y +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y +CONFIG_INET_AH=m +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=m +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +CONFIG_NETFILTER=y +CONFIG_NF_CONNTRACK=m +CONFIG_NF_CONNTRACK_EVENTS=y +CONFIG_NF_CONNTRACK_TIMESTAMP=y +CONFIG_NF_CONNTRACK_AMANDA=m +CONFIG_NF_CONNTRACK_FTP=m +CONFIG_NF_CONNTRACK_H323=m +CONFIG_NF_CONNTRACK_IRC=m +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_SNMP=m +CONFIG_NF_CONNTRACK_PPTP=m +CONFIG_NF_CONNTRACK_SANE=m +CONFIG_NF_CONNTRACK_SIP=m +CONFIG_NF_CONNTRACK_TFTP=m +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_MARK=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_TEE=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m +CONFIG_NETFILTER_XT_MATCH_CLUSTER=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m +CONFIG_NETFILTER_XT_MATCH_CONNMARK=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_CPU=m +CONFIG_NETFILTER_XT_MATCH_DCCP=m +CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m +CONFIG_NETFILTER_XT_MATCH_DSCP=m +CONFIG_NETFILTER_XT_MATCH_ESP=m +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_IPRANGE=m +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_OSF=m +CONFIG_NETFILTER_XT_MATCH_OWNER=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +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 +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_OPTS=m +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_L2TP=m +CONFIG_L2TP_V3=y +CONFIG_L2TP_IP=m +CONFIG_L2TP_ETH=m +CONFIG_BRIDGE=m +CONFIG_VLAN_8021Q=m +CONFIG_NET_SCHED=y +CONFIG_CAN=y +CONFIG_BT=m +CONFIG_BT_HCIBTUSB=m +CONFIG_CFG80211=m +CONFIG_NL80211_TESTMODE=y +CONFIG_CFG80211_WEXT=y +CONFIG_MAC80211=m +CONFIG_RFKILL=y +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_CONNECTOR=y +CONFIG_MTD=y +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_BLOCK=y +CONFIG_MTD_CFI=y +CONFIG_MTD_CFI_AMDSTD=y +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_OF=y +CONFIG_MTD_RAW_NAND=y +CONFIG_MTD_NAND_PL35X=y +CONFIG_MTD_UBI=y +CONFIG_MTD_UBI_GLUEBI=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=16384 +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_NETDEVICES=y +CONFIG_TUN=y +CONFIG_MACB=y +# CONFIG_NET_VENDOR_CIRRUS is not set +# CONFIG_NET_VENDOR_FARADAY is not set +# CONFIG_NET_VENDOR_HISILICON is not set +# CONFIG_NET_VENDOR_MARVELL is not set +# CONFIG_NET_VENDOR_MICREL is not set +# CONFIG_NET_VENDOR_MICROCHIP is not set +# CONFIG_NET_VENDOR_NATSEMI is not set +# 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_NET_VENDOR_STMICRO is not set +# CONFIG_NET_VENDOR_WIZNET is not set +# CONFIG_NET_VENDOR_XILINX is not set +CONFIG_MARVELL_PHY=y +CONFIG_MICREL_PHY=y +CONFIG_SMSC_PHY=y +CONFIG_VITESSE_PHY=y +CONFIG_MDIO_BITBANG=y +CONFIG_PPP=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m +CONFIG_USB_NET_DRIVERS=m +CONFIG_USB_RTL8152=m +CONFIG_USB_USBNET=m +CONFIG_USB_NET_CDC_EEM=m +CONFIG_USB_NET_SMSC75XX=m +CONFIG_USB_NET_SMSC95XX=m +CONFIG_USB_NET_PLUSB=m +CONFIG_USB_NET_RNDIS_HOST=m +CONFIG_USB_IPHETH=m +CONFIG_ATH9K=m +CONFIG_RT2X00=m +CONFIG_RT2500USB=m +CONFIG_RT73USB=m +CONFIG_RT2800USB=m +CONFIG_RT2800USB_RT53XX=y +CONFIG_RT2800USB_RT55XX=y +CONFIG_RT2800USB_UNKNOWN=y +CONFIG_RTL8192CU=m +CONFIG_WL12XX=m +CONFIG_WLCORE_SDIO=m +CONFIG_INPUT_SPARSEKMAP=y +CONFIG_INPUT_EVDEV=y +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_OF_PLATFORM=y +CONFIG_SERIAL_XILINX_PS_UART=y +CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y +# CONFIG_HW_RANDOM is not set +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_ZYNQ=y +CONFIG_MEDIA_SUPPORT=y +CONFIG_MEDIA_CAMERA_SUPPORT=y +CONFIG_MEDIA_USB_SUPPORT=y +CONFIG_USB_VIDEO_CLASS=m +CONFIG_FB=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_HID_MICROSOFT=m +CONFIG_USB_HID=m +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_UDC=y +CONFIG_USB_CHIPIDEA_HOST=y +CONFIG_USB_SERIAL=m +CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +CONFIG_USB_SERIAL_CP210X=m +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_PL2303=m +CONFIG_NOP_USB_XCEIV=y +CONFIG_USB_ULPI=y +CONFIG_USB_GADGET=y +CONFIG_USB_ETH=y +# CONFIG_USB_ETH_RNDIS is not set +CONFIG_USB_ETH_EEM=y +CONFIG_MMC=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_PLTFM=y +CONFIG_MMC_SDHCI_OF_ARASAN=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_DNOTIFY is not set +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_UBIFS_FS=y +CONFIG_SQUASHFS=m +CONFIG_SQUASHFS_XATTR=y +CONFIG_NFS_FS=y +CONFIG_ROOT_NFS=y +CONFIG_CIFS=y +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_ASCII=y +CONFIG_NLS_ISO8859_1=y +CONFIG_SECURITY=y +CONFIG_SECURITY_NETWORK=y +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_PRINTK_TIME=y +CONFIG_DYNAMIC_DEBUG=y +CONFIG_FRAME_WARN=1024 +CONFIG_MAGIC_SYSRQ=y +CONFIG_RCU_CPU_STALL_TIMEOUT=60 From b2587969bc00b8cbffe21530a60ca5da36b7e661 Mon Sep 17 00:00:00 2001 From: Chaitanya Vadrevu Date: Thu, 6 Mar 2025 17:55:45 -0600 Subject: [PATCH 098/100] nati_bluefin_defconfig: defconfig for NI Bluefin targets [cvadrevu: squash all defconfig commits accumulated up to 6.6.77-rt50 and regenerate for 6.12.16-rt9] Signed-off-by: Chaitanya Vadrevu [gratian: squash all defconfig commits accumulated up to 6.12.74-rt16 and regenerate for 6.18.13-rt4] Signed-off-by: Gratian Crisan --- arch/arm/configs/nati_bluefin_defconfig | 211 ++++++++++++++++++++++++ 1 file changed, 211 insertions(+) create mode 100644 arch/arm/configs/nati_bluefin_defconfig diff --git a/arch/arm/configs/nati_bluefin_defconfig b/arch/arm/configs/nati_bluefin_defconfig new file mode 100644 index 0000000000000..5ab4320d36ebb --- /dev/null +++ b/arch/arm/configs/nati_bluefin_defconfig @@ -0,0 +1,211 @@ +CONFIG_LOCALVERSION="-ni" +CONFIG_SYSVIPC=y +CONFIG_AUDIT=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_CGROUPS=y +CONFIG_CPUSETS=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSFS_SYSCALL=y +CONFIG_PERF_EVENTS=y +CONFIG_ARCH_ZYNQ=y +CONFIG_ARM_ERRATA_754322=y +CONFIG_ARM_ERRATA_764369=y +CONFIG_ARM_ERRATA_775420=y +CONFIG_SMP=y +CONFIG_HIGHMEM=y +CONFIG_CMDLINE="console=ttyPS0,115200n8 root=/dev/ram rw initrd=0x00800000,16M earlyprintk mtdparts=physmap-flash.0:512K(nor-fsbl),512K(nor-u-boot),5M(nor-linux),9M(nor-user),1M(nor-scratch),-(nor-rootfs)" +CONFIG_VFP=y +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_COMPACTION is not set +CONFIG_CMA=y +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_MULTIPATH=y +CONFIG_IP_ROUTE_VERBOSE=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_RARP=y +CONFIG_IP_MROUTE=y +CONFIG_IP_MROUTE_MULTIPLE_TABLES=y +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y +# CONFIG_IPV6_SIT is not set +CONFIG_NETFILTER=y +CONFIG_BRIDGE_NETFILTER=y +CONFIG_NETFILTER_XT_MARK=y +CONFIG_IP_NF_IPTABLES=y +CONFIG_BRIDGE_NF_EBTABLES=y +CONFIG_BRIDGE_EBT_MARK_T=y +CONFIG_BRIDGE=y +CONFIG_BRIDGE_VLAN_FILTERING=y +CONFIG_NET_DSA=y +CONFIG_VLAN_8021Q=y +CONFIG_NET_SCHED=y +CONFIG_UEVENT_HELPER=y +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_CONNECTOR=y +CONFIG_MTD=y +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_BLOCK=y +CONFIG_MTD_CFI=y +CONFIG_MTD_CFI_AMDSTD=y +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_OF=y +CONFIG_MTD_RAW_NAND=y +CONFIG_MTD_NAND_PL35X=y +CONFIG_MTD_UBI=y +CONFIG_MTD_UBI_GLUEBI=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=16384 +CONFIG_SRAM=y +CONFIG_EEPROM_AT24=y +CONFIG_EEPROM_AT25=y +CONFIG_SCSI=y +CONFIG_BLK_DEV_SD=y +CONFIG_CHR_DEV_SG=y +# CONFIG_BLK_DEV_BSG is not set +CONFIG_NETDEVICES=y +CONFIG_BONDING=y +CONFIG_TUN=y +CONFIG_NET_DSA_MV88E6XXX=y +CONFIG_NET_DSA_MV88E6XXX_PTP=y +CONFIG_MACB=y +# CONFIG_NET_VENDOR_CIRRUS is not set +# CONFIG_NET_VENDOR_FARADAY is not set +# CONFIG_NET_VENDOR_HISILICON is not set +# CONFIG_NET_VENDOR_MARVELL is not set +# CONFIG_NET_VENDOR_MICREL is not set +# CONFIG_NET_VENDOR_MICROCHIP is not set +# CONFIG_NET_VENDOR_NATSEMI is not set +# 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_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 +CONFIG_VITESSE_PHY=y +CONFIG_MDIO_BITBANG=y +CONFIG_INPUT_SPARSEKMAP=y +CONFIG_INPUT_EVDEV=y +CONFIG_KEYBOARD_GPIO=y +# CONFIG_INPUT_MOUSE 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_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_ZYNQ=y +CONFIG_POWER_RESET=y +CONFIG_POWER_RESET_GPIO_RESTART=y +CONFIG_POWER_SUPPLY=y +CONFIG_SENSORS_LM90=y +CONFIG_WATCHDOG=y +CONFIG_WATCHDOG_NOWAYOUT=y +CONFIG_CADENCE_WATCHDOG=y +CONFIG_FB=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_USB=y +CONFIG_USB_DYNAMIC_MINORS=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_STORAGE=y +CONFIG_USB_CHIPIDEA=y +CONFIG_USB_CHIPIDEA_HOST=y +CONFIG_NOP_USB_XCEIV=y +CONFIG_USB_ULPI=y +CONFIG_MMC=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_TRIGGERS=y +CONFIG_LEDS_TRIGGER_TIMER=y +CONFIG_LEDS_TRIGGER_ONESHOT=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_LEDS_TRIGGER_DEFAULT_ON=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_SI5351=y +CONFIG_COMMON_CLK_SI570=y +CONFIG_ARM_GT_INITIAL_PRESCALER_VAL=2 +CONFIG_MEMORY=y +CONFIG_OVERLAY_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_UBIFS_FS=y +CONFIG_SQUASHFS=y +CONFIG_SQUASHFS_XATTR=y +CONFIG_SQUASHFS_LZ4=y +CONFIG_SQUASHFS_LZO=y +CONFIG_SQUASHFS_XZ=y +CONFIG_NFS_FS=y +CONFIG_ROOT_NFS=y +CONFIG_CIFS=y +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_ASCII=y +CONFIG_NLS_ISO8859_1=y +CONFIG_SECURITY=y +CONFIG_SECURITY_NETWORK=y +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_SHA1=y +CONFIG_CRYPTO_SHA256=y +CONFIG_CRYPTO_SHA512=y +CONFIG_CRYPTO_ANSI_CPRNG=y +CONFIG_CRYPTO_AES_ARM=y +CONFIG_FONTS=y +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +CONFIG_PRINTK_TIME=y +CONFIG_DYNAMIC_DEBUG=y +CONFIG_FRAME_WARN=1024 +CONFIG_MAGIC_SYSRQ=y +CONFIG_RCU_CPU_STALL_TIMEOUT=60 From 8a092c5de254ec542a2e6cda28995902087d63e9 Mon Sep 17 00:00:00 2001 From: Sien Date: Wed, 1 Jun 2016 10:02:20 -0500 Subject: [PATCH 099/100] nati_slsc_defconfig: defconfig for NI SLSC targets [gratian: squash all defconfig commits accumulated up to 6.12.74-rt16 and regenerate for 6.18.13-rt4] Signed-off-by: Gratian Crisan --- arch/arm/configs/nati_slsc_defconfig | 225 +++++++++++++++++++++++++++ 1 file changed, 225 insertions(+) create mode 100644 arch/arm/configs/nati_slsc_defconfig diff --git a/arch/arm/configs/nati_slsc_defconfig b/arch/arm/configs/nati_slsc_defconfig new file mode 100644 index 0000000000000..34d474f347025 --- /dev/null +++ b/arch/arm/configs/nati_slsc_defconfig @@ -0,0 +1,225 @@ +CONFIG_LOCALVERSION="-ni" +CONFIG_SYSVIPC=y +CONFIG_AUDIT=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_CGROUPS=y +CONFIG_CPUSETS=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSFS_SYSCALL=y +CONFIG_PERF_EVENTS=y +CONFIG_ARCH_ZYNQ=y +CONFIG_ARM_ERRATA_754322=y +CONFIG_ARM_ERRATA_764369=y +CONFIG_ARM_ERRATA_775420=y +CONFIG_SMP=y +CONFIG_HIGHMEM=y +CONFIG_CMDLINE="console=ttyPS0,115200n8 root=/dev/ram rw initrd=0x00800000,16M earlyprintk mtdparts=physmap-flash.0:512K(nor-fsbl),512K(nor-u-boot),5M(nor-linux),9M(nor-user),1M(nor-scratch),-(nor-rootfs)" +CONFIG_VFP=y +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_COMPACTION is not set +CONFIG_CMA=y +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_INET=y +# CONFIG_IPV6_SIT is not set +CONFIG_L2TP=m +CONFIG_L2TP_V3=y +CONFIG_L2TP_IP=m +CONFIG_L2TP_ETH=m +CONFIG_BRIDGE=m +CONFIG_VLAN_8021Q=m +CONFIG_NET_SCHED=y +CONFIG_CAN=y +CONFIG_BT=m +CONFIG_BT_HCIBTUSB=m +CONFIG_CFG80211=m +CONFIG_NL80211_TESTMODE=y +CONFIG_CFG80211_WEXT=y +CONFIG_MAC80211=m +CONFIG_RFKILL=y +CONFIG_DEVTMPFS=y +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 +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_OF=y +CONFIG_MTD_SPI_NOR=y +CONFIG_MTD_UBI=y +CONFIG_MTD_UBI_GLUEBI=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=16384 +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_NETDEVICES=y +CONFIG_TUN=y +CONFIG_MACB=y +# CONFIG_NET_VENDOR_CIRRUS is not set +# CONFIG_NET_VENDOR_FARADAY is not set +# CONFIG_NET_VENDOR_HISILICON is not set +# CONFIG_NET_VENDOR_MARVELL is not set +# CONFIG_NET_VENDOR_MICREL is not set +# CONFIG_NET_VENDOR_MICROCHIP is not set +# CONFIG_NET_VENDOR_NATSEMI is not set +# 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_NET_VENDOR_STMICRO is not set +# CONFIG_NET_VENDOR_WIZNET is not set +# CONFIG_NET_VENDOR_XILINX is not set +CONFIG_MARVELL_PHY=y +CONFIG_MICREL_PHY=y +CONFIG_SMSC_PHY=y +CONFIG_VITESSE_PHY=y +CONFIG_MDIO_BITBANG=y +CONFIG_PPP=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m +CONFIG_USB_NET_DRIVERS=m +CONFIG_USB_RTL8152=m +CONFIG_USB_USBNET=m +CONFIG_USB_NET_CDC_EEM=m +CONFIG_USB_NET_SMSC75XX=m +CONFIG_USB_NET_SMSC95XX=m +CONFIG_USB_NET_PLUSB=m +CONFIG_USB_NET_RNDIS_HOST=m +CONFIG_USB_IPHETH=m +CONFIG_ATH9K=m +CONFIG_ATH6KL=m +CONFIG_ATH6KL_SDIO=m +CONFIG_RT2X00=m +CONFIG_RT2500USB=m +CONFIG_RT73USB=m +CONFIG_RT2800USB=m +CONFIG_RT2800USB_RT53XX=y +CONFIG_RT2800USB_RT55XX=y +CONFIG_RT2800USB_UNKNOWN=y +CONFIG_RTL8192CU=m +CONFIG_WL12XX=m +CONFIG_WLCORE_SDIO=m +CONFIG_INPUT_SPARSEKMAP=y +CONFIG_INPUT_EVDEV=y +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_OF_PLATFORM=y +CONFIG_SERIAL_XILINX_PS_UART=y +CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y +# CONFIG_HW_RANDOM is not set +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_ZYNQ=y +CONFIG_WATCHDOG=y +CONFIG_CADENCE_WATCHDOG=y +CONFIG_MEDIA_SUPPORT=y +CONFIG_MEDIA_CAMERA_SUPPORT=y +CONFIG_FB=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_HID_MICROSOFT=m +CONFIG_USB_HID=m +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_UDC=y +CONFIG_USB_CHIPIDEA_HOST=y +CONFIG_USB_SERIAL=m +CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +CONFIG_USB_SERIAL_CP210X=m +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_PL2303=m +CONFIG_NOP_USB_XCEIV=y +CONFIG_USB_ULPI=y +CONFIG_USB_GADGET=y +CONFIG_USB_ETH=y +# CONFIG_USB_ETH_RNDIS is not set +CONFIG_USB_ETH_EEM=y +CONFIG_MMC=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_PLTFM=y +CONFIG_MMC_SDHCI_OF_ARASAN=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_PCF8563=y +CONFIG_RTC_DRV_DS3232=y +CONFIG_DMADEVICES=y +CONFIG_PL330_DMA=y +CONFIG_UIO=y +CONFIG_UIO_PDRV_GENIRQ=y +CONFIG_COMMON_CLK_SI570=y +CONFIG_ARM_GT_INITIAL_PRESCALER_VAL=2 +CONFIG_MEMORY=y +CONFIG_IIO=y +CONFIG_AD7291=y +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_SECURITY=y +CONFIG_EXT4_FS=y +# CONFIG_DNOTIFY is not set +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_UBIFS_FS=y +CONFIG_SQUASHFS=y +CONFIG_SQUASHFS_XATTR=y +CONFIG_SQUASHFS_LZO=y +CONFIG_SQUASHFS_XZ=y +CONFIG_NFS_FS=y +CONFIG_CIFS=y +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_ASCII=y +CONFIG_NLS_ISO8859_1=y +CONFIG_SECURITY=y +CONFIG_SECURITY_NETWORK=y +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_PRINTK_TIME=y +CONFIG_DYNAMIC_DEBUG=y +CONFIG_FRAME_WARN=1024 +CONFIG_MAGIC_SYSRQ=y +CONFIG_RCU_CPU_STALL_TIMEOUT=60 From a4b99046499e0075322f8d3567bac8e77a8aae43 Mon Sep 17 00:00:00 2001 From: Gratian Crisan Date: Tue, 19 May 2015 19:24:43 -0500 Subject: [PATCH 100/100] nati_x86_64_defconfig: defconfig for NI x86_64-based targets [gratian: squash all defconfig commits accumulated up to 6.0.19-rt14 and regenerate for 6.1.12-rt7] Signed-off-by: Gratian Crisan [mpeterse: squash all defconfig commits accumulated up to 6.1.54-rt15 and regenerate for 6.6-rc6-rt10] Signed-off-by: Mike Petersen [cvadrevu: squash all defconfig commits accumulated up to 6.6.77-rt50 and regenerate for 6.12.16-rt9] Signed-off-by: Chaitanya Vadrevu [gratian: squash all defconfig commits accumulated up to 6.12.74-rt16 and regenerate for 6.18.13-rt4] Signed-off-by: Gratian Crisan --- arch/x86/configs/nati_x86_64_defconfig | 611 +++++++++++++++++++++++++ 1 file changed, 611 insertions(+) create mode 100644 arch/x86/configs/nati_x86_64_defconfig diff --git a/arch/x86/configs/nati_x86_64_defconfig b/arch/x86/configs/nati_x86_64_defconfig new file mode 100644 index 0000000000000..985bfccafc8c4 --- /dev/null +++ b/arch/x86/configs/nati_x86_64_defconfig @@ -0,0 +1,611 @@ +CONFIG_KERNEL_XZ=y +CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y +CONFIG_AUDIT=y +# CONFIG_CONTEXT_TRACKING_USER_FORCE is not set +CONFIG_HIGH_RES_TIMERS=y +# CONFIG_CLOCKSOURCE_WATCHDOG is not set +CONFIG_BPF_SYSCALL=y +CONFIG_BPF_JIT=y +CONFIG_PREEMPT_RT=y +CONFIG_VIRT_CPU_ACCOUNTING_GEN=y +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_RCU_NOCB_CPU_CB_BOOST is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=18 +CONFIG_CGROUPS=y +CONFIG_CGROUP_FAVOR_DYNMODS=y +CONFIG_MEMCG=y +CONFIG_CGROUP_SCHED=y +CONFIG_CGROUP_FREEZER=y +CONFIG_CPUSETS=y +CONFIG_CPUSETS_V1=y +# CONFIG_PROC_PID_CPUSET is not set +CONFIG_CGROUP_DEVICE=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_CGROUP_BPF=y +CONFIG_NAMESPACES=y +# CONFIG_TIME_NS is not set +CONFIG_USER_NS=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_EXPERT=y +# CONFIG_PCSPKR_PLATFORM is not set +CONFIG_KALLSYMS_ALL=y +CONFIG_SMP=y +# CONFIG_X86_EXTENDED_PLATFORM is not set +CONFIG_X86_INTEL_LPSS=y +# CONFIG_SCHED_OMIT_FRAME_POINTER is not set +CONFIG_HYPERVISOR_GUEST=y +CONFIG_PROCESSOR_SELECT=y +# CONFIG_CPU_SUP_CENTAUR is not set +CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS=y +CONFIG_X86_MSR=m +CONFIG_X86_CPUID=m +CONFIG_NUMA=y +# CONFIG_AMD_NUMA is not set +CONFIG_MTRR_SANITIZER_ENABLE_DEFAULT=1 +CONFIG_EFI=y +CONFIG_EFI_STUB=y +CONFIG_HZ_100=y +# CONFIG_MODIFY_LDT_SYSCALL is not set +# CONFIG_SUSPEND is not set +# CONFIG_ACPI_AC is not set +# CONFIG_ACPI_BATTERY is not set +CONFIG_ACPI_BUTTON=m +# CONFIG_ACPI_FAN is not set +# CONFIG_ACPI_THERMAL is not set +# CONFIG_ACPI_DEBUG is not set +CONFIG_ACPI_APEI=y +CONFIG_ACPI_APEI_GHES=y +CONFIG_ACPI_APEI_MEMORY_FAILURE=y +CONFIG_INTEL_IDLE=y +CONFIG_IA32_EMULATION=y +# CONFIG_VIRTUALIZATION is not set +# CONFIG_SCHED_MC is not set +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODVERSIONS=y +CONFIG_BLK_DEV_INTEGRITY=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +# CONFIG_SLUB_CPU_PARTIAL is not set +# CONFIG_COMPAT_BRK is not set +CONFIG_MEMORY_HOTPLUG=y +CONFIG_MEMORY_HOTREMOVE=y +CONFIG_KSM=y +CONFIG_DEFAULT_MMAP_MIN_ADDR=65536 +CONFIG_MEMORY_FAILURE=y +CONFIG_ZONE_DEVICE=y +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_TLS=m +CONFIG_TLS_DEVICE=y +CONFIG_XFRM_USER=m +CONFIG_NET_KEY=m +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_MULTIPATH=y +CONFIG_IP_ROUTE_VERBOSE=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_RARP=y +CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE_DEMUX=m +CONFIG_NET_IPGRE=m +CONFIG_NET_IPGRE_BROADCAST=y +CONFIG_IP_MROUTE=y +CONFIG_IP_MROUTE_MULTIPLE_TABLES=y +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y +CONFIG_INET_AH=m +CONFIG_INET_ESP=m +CONFIG_INET_ESP_OFFLOAD=m +CONFIG_INET_IPCOMP=m +CONFIG_INET_DIAG=m +CONFIG_IPV6=m +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_ESP_OFFLOAD=m +CONFIG_INET6_IPCOMP=m +CONFIG_IPV6_MULTIPLE_TABLES=y +CONFIG_NETFILTER=y +CONFIG_BRIDGE_NETFILTER=m +CONFIG_NF_CONNTRACK=m +CONFIG_NF_CONNTRACK_SECMARK=y +CONFIG_NF_CONNTRACK_ZONES=y +CONFIG_NF_CONNTRACK_EVENTS=y +CONFIG_NF_CONNTRACK_TIMEOUT=y +CONFIG_NF_CONNTRACK_TIMESTAMP=y +CONFIG_NF_CONNTRACK_LABELS=y +CONFIG_NF_CONNTRACK_AMANDA=m +CONFIG_NF_CONNTRACK_FTP=m +CONFIG_NF_CONNTRACK_H323=m +CONFIG_NF_CONNTRACK_IRC=m +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_SNMP=m +CONFIG_NF_CONNTRACK_PPTP=m +CONFIG_NF_CONNTRACK_SANE=m +CONFIG_NF_CONNTRACK_SIP=m +CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NF_CT_NETLINK=m +CONFIG_NF_CT_NETLINK_TIMEOUT=m +CONFIG_NF_TABLES=m +CONFIG_NF_TABLES_INET=y +CONFIG_NF_TABLES_NETDEV=y +CONFIG_NFT_NUMGEN=m +CONFIG_NFT_CT=m +CONFIG_NFT_CONNLIMIT=m +CONFIG_NFT_LOG=m +CONFIG_NFT_LIMIT=m +CONFIG_NFT_MASQ=m +CONFIG_NFT_REDIR=m +CONFIG_NFT_NAT=m +CONFIG_NFT_TUNNEL=m +CONFIG_NFT_QUEUE=m +CONFIG_NFT_QUOTA=m +CONFIG_NFT_REJECT=m +CONFIG_NFT_COMPAT=m +CONFIG_NFT_HASH=m +CONFIG_NFT_FIB_INET=m +CONFIG_NFT_XFRM=m +CONFIG_NFT_SOCKET=m +CONFIG_NFT_OSF=m +CONFIG_NFT_TPROXY=m +CONFIG_NFT_SYNPROXY=m +CONFIG_NFT_DUP_NETDEV=m +CONFIG_NFT_FWD_NETDEV=m +CONFIG_NFT_FIB_NETDEV=m +CONFIG_NFT_REJECT_NETDEV=m +CONFIG_NF_FLOW_TABLE_INET=m +CONFIG_NF_FLOW_TABLE=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +CONFIG_NETFILTER_XT_TARGET_CONNMARK=m +CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_HL=m +CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m +CONFIG_NETFILTER_XT_TARGET_LOG=m +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_NAT=m +CONFIG_NETFILTER_XT_TARGET_NETMAP=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_REDIRECT=m +CONFIG_NETFILTER_XT_TARGET_MASQUERADE=m +CONFIG_NETFILTER_XT_TARGET_TEE=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m +CONFIG_NETFILTER_XT_MATCH_CLUSTER=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m +CONFIG_NETFILTER_XT_MATCH_CONNMARK=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_CPU=m +CONFIG_NETFILTER_XT_MATCH_DCCP=m +CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m +CONFIG_NETFILTER_XT_MATCH_DSCP=m +CONFIG_NETFILTER_XT_MATCH_ESP=m +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_IPRANGE=m +CONFIG_NETFILTER_XT_MATCH_IPVS=m +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_OSF=m +CONFIG_NETFILTER_XT_MATCH_OWNER=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +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_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_IP_VS=m +CONFIG_NFT_DUP_IPV4=m +CONFIG_NFT_FIB_IPV4=m +CONFIG_NF_TABLES_ARP=y +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_ARP_MANGLE=m +CONFIG_NFT_DUP_IPV6=m +CONFIG_NFT_FIB_IPV6=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_OPTS=m +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_IP6_NF_TARGET_REJECT=m +CONFIG_IP_SCTP=m +CONFIG_SCTP_DBG_OBJCNT=y +CONFIG_L2TP=m +CONFIG_L2TP_DEBUGFS=m +CONFIG_L2TP_V3=y +CONFIG_L2TP_IP=m +CONFIG_L2TP_ETH=m +CONFIG_BRIDGE=m +CONFIG_VLAN_8021Q=m +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_MULTIQ=m +CONFIG_NET_SCH_NETEM=m +CONFIG_NET_CLS_BASIC=m +CONFIG_NET_CLS_U32=m +CONFIG_NET_EMATCH=y +CONFIG_NET_EMATCH_CMP=m +CONFIG_NET_CLS_ACT=y +CONFIG_NET_ACT_SKBEDIT=m +CONFIG_DCB=y +CONFIG_DNS_RESOLVER=y +CONFIG_BT=m +CONFIG_BT_HCIBTUSB=m +CONFIG_CFG80211=m +CONFIG_NL80211_TESTMODE=y +CONFIG_CFG80211_WEXT=y +CONFIG_MAC80211=m +CONFIG_MAC80211_LEDS=y +CONFIG_RFKILL=y +CONFIG_PCI=y +CONFIG_PCI_MSI=y +CONFIG_PCI_IOV=y +CONFIG_PCI_P2PDMA=y +CONFIG_HOTPLUG_PCI_ACPI=y +CONFIG_UEVENT_HELPER=y +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_CONNECTOR=y +CONFIG_EDD=y +CONFIG_EDD_OFF=y +CONFIG_DMI_SYSFS=m +# CONFIG_EFI_DISABLE_RUNTIME is not set +CONFIG_MTD=m +CONFIG_MTD_SPI_NOR=m +CONFIG_MTD_UBI=m +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_RAM=y +CONFIG_VIRTIO_BLK=m +CONFIG_BLK_DEV_NVME=y +CONFIG_NVME_RDMA=m +CONFIG_NI_RT_FEATURES=y +CONFIG_NI_LED_PREFIX="nilrt" +CONFIG_NI_WATCHDOG=y +CONFIG_BLK_DEV_SD=y +CONFIG_BLK_DEV_SR=y +CONFIG_SCSI_SAS_ATA=y +CONFIG_SCSI_AACRAID=m +CONFIG_SCSI_MVSAS=m +CONFIG_SCSI_ARCMSR=m +CONFIG_SCSI_SYM53C8XX_2=m +CONFIG_SCSI_VIRTIO=m +CONFIG_ATA=y +CONFIG_SATA_AHCI=y +CONFIG_ATA_PIIX=y +CONFIG_SATA_MV=m +CONFIG_SATA_SIL=m +CONFIG_MD=y +CONFIG_BLK_DEV_DM=y +CONFIG_DM_CRYPT=y +CONFIG_DM_RAID=m +CONFIG_FIREWIRE=m +CONFIG_FIREWIRE_OHCI=m +CONFIG_FIREWIRE_SBP2=m +CONFIG_FIREWIRE_NET=m +CONFIG_NETDEVICES=y +CONFIG_BONDING=m +CONFIG_WIREGUARD=m +CONFIG_NETCONSOLE=m +CONFIG_NETCONSOLE_DYNAMIC=y +CONFIG_TUN=y +CONFIG_VETH=m +CONFIG_VIRTIO_NET=m +CONFIG_NLMON=m +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_NET_VENDOR_ADAPTEC is not set +# CONFIG_NET_VENDOR_ALTEON is not set +# CONFIG_NET_VENDOR_AMD is not set +# CONFIG_NET_VENDOR_ATHEROS is not set +CONFIG_TIGON3=m +# CONFIG_NET_VENDOR_CHELSIO is not set +# CONFIG_NET_VENDOR_CISCO is not set +CONFIG_NET_TULIP=y +CONFIG_TULIP=m +# CONFIG_NET_VENDOR_DLINK is not set +# CONFIG_NET_VENDOR_EMULEX is not set +# CONFIG_NET_VENDOR_I825XX is not set +CONFIG_E100=m +CONFIG_E1000=m +CONFIG_E1000E=m +CONFIG_IGB=m +CONFIG_IGBVF=m +CONFIG_IXGBE=m +# CONFIG_IXGBE_HWMON is not set +CONFIG_I40E=m +CONFIG_IGC=m +# CONFIG_NET_VENDOR_MARVELL is not set +CONFIG_MLX5_CORE=m +CONFIG_MLX5_CORE_EN=y +CONFIG_MLX5_EN_IPSEC=y +CONFIG_MLX5_EN_TLS=y +# CONFIG_NET_VENDOR_MICREL is not set +# CONFIG_NET_VENDOR_MICROCHIP is not set +# CONFIG_NET_VENDOR_MYRI is not set +# CONFIG_NET_VENDOR_NATSEMI is not set +# CONFIG_NET_VENDOR_NVIDIA is not set +# CONFIG_NET_VENDOR_OKI is not set +# CONFIG_NET_VENDOR_QLOGIC is not set +# CONFIG_NET_VENDOR_BROCADE is not set +# CONFIG_NET_VENDOR_RDC is not set +# CONFIG_NET_VENDOR_REALTEK is not set +# CONFIG_NET_VENDOR_SEEQ is not set +# CONFIG_NET_VENDOR_SILAN is not set +# CONFIG_NET_VENDOR_SIS is not set +# CONFIG_NET_VENDOR_SMSC is not set +# CONFIG_NET_VENDOR_STMICRO is not set +# CONFIG_NET_VENDOR_SUN is not set +# CONFIG_NET_VENDOR_TEHUTI is not set +# CONFIG_NET_VENDOR_TI is not set +# CONFIG_NET_VENDOR_VIA is not set +# CONFIG_NET_VENDOR_WIZNET is not set +CONFIG_PHYLIB=y +CONFIG_MICROCHIP_PHY=m +CONFIG_PPP=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=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 +CONFIG_USB_NET_SMSC75XX=m +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_CARL9170=m +CONFIG_ATH6KL=m +CONFIG_ATH6KL_SDIO=m +CONFIG_ATH6KL_USB=m +CONFIG_ATH6KL_NI_BIOS_DOMAIN=y +CONFIG_ATH6KL_SILEX_FIRMWARE=y +CONFIG_AR5523=m +CONFIG_AT76C50X_USB=m +CONFIG_MT7601U=m +CONFIG_RT2X00=m +CONFIG_RT2500USB=m +CONFIG_RT73USB=m +CONFIG_RT2800USB=m +CONFIG_RT2800USB_RT53XX=y +CONFIG_RT2800USB_RT55XX=y +CONFIG_RT2800USB_UNKNOWN=y +CONFIG_RTL8187=m +CONFIG_RTL8192CU=m +CONFIG_ZD1211RW=m +CONFIG_HYPERV_NET=y +CONFIG_INPUT_MOUSEDEV=m +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_EVDEV=y +CONFIG_KEYBOARD_ATKBD=m +CONFIG_MOUSE_PS2=m +CONFIG_INPUT_TABLET=y +CONFIG_TABLET_SERIAL_WACOM4=m +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_USB_COMPOSITE=m +CONFIG_SERIO=m +# CONFIG_LEGACY_PTYS is not set +# CONFIG_LEGACY_TIOCSTI is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=32 +CONFIG_SERIAL_8250_RUNTIME_UARTS=0 +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_SERIAL_8250_DETECT_IRQ=y +CONFIG_SERIAL_8250_RSA=y +CONFIG_SERIAL_8250_DW=y +# CONFIG_SERIAL_8250_PERICOM is not set +CONFIG_SERIAL_8250_NI=y +CONFIG_VIRTIO_CONSOLE=m +# CONFIG_HW_RANDOM_AMD is not set +# CONFIG_HW_RANDOM_VIA is not set +CONFIG_HW_RANDOM_VIRTIO=m +CONFIG_HPET=y +CONFIG_TCG_TPM=y +CONFIG_TCG_TIS=y +CONFIG_TCG_CRB=y +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=m +CONFIG_I2C_I801=m +CONFIG_I2C_DESIGNWARE_CORE=m +CONFIG_I2C_DESIGNWARE_PCI=m +CONFIG_SPI=y +CONFIG_SPI_PXA2XX=m +CONFIG_SPI_SPIDEV=m +CONFIG_PINCTRL_BAYTRAIL=y +CONFIG_PINCTRL_BROXTON=y +CONFIG_SENSORS_CORETEMP=m +CONFIG_SENSORS_TMP421=m +CONFIG_THERMAL_GOV_USER_SPACE=y +CONFIG_WATCHDOG=y +CONFIG_WATCHDOG_CORE=y +CONFIG_SOFT_WATCHDOG=m +CONFIG_NIC7018_WDT=m +CONFIG_LPC_ICH=m +CONFIG_MEDIA_SUPPORT=m +CONFIG_MEDIA_SUBDRV_AUTOSELECT=y +CONFIG_MEDIA_USB_SUPPORT=y +CONFIG_USB_VIDEO_CLASS=m +CONFIG_AGP=m +CONFIG_DRM=m +CONFIG_DRM_RADEON=m +CONFIG_DRM_I915=m +CONFIG_DRM_VMWGFX=m +CONFIG_DRM_VIRTIO_GPU=m +CONFIG_DRM_BOCHS=m +CONFIG_FB=y +CONFIG_FB_EFI=y +CONFIG_FB_MODE_HELPERS=y +CONFIG_LCD_CLASS_DEVICE=m +CONFIG_HIDRAW=y +CONFIG_HID_MICROSOFT=m +CONFIG_HID_MULTITOUCH=m +CONFIG_HID_PENMOUNT=m +CONFIG_USB_HIDDEV=y +CONFIG_USB=y +CONFIG_USB_DYNAMIC_MINORS=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_XHCI_PLATFORM=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_UHCI_HCD=y +CONFIG_USB_STORAGE=y +CONFIG_USB_DWC3=m +CONFIG_USB_DWC3_GADGET=y +CONFIG_USB_SERIAL=m +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_USB_SERIAL_QUALCOMM=m +CONFIG_USB_SERIAL_SIERRAWIRELESS=m +CONFIG_NOP_USB_XCEIV=m +CONFIG_USB_GADGET=m +CONFIG_USB_ETH=m +# CONFIG_USB_ETH_RNDIS is not set +CONFIG_USB_ETH_EEM=y +CONFIG_MMC=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_PCI=y +CONFIG_MMC_SDHCI_ACPI=y +CONFIG_LEDS_CLASS=y +CONFIG_LEDS_NIC78BX=m +CONFIG_INFINIBAND=m +CONFIG_INFINIBAND_USER_ACCESS=m +CONFIG_MLX5_INFINIBAND=m +CONFIG_RTC_CLASS=y +CONFIG_DMADEVICES=y +CONFIG_UIO=m +CONFIG_UIO_PCI_GENERIC=m +CONFIG_VIRTIO_PCI=m +CONFIG_VIRTIO_BALLOON=m +CONFIG_VIRTIO_INPUT=m +CONFIG_VIRTIO_MMIO=m +CONFIG_HYPERV=y +CONFIG_HYPERV_UTILS=y +CONFIG_HYPERV_BALLOON=y +CONFIG_INTEL_IOMMU=y +# CONFIG_INTEL_IOMMU_DEFAULT_ON is not set +CONFIG_IRQ_REMAP=y +CONFIG_NTB=y +CONFIG_NTB_SWITCHTEC=y +CONFIG_USB4=m +CONFIG_DAX=y +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=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_CUSE=m +CONFIG_OVERLAY_FS=y +CONFIG_ISO9660_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_NTFS3_FS=m +CONFIG_NTFS3_LZX_XPRESS=y +CONFIG_NTFS3_FS_POSIX_ACL=y +CONFIG_PROC_KCORE=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_HUGETLBFS=y +CONFIG_CONFIGFS_FS=y +CONFIG_EFIVAR_FS=y +CONFIG_UBIFS_FS=m +CONFIG_SQUASHFS=y +CONFIG_SQUASHFS_XATTR=y +CONFIG_NFS_FS=m +CONFIG_NFS_V2=m +CONFIG_NFS_V4=m +CONFIG_NFS_V4_1=y +CONFIG_CIFS=m +CONFIG_CIFS_XATTR=y +CONFIG_CIFS_POSIX=y +CONFIG_CIFS_DFS_UPCALL=y +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_ASCII=y +CONFIG_NLS_ISO8859_1=y +CONFIG_NLS_UTF8=y +CONFIG_SECURITY=y +CONFIG_SECURITY_NETWORK=y +CONFIG_SECURITY_SELINUX=y +CONFIG_SECURITY_SELINUX_BOOTPARAM=y +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_CRYPTO_NULL=y +CONFIG_CRYPTO_PCRYPT=m +CONFIG_CRYPTO_CRYPTD=y +CONFIG_CRYPTO_AES=y +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_LRW=y +CONFIG_CRYPTO_XTS=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_SHA1=y +CONFIG_CRYPTO_SHA256=y +CONFIG_CRYPTO_CRC32C=y +CONFIG_CRYPTO_USER_API_SKCIPHER=m +CONFIG_CRYPTO_AES_NI_INTEL=m +CONFIG_PRINTK_TIME=y +CONFIG_FRAME_WARN=1024 +CONFIG_MAGIC_SYSRQ=y +CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x0 +CONFIG_DEBUG_FS=y +# CONFIG_SLUB_DEBUG is not set +CONFIG_PANIC_ON_OOPS=y +CONFIG_PANIC_TIMEOUT=30 +CONFIG_RCU_CPU_STALL_TIMEOUT=60 +# CONFIG_RCU_TRACE is not set +CONFIG_FUNCTION_TRACER=y +CONFIG_FUNCTION_GRAPH_RETVAL=y +CONFIG_FUNCTION_PROFILER=y +CONFIG_FTRACE_SYSCALLS=y +CONFIG_TRACER_SNAPSHOT=y +CONFIG_TRACER_SNAPSHOT_PER_CPU_SWAP=y +# CONFIG_STRICT_DEVMEM is not set +# CONFIG_X86_VERBOSE_BOOTUP is not set +# CONFIG_EARLY_PRINTK is not set +CONFIG_IO_DELAY_0XED=y +CONFIG_UNWINDER_GUESS=y