| /* |
| * platform_msic.c: MSIC platform data initialization file |
| * |
| * (C) Copyright 2013 Intel Corporation |
| * Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com> |
| * |
| * This program is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU General Public License |
| * as published by the Free Software Foundation; version 2 |
| * of the License. |
| */ |
| |
| #include <linux/kernel.h> |
| #include <linux/interrupt.h> |
| #include <linux/scatterlist.h> |
| #include <linux/init.h> |
| #include <linux/sfi.h> |
| #include <linux/mfd/intel_msic.h> |
| #include <asm/intel_scu_ipc.h> |
| #include <asm/intel-mid.h> |
| #include "platform_msic.h" |
| |
| struct intel_msic_platform_data msic_pdata; |
| |
| static struct resource msic_resources[] = { |
| { |
| .start = INTEL_MSIC_IRQ_PHYS_BASE, |
| .end = INTEL_MSIC_IRQ_PHYS_BASE + 64 - 1, |
| .flags = IORESOURCE_MEM, |
| }, |
| }; |
| |
| static struct platform_device msic_device = { |
| .name = "intel_msic", |
| .id = -1, |
| .dev = { |
| .platform_data = &msic_pdata, |
| }, |
| .num_resources = ARRAY_SIZE(msic_resources), |
| .resource = msic_resources, |
| }; |
| |
| static int msic_scu_status_change(struct notifier_block *nb, |
| unsigned long code, void *data) |
| { |
| if (code == SCU_DOWN) { |
| platform_device_unregister(&msic_device); |
| return 0; |
| } |
| |
| return platform_device_register(&msic_device); |
| } |
| |
| static int __init msic_init(void) |
| { |
| static struct notifier_block msic_scu_notifier = { |
| .notifier_call = msic_scu_status_change, |
| }; |
| |
| /* |
| * We need to be sure that the SCU IPC is ready before MSIC device |
| * can be registered. |
| */ |
| if (intel_mid_has_msic()) |
| intel_scu_notifier_add(&msic_scu_notifier); |
| |
| return 0; |
| } |
| arch_initcall(msic_init); |
| |
| /* |
| * msic_generic_platform_data - sets generic platform data for the block |
| * @info: pointer to the SFI device table entry for this block |
| * @block: MSIC block |
| * |
| * Function sets IRQ number from the SFI table entry for given device to |
| * the MSIC platform data. |
| */ |
| void *msic_generic_platform_data(void *info, enum intel_msic_block block) |
| { |
| struct sfi_device_table_entry *entry = info; |
| |
| BUG_ON(block < 0 || block >= INTEL_MSIC_BLOCK_LAST); |
| msic_pdata.irq[block] = entry->irq; |
| |
| return NULL; |
| } |