This source file includes following definitions.
- wilco_get_resource
- wilco_ec_probe
- wilco_ec_remove
1
2
3
4
5
6
7
8
9
10
11
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
61 ec->io_data = wilco_get_resource(pdev, 0);
62 ec->io_command = wilco_get_resource(pdev, 1);
63 ec->io_packet = wilco_get_resource(pdev, 2);
64 if (!ec->io_data || !ec->io_command || !ec->io_packet)
65 return -ENODEV;
66
67
68 cros_ec_lpc_mec_init(ec->io_packet->start,
69 ec->io_packet->start + EC_MAILBOX_DATA_SIZE);
70
71
72
73
74
75 ec->debugfs_pdev = platform_device_register_data(dev,
76 "wilco-ec-debugfs",
77 PLATFORM_DEVID_AUTO,
78 NULL, 0);
79
80
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
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
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);