/* * 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; } |