162306a36Sopenharmony_ci/* 262306a36Sopenharmony_ci * natfeat.c - ARAnyM hardware support via Native Features (natfeats) 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * Copyright (c) 2005 Petr Stehlik of ARAnyM dev team 562306a36Sopenharmony_ci * 662306a36Sopenharmony_ci * Reworked for Linux by Roman Zippel <zippel@linux-m68k.org> 762306a36Sopenharmony_ci * 862306a36Sopenharmony_ci * This software may be used and distributed according to the terms of 962306a36Sopenharmony_ci * the GNU General Public License (GPL), incorporated herein by reference. 1062306a36Sopenharmony_ci */ 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci#include <linux/init.h> 1362306a36Sopenharmony_ci#include <linux/types.h> 1462306a36Sopenharmony_ci#include <linux/console.h> 1562306a36Sopenharmony_ci#include <linux/string.h> 1662306a36Sopenharmony_ci#include <linux/kernel.h> 1762306a36Sopenharmony_ci#include <linux/module.h> 1862306a36Sopenharmony_ci#include <linux/reboot.h> 1962306a36Sopenharmony_ci#include <linux/io.h> 2062306a36Sopenharmony_ci#include <asm/machdep.h> 2162306a36Sopenharmony_ci#include <asm/natfeat.h> 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_ciextern long nf_get_id_phys(unsigned long feature_name); 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ciasm("\n" 2662306a36Sopenharmony_ci" .global nf_get_id_phys,nf_call\n" 2762306a36Sopenharmony_ci"nf_get_id_phys:\n" 2862306a36Sopenharmony_ci" .short 0x7300\n" 2962306a36Sopenharmony_ci" rts\n" 3062306a36Sopenharmony_ci"nf_call:\n" 3162306a36Sopenharmony_ci" .short 0x7301\n" 3262306a36Sopenharmony_ci" rts\n" 3362306a36Sopenharmony_ci"1: moveq.l #0,%d0\n" 3462306a36Sopenharmony_ci" rts\n" 3562306a36Sopenharmony_ci" .section __ex_table,\"a\"\n" 3662306a36Sopenharmony_ci" .long nf_get_id_phys,1b\n" 3762306a36Sopenharmony_ci" .long nf_call,1b\n" 3862306a36Sopenharmony_ci" .previous"); 3962306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(nf_call); 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_cilong nf_get_id(const char *feature_name) 4262306a36Sopenharmony_ci{ 4362306a36Sopenharmony_ci /* feature_name may be in vmalloc()ed memory, so make a copy */ 4462306a36Sopenharmony_ci char name_copy[32]; 4562306a36Sopenharmony_ci size_t n; 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_ci n = strlcpy(name_copy, feature_name, sizeof(name_copy)); 4862306a36Sopenharmony_ci if (n >= sizeof(name_copy)) 4962306a36Sopenharmony_ci return 0; 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ci return nf_get_id_phys(virt_to_phys(name_copy)); 5262306a36Sopenharmony_ci} 5362306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(nf_get_id); 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_civoid nfprint(const char *fmt, ...) 5662306a36Sopenharmony_ci{ 5762306a36Sopenharmony_ci static char buf[256]; 5862306a36Sopenharmony_ci va_list ap; 5962306a36Sopenharmony_ci int n; 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci va_start(ap, fmt); 6262306a36Sopenharmony_ci n = vsnprintf(buf, 256, fmt, ap); 6362306a36Sopenharmony_ci nf_call(nf_get_id("NF_STDERR"), virt_to_phys(buf)); 6462306a36Sopenharmony_ci va_end(ap); 6562306a36Sopenharmony_ci} 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_cistatic void nf_poweroff(void) 6862306a36Sopenharmony_ci{ 6962306a36Sopenharmony_ci long id = nf_get_id("NF_SHUTDOWN"); 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_ci if (id) 7262306a36Sopenharmony_ci nf_call(id); 7362306a36Sopenharmony_ci} 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_civoid __init nf_init(void) 7662306a36Sopenharmony_ci{ 7762306a36Sopenharmony_ci unsigned long id, version; 7862306a36Sopenharmony_ci char buf[256]; 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_ci id = nf_get_id("NF_VERSION"); 8162306a36Sopenharmony_ci if (!id) 8262306a36Sopenharmony_ci return; 8362306a36Sopenharmony_ci version = nf_call(id); 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci id = nf_get_id("NF_NAME"); 8662306a36Sopenharmony_ci if (!id) 8762306a36Sopenharmony_ci return; 8862306a36Sopenharmony_ci nf_call(id, virt_to_phys(buf), 256); 8962306a36Sopenharmony_ci buf[255] = 0; 9062306a36Sopenharmony_ci 9162306a36Sopenharmony_ci pr_info("NatFeats found (%s, %lu.%lu)\n", buf, version >> 16, 9262306a36Sopenharmony_ci version & 0xffff); 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_ci register_platform_power_off(nf_poweroff); 9562306a36Sopenharmony_ci} 96