diff options
| author | Hanjun Guo <hanjun.guo@linaro.org> | 2015-03-24 10:02:48 -0400 |
|---|---|---|
| committer | Will Deacon <will.deacon@arm.com> | 2015-03-26 11:13:07 -0400 |
| commit | fbe61ec71ac975279cd47b6c299d5e33f63aac4e (patch) | |
| tree | 1a0b6128e7901e1b0fb8639c1347cff4a2cac4cf /arch | |
| parent | 020295b4cb5b7d510ea1f4531a502c3f8a2380c5 (diff) | |
ARM64 / ACPI: Introduce ACPI_IRQ_MODEL_GIC and register device's gsi
Introduce ACPI_IRQ_MODEL_GIC which is needed for ARM64 as GIC is
used, and then register device's gsi with the core IRQ subsystem.
acpi_register_gsi() is similar to DT based irq_of_parse_and_map(),
since gsi is unique in the system, so use hwirq number directly
for the mapping.
We are going to implement stacked domains when GICv2m, GICv3, ITS
support are added.
CC: Marc Zyngier <marc.zyngier@arm.com>
Originally-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
Tested-by: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>
Tested-by: Yijing Wang <wangyijing@huawei.com>
Tested-by: Mark Langsdorf <mlangsdo@redhat.com>
Tested-by: Jon Masters <jcm@redhat.com>
Tested-by: Timur Tabi <timur@codeaurora.org>
Tested-by: Robert Richter <rrichter@cavium.com>
Acked-by: Robert Richter <rrichter@cavium.com>
Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Reviewed-by: Grant Likely <grant.likely@linaro.org>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
Signed-off-by: Will Deacon <will.deacon@arm.com>
Diffstat (limited to 'arch')
| -rw-r--r-- | arch/arm64/kernel/acpi.c | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c index c9203c0a1179..dec6f8aed3dc 100644 --- a/arch/arm64/kernel/acpi.c +++ b/arch/arm64/kernel/acpi.c | |||
| @@ -76,6 +76,12 @@ static int __init dt_scan_depth1_nodes(unsigned long node, | |||
| 76 | } | 76 | } |
| 77 | 77 | ||
| 78 | /* | 78 | /* |
| 79 | * Since we're on ARM, the default interrupt routing model | ||
| 80 | * clearly has to be GIC. | ||
| 81 | */ | ||
| 82 | enum acpi_irq_model_id acpi_irq_model = ACPI_IRQ_MODEL_GIC; | ||
| 83 | |||
| 84 | /* | ||
| 79 | * __acpi_map_table() will be called before page_init(), so early_ioremap() | 85 | * __acpi_map_table() will be called before page_init(), so early_ioremap() |
| 80 | * or early_memremap() should be called here to for ACPI table mapping. | 86 | * or early_memremap() should be called here to for ACPI table mapping. |
| 81 | */ | 87 | */ |
| @@ -218,6 +224,73 @@ void __init acpi_init_cpus(void) | |||
| 218 | pr_info("%d CPUs enabled, %d CPUs total\n", enabled_cpus, total_cpus); | 224 | pr_info("%d CPUs enabled, %d CPUs total\n", enabled_cpus, total_cpus); |
| 219 | } | 225 | } |
| 220 | 226 | ||
| 227 | int acpi_gsi_to_irq(u32 gsi, unsigned int *irq) | ||
| 228 | { | ||
| 229 | *irq = irq_find_mapping(NULL, gsi); | ||
| 230 | |||
| 231 | return 0; | ||
| 232 | } | ||
| 233 | EXPORT_SYMBOL_GPL(acpi_gsi_to_irq); | ||
| 234 | |||
| 235 | /* | ||
| 236 | * success: return IRQ number (>0) | ||
| 237 | * failure: return =< 0 | ||
| 238 | */ | ||
| 239 | int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity) | ||
| 240 | { | ||
| 241 | unsigned int irq; | ||
| 242 | unsigned int irq_type; | ||
| 243 | |||
| 244 | /* | ||
| 245 | * ACPI have no bindings to indicate SPI or PPI, so we | ||
| 246 | * use different mappings from DT in ACPI. | ||
| 247 | * | ||
| 248 | * For FDT | ||
| 249 | * PPI interrupt: in the range [0, 15]; | ||
| 250 | * SPI interrupt: in the range [0, 987]; | ||
| 251 | * | ||
| 252 | * For ACPI, GSI should be unique so using | ||
| 253 | * the hwirq directly for the mapping: | ||
| 254 | * PPI interrupt: in the range [16, 31]; | ||
| 255 | * SPI interrupt: in the range [32, 1019]; | ||
| 256 | */ | ||
| 257 | |||
| 258 | if (trigger == ACPI_EDGE_SENSITIVE && | ||
| 259 | polarity == ACPI_ACTIVE_LOW) | ||
| 260 | irq_type = IRQ_TYPE_EDGE_FALLING; | ||
| 261 | else if (trigger == ACPI_EDGE_SENSITIVE && | ||
| 262 | polarity == ACPI_ACTIVE_HIGH) | ||
| 263 | irq_type = IRQ_TYPE_EDGE_RISING; | ||
| 264 | else if (trigger == ACPI_LEVEL_SENSITIVE && | ||
| 265 | polarity == ACPI_ACTIVE_LOW) | ||
| 266 | irq_type = IRQ_TYPE_LEVEL_LOW; | ||
| 267 | else if (trigger == ACPI_LEVEL_SENSITIVE && | ||
| 268 | polarity == ACPI_ACTIVE_HIGH) | ||
| 269 | irq_type = IRQ_TYPE_LEVEL_HIGH; | ||
| 270 | else | ||
| 271 | irq_type = IRQ_TYPE_NONE; | ||
| 272 | |||
| 273 | /* | ||
| 274 | * Since only one GIC is supported in ACPI 5.0, we can | ||
| 275 | * create mapping refer to the default domain | ||
| 276 | */ | ||
| 277 | irq = irq_create_mapping(NULL, gsi); | ||
| 278 | if (!irq) | ||
| 279 | return irq; | ||
| 280 | |||
| 281 | /* Set irq type if specified and different than the current one */ | ||
| 282 | if (irq_type != IRQ_TYPE_NONE && | ||
| 283 | irq_type != irq_get_trigger_type(irq)) | ||
| 284 | irq_set_irq_type(irq, irq_type); | ||
| 285 | return irq; | ||
| 286 | } | ||
| 287 | EXPORT_SYMBOL_GPL(acpi_register_gsi); | ||
| 288 | |||
| 289 | void acpi_unregister_gsi(u32 gsi) | ||
| 290 | { | ||
| 291 | } | ||
| 292 | EXPORT_SYMBOL_GPL(acpi_unregister_gsi); | ||
| 293 | |||
| 221 | static int __init acpi_parse_fadt(struct acpi_table_header *table) | 294 | static int __init acpi_parse_fadt(struct acpi_table_header *table) |
| 222 | { | 295 | { |
| 223 | struct acpi_table_fadt *fadt = (struct acpi_table_fadt *)table; | 296 | struct acpi_table_fadt *fadt = (struct acpi_table_fadt *)table; |
