root/drivers/platform/chrome/wilco_ec/core.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. wilco_get_resource
  2. wilco_ec_probe
  3. wilco_ec_remove

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * Core driver for Wilco Embedded Controller
   4  *
   5  * Copyright 2018 Google LLC
   6  *
   7  * This is the entry point for the drivers that control the Wilco EC.
   8  * This driver is responsible for several tasks:
   9  * - Initialize the register interface that is used by wilco_ec_mailbox()
  10  * - Create a platform device which is picked up by the debugfs driver
  11  * - Create a platform device which is picked up by the RTC driver
  12  */
  13 
  14 #include <linux/acpi.h>
  15 #include <linux/device.h>
  16 #include <linux/ioport.h>
  17 #include <linux/module.h>
  18 #include <linux/platform_data/wilco-ec.h>
  19 #include <linux/platform_device.h>
  20 
  21 #include "../cros_ec_lpc_mec.h"
  22 
  23 #define DRV_NAME "wilco-ec"
  24 
  25 static struct resource *wilco_get_resource(struct platform_device *pdev,
  26                                            int index)
  27 {
  28         struct device *dev = &pdev->dev;
  29         struct resource *res;
  30 
  31         res = platform_get_resource(pdev, IORESOURCE_IO, index);
  32         if (!res) {
  33                 dev_dbg(dev, "Couldn't find IO resource %d\n", index);
  34                 return res;
  35         }
  36 
  37         return devm_request_region(dev, res->start, resource_size(res),
  38                                    dev_name(dev));
  39 }
  40 
  41 static int wilco_ec_probe(struct platform_device *pdev)
  42 {
  43         struct device *dev = &pdev->dev;
  44         struct wilco_ec_device *ec;
  45         int ret;
  46 
  47         ec = devm_kzalloc(dev, sizeof(*ec), GFP_KERNEL);
  48         if (!ec)
  49                 return -ENOMEM;
  50 
  51         platform_set_drvdata(pdev, ec);
  52         ec->dev = dev;
  53         mutex_init(&ec->mailbox_lock);
  54 
  55         ec->data_size = sizeof(struct wilco_ec_response) + EC_MAILBOX_DATA_SIZE;
  56         ec->data_buffer = devm_kzalloc(dev, ec->data_size, GFP_KERNEL);
  57         if (!ec->data_buffer)
  58                 return -ENOMEM;
  59 
  60         /* Prepare access to IO regions provided by ACPI */
  61         ec->io_data = wilco_get_resource(pdev, 0);      /* Host Data */
  62         ec->io_command = wilco_get_resource(pdev, 1);   /* Host Command */
  63         ec->io_packet = wilco_get_resource(pdev, 2);    /* MEC EMI */
  64         if (!ec->io_data || !ec->io_command || !ec->io_packet)
  65                 return -ENODEV;
  66 
  67         /* Initialize cros_ec register interface for communication */
  68         cros_ec_lpc_mec_init(ec->io_packet->start,
  69                              ec->io_packet->start + EC_MAILBOX_DATA_SIZE);
  70 
  71         /*
  72          * Register a child device that will be found by the debugfs driver.
  73          * Ignore failure.
  74          */
  75         ec->debugfs_pdev = platform_device_register_data(dev,
  76                                                          "wilco-ec-debugfs",
  77                                                          PLATFORM_DEVID_AUTO,
  78                                                          NULL, 0);
  79 
  80         /* Register a child device that will be found by the RTC driver. */
  81         ec->rtc_pdev = platform_device_register_data(dev, "rtc-wilco-ec",
  82                                                      PLATFORM_DEVID_AUTO,
  83                                                      NULL, 0);
  84         if (IS_ERR(ec->rtc_pdev)) {
  85                 dev_err(dev, "Failed to create RTC platform device\n");
  86                 ret = PTR_ERR(ec->rtc_pdev);
  87                 goto unregister_debugfs;
  88         }
  89 
  90         ret = wilco_ec_add_sysfs(ec);
  91         if (ret < 0) {
  92                 dev_err(dev, "Failed to create sysfs entries: %d", ret);
  93                 goto unregister_rtc;
  94         }
  95 
  96         /* Register child device that will be found by the telemetry driver. */
  97         ec->telem_pdev = platform_device_register_data(dev, "wilco_telem",
  98                                                        PLATFORM_DEVID_AUTO,
  99                                                        ec, sizeof(*ec));
 100         if (IS_ERR(ec->telem_pdev)) {
 101                 dev_err(dev, "Failed to create telemetry platform device\n");
 102                 ret = PTR_ERR(ec->telem_pdev);
 103                 goto remove_sysfs;
 104         }
 105 
 106         return 0;
 107 
 108 remove_sysfs:
 109         wilco_ec_remove_sysfs(ec);
 110 unregister_rtc:
 111         platform_device_unregister(ec->rtc_pdev);
 112 unregister_debugfs:
 113         if (ec->debugfs_pdev)
 114                 platform_device_unregister(ec->debugfs_pdev);
 115         cros_ec_lpc_mec_destroy();
 116         return ret;
 117 }
 118 
 119 static int wilco_ec_remove(struct platform_device *pdev)
 120 {
 121         struct wilco_ec_device *ec = platform_get_drvdata(pdev);
 122 
 123         wilco_ec_remove_sysfs(ec);
 124         platform_device_unregister(ec->telem_pdev);
 125         platform_device_unregister(ec->rtc_pdev);
 126         if (ec->debugfs_pdev)
 127                 platform_device_unregister(ec->debugfs_pdev);
 128 
 129         /* Teardown cros_ec interface */
 130         cros_ec_lpc_mec_destroy();
 131 
 132         return 0;
 133 }
 134 
 135 static const struct acpi_device_id wilco_ec_acpi_device_ids[] = {
 136         { "GOOG000C", 0 },
 137         { }
 138 };
 139 MODULE_DEVICE_TABLE(acpi, wilco_ec_acpi_device_ids);
 140 
 141 static struct platform_driver wilco_ec_driver = {
 142         .driver = {
 143                 .name = DRV_NAME,
 144                 .acpi_match_table = wilco_ec_acpi_device_ids,
 145         },
 146         .probe = wilco_ec_probe,
 147         .remove = wilco_ec_remove,
 148 };
 149 
 150 module_platform_driver(wilco_ec_driver);
 151 
 152 MODULE_AUTHOR("Nick Crews <ncrews@chromium.org>");
 153 MODULE_AUTHOR("Duncan Laurie <dlaurie@chromium.org>");
 154 MODULE_LICENSE("GPL v2");
 155 MODULE_DESCRIPTION("ChromeOS Wilco Embedded Controller driver");
 156 MODULE_ALIAS("platform:" DRV_NAME);

/* [<][>][^][v][top][bottom][index][help] */