1
2
3
4
5
6
7
8
9
10
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
62
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
73
74
75
76
77
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