165cd577dSPetr Stehlik /* 265cd577dSPetr Stehlik * natfeat.c - ARAnyM hardware support via Native Features (natfeats) 365cd577dSPetr Stehlik * 465cd577dSPetr Stehlik * Copyright (c) 2005 Petr Stehlik of ARAnyM dev team 565cd577dSPetr Stehlik * 665cd577dSPetr Stehlik * Reworked for Linux by Roman Zippel <zippel@linux-m68k.org> 765cd577dSPetr Stehlik * 865cd577dSPetr Stehlik * This software may be used and distributed according to the terms of 965cd577dSPetr Stehlik * the GNU General Public License (GPL), incorporated herein by reference. 1065cd577dSPetr Stehlik */ 1165cd577dSPetr Stehlik 1265cd577dSPetr Stehlik #include <linux/types.h> 1365cd577dSPetr Stehlik #include <linux/console.h> 1465cd577dSPetr Stehlik #include <linux/string.h> 1565cd577dSPetr Stehlik #include <linux/kernel.h> 1665cd577dSPetr Stehlik #include <linux/module.h> 1765cd577dSPetr Stehlik #include <linux/io.h> 1865cd577dSPetr Stehlik #include <asm/machdep.h> 1965cd577dSPetr Stehlik #include <asm/natfeat.h> 2065cd577dSPetr Stehlik 2155490050SGeert Uytterhoeven extern long nf_get_id_phys(unsigned long feature_name); 22e8184e10SGeert Uytterhoeven 2365cd577dSPetr Stehlik asm("\n" 2455490050SGeert Uytterhoeven " .global nf_get_id_phys,nf_call\n" 2555490050SGeert Uytterhoeven "nf_get_id_phys:\n" 2665cd577dSPetr Stehlik " .short 0x7300\n" 2765cd577dSPetr Stehlik " rts\n" 2865cd577dSPetr Stehlik "nf_call:\n" 2965cd577dSPetr Stehlik " .short 0x7301\n" 3065cd577dSPetr Stehlik " rts\n" 3165cd577dSPetr Stehlik "1: moveq.l #0,%d0\n" 3265cd577dSPetr Stehlik " rts\n" 3365cd577dSPetr Stehlik " .section __ex_table,\"a\"\n" 3455490050SGeert Uytterhoeven " .long nf_get_id_phys,1b\n" 3565cd577dSPetr Stehlik " .long nf_call,1b\n" 3665cd577dSPetr Stehlik " .previous"); 3765cd577dSPetr Stehlik EXPORT_SYMBOL_GPL(nf_call); 3865cd577dSPetr Stehlik 39e8184e10SGeert Uytterhoeven long nf_get_id(const char *feature_name) 40e8184e10SGeert Uytterhoeven { 41e8184e10SGeert Uytterhoeven /* feature_name may be in vmalloc()ed memory, so make a copy */ 42e8184e10SGeert Uytterhoeven char name_copy[32]; 43e8184e10SGeert Uytterhoeven size_t n; 44e8184e10SGeert Uytterhoeven 45e8184e10SGeert Uytterhoeven n = strlcpy(name_copy, feature_name, sizeof(name_copy)); 46e8184e10SGeert Uytterhoeven if (n >= sizeof(name_copy)) 47e8184e10SGeert Uytterhoeven return 0; 48e8184e10SGeert Uytterhoeven 4955490050SGeert Uytterhoeven return nf_get_id_phys(virt_to_phys(name_copy)); 50e8184e10SGeert Uytterhoeven } 51e8184e10SGeert Uytterhoeven EXPORT_SYMBOL_GPL(nf_get_id); 52e8184e10SGeert Uytterhoeven 5365cd577dSPetr Stehlik void nfprint(const char *fmt, ...) 5465cd577dSPetr Stehlik { 5565cd577dSPetr Stehlik static char buf[256]; 5665cd577dSPetr Stehlik va_list ap; 5765cd577dSPetr Stehlik int n; 5865cd577dSPetr Stehlik 5965cd577dSPetr Stehlik va_start(ap, fmt); 6065cd577dSPetr Stehlik n = vsnprintf(buf, 256, fmt, ap); 6155490050SGeert Uytterhoeven nf_call(nf_get_id("NF_STDERR"), virt_to_phys(buf)); 6265cd577dSPetr Stehlik va_end(ap); 6365cd577dSPetr Stehlik } 6465cd577dSPetr Stehlik 6565cd577dSPetr Stehlik static void nf_poweroff(void) 6665cd577dSPetr Stehlik { 6765cd577dSPetr Stehlik long id = nf_get_id("NF_SHUTDOWN"); 6865cd577dSPetr Stehlik 6965cd577dSPetr Stehlik if (id) 7065cd577dSPetr Stehlik nf_call(id); 7165cd577dSPetr Stehlik } 7265cd577dSPetr Stehlik 7365cd577dSPetr Stehlik void nf_init(void) 7465cd577dSPetr Stehlik { 7565cd577dSPetr Stehlik unsigned long id, version; 7665cd577dSPetr Stehlik char buf[256]; 7765cd577dSPetr Stehlik 7865cd577dSPetr Stehlik id = nf_get_id("NF_VERSION"); 7965cd577dSPetr Stehlik if (!id) 8065cd577dSPetr Stehlik return; 8165cd577dSPetr Stehlik version = nf_call(id); 8265cd577dSPetr Stehlik 8365cd577dSPetr Stehlik id = nf_get_id("NF_NAME"); 8465cd577dSPetr Stehlik if (!id) 8565cd577dSPetr Stehlik return; 8655490050SGeert Uytterhoeven nf_call(id, virt_to_phys(buf), 256); 8765cd577dSPetr Stehlik buf[255] = 0; 8865cd577dSPetr Stehlik 8965cd577dSPetr Stehlik pr_info("NatFeats found (%s, %lu.%lu)\n", buf, version >> 16, 9065cd577dSPetr Stehlik version & 0xffff); 9165cd577dSPetr Stehlik 9265cd577dSPetr Stehlik mach_power_off = nf_poweroff; 9365cd577dSPetr Stehlik } 94