Merge remote-tracking branches 'asoc/topic/tegra', 'asoc/topic/tlv320aic23', 'asoc...
[sfrench/cifs-2.6.git] / arch / x86 / platform / intel-mid / device_libs / platform_mrfld_power_btn.c
1 /*
2  * Intel Merrifield power button support
3  *
4  * (C) Copyright 2017 Intel Corporation
5  *
6  * Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; version 2
11  * of the License.
12  */
13
14 #include <linux/init.h>
15 #include <linux/ioport.h>
16 #include <linux/platform_device.h>
17 #include <linux/sfi.h>
18
19 #include <asm/intel-mid.h>
20 #include <asm/intel_scu_ipc.h>
21
22 static struct resource mrfld_power_btn_resources[] = {
23         {
24                 .flags          = IORESOURCE_IRQ,
25         },
26 };
27
28 static struct platform_device mrfld_power_btn_dev = {
29         .name           = "msic_power_btn",
30         .id             = PLATFORM_DEVID_NONE,
31         .num_resources  = ARRAY_SIZE(mrfld_power_btn_resources),
32         .resource       = mrfld_power_btn_resources,
33 };
34
35 static int mrfld_power_btn_scu_status_change(struct notifier_block *nb,
36                                              unsigned long code, void *data)
37 {
38         if (code == SCU_DOWN) {
39                 platform_device_unregister(&mrfld_power_btn_dev);
40                 return 0;
41         }
42
43         return platform_device_register(&mrfld_power_btn_dev);
44 }
45
46 static struct notifier_block mrfld_power_btn_scu_notifier = {
47         .notifier_call  = mrfld_power_btn_scu_status_change,
48 };
49
50 static int __init register_mrfld_power_btn(void)
51 {
52         if (intel_mid_identify_cpu() != INTEL_MID_CPU_CHIP_TANGIER)
53                 return -ENODEV;
54
55         /*
56          * We need to be sure that the SCU IPC is ready before
57          * PMIC power button device can be registered:
58          */
59         intel_scu_notifier_add(&mrfld_power_btn_scu_notifier);
60
61         return 0;
62 }
63 arch_initcall(register_mrfld_power_btn);
64
65 static void __init *mrfld_power_btn_platform_data(void *info)
66 {
67         struct resource *res = mrfld_power_btn_resources;
68         struct sfi_device_table_entry *pentry = info;
69
70         res->start = res->end = pentry->irq;
71         return NULL;
72 }
73
74 static const struct devs_id mrfld_power_btn_dev_id __initconst = {
75         .name                   = "bcove_power_btn",
76         .type                   = SFI_DEV_TYPE_IPC,
77         .delay                  = 1,
78         .msic                   = 1,
79         .get_platform_data      = &mrfld_power_btn_platform_data,
80 };
81
82 sfi_device(mrfld_power_btn_dev_id);