1/*
2 * platform_msic.c: MSIC platform data initilization file
3 *
4 * (C) Copyright 2013 Intel Corporation
5 * Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; version 2
10 * of the License.
11 */
12
13#include <linux/kernel.h>
14#include <linux/interrupt.h>
15#include <linux/scatterlist.h>
16#include <linux/init.h>
17#include <linux/sfi.h>
18#include <linux/mfd/intel_msic.h>
19#include <asm/intel_scu_ipc.h>
20#include <asm/intel-mid.h>
21#include "platform_msic.h"
22
23struct intel_msic_platform_data msic_pdata;
24
25static struct resource msic_resources[] = {
26	{
27		.start	= INTEL_MSIC_IRQ_PHYS_BASE,
28		.end	= INTEL_MSIC_IRQ_PHYS_BASE + 64 - 1,
29		.flags	= IORESOURCE_MEM,
30	},
31};
32
33static struct platform_device msic_device = {
34	.name		= "intel_msic",
35	.id		= -1,
36	.dev		= {
37		.platform_data	= &msic_pdata,
38	},
39	.num_resources	= ARRAY_SIZE(msic_resources),
40	.resource	= msic_resources,
41};
42
43static int msic_scu_status_change(struct notifier_block *nb,
44				  unsigned long code, void *data)
45{
46	if (code == SCU_DOWN) {
47		platform_device_unregister(&msic_device);
48		return 0;
49	}
50
51	return platform_device_register(&msic_device);
52}
53
54static int __init msic_init(void)
55{
56	static struct notifier_block msic_scu_notifier = {
57		.notifier_call	= msic_scu_status_change,
58	};
59
60	/*
61	 * We need to be sure that the SCU IPC is ready before MSIC device
62	 * can be registered.
63	 */
64	if (intel_mid_has_msic())
65		intel_scu_notifier_add(&msic_scu_notifier);
66
67	return 0;
68}
69arch_initcall(msic_init);
70
71/*
72 * msic_generic_platform_data - sets generic platform data for the block
73 * @info: pointer to the SFI device table entry for this block
74 * @block: MSIC block
75 *
76 * Function sets IRQ number from the SFI table entry for given device to
77 * the MSIC platform data.
78 */
79void *msic_generic_platform_data(void *info, enum intel_msic_block block)
80{
81	struct sfi_device_table_entry *entry = info;
82
83	BUG_ON(block < 0 || block >= INTEL_MSIC_BLOCK_LAST);
84	msic_pdata.irq[block] = entry->irq;
85
86	return NULL;
87}
88