linux/arch/x86/platform/intel-mid/device_libs/platform_mrfld_power_btn.c
<<
>>
Prefs
   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
  22static struct resource mrfld_power_btn_resources[] = {
  23        {
  24                .flags          = IORESOURCE_IRQ,
  25        },
  26};
  27
  28static 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
  35static 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
  46static struct notifier_block mrfld_power_btn_scu_notifier = {
  47        .notifier_call  = mrfld_power_btn_scu_status_change,
  48};
  49
  50static 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}
  63arch_initcall(register_mrfld_power_btn);
  64
  65static 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
  74static 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
  82sfi_device(mrfld_power_btn_dev_id);
  83