1 /* 2 * xen/arch/arm/platform.c 3 * 4 * Helpers to execute platform specific code. 5 * 6 * Julien Grall <julien.grall@linaro.org> 7 * Copyright (C) 2013 Linaro Limited. 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 2 of the License, or 12 * (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 */ 19 20 #include <asm/platform.h> 21 #include <xen/device_tree.h> 22 #include <xen/init.h> 23 #include <asm/psci.h> 24 25 extern const struct platform_desc _splatform[], _eplatform[]; 26 27 /* Pointer to the current platform description */ 28 static const struct platform_desc *platform; 29 30 platform_is_compatible(const struct platform_desc * plat)31static bool __init platform_is_compatible(const struct platform_desc *plat) 32 { 33 const char *const *compat; 34 35 if ( !plat->compatible ) 36 return false; 37 38 for ( compat = plat->compatible; *compat; compat++ ) 39 { 40 if ( dt_machine_is_compatible(*compat) ) 41 return true; 42 } 43 44 return false; 45 } 46 platform_init(void)47void __init platform_init(void) 48 { 49 int res = 0; 50 51 ASSERT(platform == NULL); 52 53 /* Looking for the platform description */ 54 for ( platform = _splatform; platform != _eplatform; platform++ ) 55 { 56 if ( platform_is_compatible(platform) ) 57 break; 58 } 59 60 /* We don't have specific operations for this platform */ 61 if ( platform == _eplatform ) 62 { 63 /* TODO: dump DT machine compatible node */ 64 printk(XENLOG_INFO "Platform: Generic System\n"); 65 platform = NULL; 66 } 67 else 68 printk(XENLOG_INFO "Platform: %s\n", platform->name); 69 70 if ( platform && platform->init ) 71 res = platform->init(); 72 73 if ( res ) 74 panic("Unable to initialize the platform"); 75 } 76 platform_init_time(void)77int __init platform_init_time(void) 78 { 79 int res = 0; 80 81 if ( platform && platform->init_time ) 82 res = platform->init_time(); 83 84 return res; 85 } 86 platform_specific_mapping(struct domain * d)87int __init platform_specific_mapping(struct domain *d) 88 { 89 int res = 0; 90 91 if ( platform && platform->specific_mapping ) 92 res = platform->specific_mapping(d); 93 94 return res; 95 } 96 97 #ifdef CONFIG_ARM_32 platform_cpu_up(int cpu)98int __init platform_cpu_up(int cpu) 99 { 100 if ( psci_ver ) 101 return call_psci_cpu_on(cpu); 102 103 if ( platform && platform->cpu_up ) 104 return platform->cpu_up(cpu); 105 106 return -ENODEV; 107 } 108 platform_smp_init(void)109int __init platform_smp_init(void) 110 { 111 if ( platform && platform->smp_init ) 112 return platform->smp_init(); 113 114 return 0; 115 } 116 #endif 117 platform_reset(void)118void platform_reset(void) 119 { 120 if ( platform && platform->reset ) 121 platform->reset(); 122 } 123 platform_poweroff(void)124void platform_poweroff(void) 125 { 126 if ( platform && platform->poweroff ) 127 platform->poweroff(); 128 } 129 platform_has_quirk(uint32_t quirk)130bool platform_has_quirk(uint32_t quirk) 131 { 132 uint32_t quirks = 0; 133 134 if ( platform && platform->quirks ) 135 quirks = platform->quirks(); 136 137 return (quirks & quirk); 138 } 139 platform_device_is_blacklisted(const struct dt_device_node * node)140bool platform_device_is_blacklisted(const struct dt_device_node *node) 141 { 142 const struct dt_device_match *blacklist = NULL; 143 144 if ( platform && platform->blacklist_dev ) 145 blacklist = platform->blacklist_dev; 146 147 return (dt_match_node(blacklist, node) != NULL); 148 } 149 150 /* 151 * Local variables: 152 * mode: C 153 * c-file-style: "BSD" 154 * c-basic-offset: 4 155 * indent-tabs-mode: nil 156 * End: 157 */ 158