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)31 static 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)47 void __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)77 int __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)87 int __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)98 int __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)109 int __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)118 void platform_reset(void)
119 {
120     if ( platform && platform->reset )
121         platform->reset();
122 }
123 
platform_poweroff(void)124 void platform_poweroff(void)
125 {
126     if ( platform && platform->poweroff )
127         platform->poweroff();
128 }
129 
platform_has_quirk(uint32_t quirk)130 bool 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)140 bool 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