hc
2023-12-09 b22da3d8526a935aa31e086e63f60ff3246cb61c
kernel/drivers/i2c/i2c-core-acpi.c
....@@ -1,12 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Linux I2C core ACPI support code
34 *
45 * Copyright (C) 2014 Intel Corp, Author: Lan Tianyu <tianyu.lan@intel.com>
5
- *
6
- * This program is free software; you can redistribute it and/or modify it
7
- * under the terms of the GNU General Public License as published by the Free
8
- * Software Foundation; either version 2 of the License, or (at your option)
9
- * any later version.
106 */
117
128 #include <linux/acpi.h>
....@@ -46,6 +42,33 @@
4642 u32 force_speed;
4743 };
4844
45
+/**
46
+ * i2c_acpi_get_i2c_resource - Gets I2cSerialBus resource if type matches
47
+ * @ares: ACPI resource
48
+ * @i2c: Pointer to I2cSerialBus resource will be returned here
49
+ *
50
+ * Checks if the given ACPI resource is of type I2cSerialBus.
51
+ * In this case, returns a pointer to it to the caller.
52
+ *
53
+ * Returns true if resource type is of I2cSerialBus, otherwise false.
54
+ */
55
+bool i2c_acpi_get_i2c_resource(struct acpi_resource *ares,
56
+ struct acpi_resource_i2c_serialbus **i2c)
57
+{
58
+ struct acpi_resource_i2c_serialbus *sb;
59
+
60
+ if (ares->type != ACPI_RESOURCE_TYPE_SERIAL_BUS)
61
+ return false;
62
+
63
+ sb = &ares->data.i2c_serial_bus;
64
+ if (sb->type != ACPI_RESOURCE_SERIAL_TYPE_I2C)
65
+ return false;
66
+
67
+ *i2c = sb;
68
+ return true;
69
+}
70
+EXPORT_SYMBOL_GPL(i2c_acpi_get_i2c_resource);
71
+
4972 static int i2c_acpi_fill_info(struct acpi_resource *ares, void *data)
5073 {
5174 struct i2c_acpi_lookup *lookup = data;
....@@ -53,11 +76,7 @@
5376 struct acpi_resource_i2c_serialbus *sb;
5477 acpi_status status;
5578
56
- if (info->addr || ares->type != ACPI_RESOURCE_TYPE_SERIAL_BUS)
57
- return 1;
58
-
59
- sb = &ares->data.i2c_serial_bus;
60
- if (sb->type != ACPI_RESOURCE_SERIAL_TYPE_I2C)
79
+ if (info->addr || !i2c_acpi_get_i2c_resource(ares, &sb))
6180 return 1;
6281
6382 if (lookup->index != -1 && lookup->n++ != lookup->index)
....@@ -66,7 +85,7 @@
6685 status = acpi_get_handle(lookup->device_handle,
6786 sb->resource_source.string_ptr,
6887 &lookup->adapter_handle);
69
- if (!ACPI_SUCCESS(status))
88
+ if (ACPI_FAILURE(status))
7089 return 1;
7190
7291 info->addr = sb->slave_address;
....@@ -93,8 +112,7 @@
93112 struct list_head resource_list;
94113 int ret;
95114
96
- if (acpi_bus_get_status(adev) || !adev->status.present ||
97
- acpi_device_enumerated(adev))
115
+ if (acpi_bus_get_status(adev) || !adev->status.present)
98116 return -EINVAL;
99117
100118 if (acpi_match_device_ids(adev, i2c_acpi_ignored_device_ids) == 0)
....@@ -115,19 +133,61 @@
115133 return 0;
116134 }
117135
136
+static int i2c_acpi_add_resource(struct acpi_resource *ares, void *data)
137
+{
138
+ int *irq = data;
139
+ struct resource r;
140
+
141
+ if (*irq <= 0 && acpi_dev_resource_interrupt(ares, 0, &r))
142
+ *irq = i2c_dev_irq_from_resources(&r, 1);
143
+
144
+ return 1; /* No need to add resource to the list */
145
+}
146
+
147
+/**
148
+ * i2c_acpi_get_irq - get device IRQ number from ACPI
149
+ * @client: Pointer to the I2C client device
150
+ *
151
+ * Find the IRQ number used by a specific client device.
152
+ *
153
+ * Return: The IRQ number or an error code.
154
+ */
155
+int i2c_acpi_get_irq(struct i2c_client *client)
156
+{
157
+ struct acpi_device *adev = ACPI_COMPANION(&client->dev);
158
+ struct list_head resource_list;
159
+ int irq = -ENOENT;
160
+ int ret;
161
+
162
+ INIT_LIST_HEAD(&resource_list);
163
+
164
+ ret = acpi_dev_get_resources(adev, &resource_list,
165
+ i2c_acpi_add_resource, &irq);
166
+ if (ret < 0)
167
+ return ret;
168
+
169
+ acpi_dev_free_resource_list(&resource_list);
170
+
171
+ if (irq == -ENOENT)
172
+ irq = acpi_dev_gpio_irq_get(adev, 0);
173
+
174
+ return irq;
175
+}
176
+
118177 static int i2c_acpi_get_info(struct acpi_device *adev,
119178 struct i2c_board_info *info,
120179 struct i2c_adapter *adapter,
121180 acpi_handle *adapter_handle)
122181 {
123
- struct list_head resource_list;
124
- struct resource_entry *entry;
125182 struct i2c_acpi_lookup lookup;
126183 int ret;
127184
128185 memset(&lookup, 0, sizeof(lookup));
129186 lookup.info = info;
130187 lookup.index = -1;
188
+
189
+ if (acpi_device_enumerated(adev))
190
+ return -EINVAL;
131191
132192 ret = i2c_acpi_do_lookup(adev, &lookup);
133193 if (ret)
....@@ -152,21 +212,6 @@
152212 if (adapter_handle)
153213 *adapter_handle = lookup.adapter_handle;
154214
155
- /* Then fill IRQ number if any */
156
- INIT_LIST_HEAD(&resource_list);
157
- ret = acpi_dev_get_resources(adev, &resource_list, NULL, NULL);
158
- if (ret < 0)
159
- return -EINVAL;
160
-
161
- resource_list_for_each_entry(entry, &resource_list) {
162
- if (resource_type(entry->res) == IORESOURCE_IRQ) {
163
- info->irq = entry->res->start;
164
- break;
165
- }
166
- }
167
-
168
- acpi_dev_free_resource_list(&resource_list);
169
-
170215 acpi_set_modalias(adev, dev_name(&adev->dev), info->type,
171216 sizeof(info->type));
172217
....@@ -180,7 +225,7 @@
180225 adev->power.flags.ignore_parent = true;
181226 acpi_device_set_enumerated(adev);
182227
183
- if (!i2c_new_device(adapter, info)) {
228
+ if (IS_ERR(i2c_new_client_device(adapter, info))) {
184229 adev->power.flags.ignore_parent = false;
185230 dev_err(&adapter->dev,
186231 "failed to add I2C device %s from ACPI\n",
....@@ -241,16 +286,6 @@
241286 acpi_walk_dep_device_list(handle);
242287 }
243288
244
-const struct acpi_device_id *
245
-i2c_acpi_match_device(const struct acpi_device_id *matches,
246
- struct i2c_client *client)
247
-{
248
- if (!(client && matches))
249
- return NULL;
250
-
251
- return acpi_match_device(matches, &client->dev);
252
-}
253
-
254289 static const struct acpi_device_id i2c_acpi_force_400khz_device_ids[] = {
255290 /*
256291 * These Silead touchscreen controllers only work at 400KHz, for
....@@ -283,7 +318,7 @@
283318 lookup->min_speed = lookup->speed;
284319
285320 if (acpi_match_device_ids(adev, i2c_acpi_force_400khz_device_ids) == 0)
286
- lookup->force_speed = 400000;
321
+ lookup->force_speed = I2C_MAX_FAST_MODE_FREQ;
287322
288323 return AE_OK;
289324 }
....@@ -335,7 +370,7 @@
335370 }
336371 EXPORT_SYMBOL_GPL(i2c_acpi_find_bus_speed);
337372
338
-static int i2c_acpi_find_match_adapter(struct device *dev, void *data)
373
+static int i2c_acpi_find_match_adapter(struct device *dev, const void *data)
339374 {
340375 struct i2c_adapter *adapter = i2c_verify_adapter(dev);
341376
....@@ -345,27 +380,23 @@
345380 return ACPI_HANDLE(dev) == (acpi_handle)data;
346381 }
347382
348
-static int i2c_acpi_find_match_device(struct device *dev, void *data)
349
-{
350
- return ACPI_COMPANION(dev) == data;
351
-}
352
-
353
-static struct i2c_adapter *i2c_acpi_find_adapter_by_handle(acpi_handle handle)
383
+struct i2c_adapter *i2c_acpi_find_adapter_by_handle(acpi_handle handle)
354384 {
355385 struct device *dev;
356386
357387 dev = bus_find_device(&i2c_bus_type, NULL, handle,
358388 i2c_acpi_find_match_adapter);
389
+
359390 return dev ? i2c_verify_adapter(dev) : NULL;
360391 }
392
+EXPORT_SYMBOL_GPL(i2c_acpi_find_adapter_by_handle);
361393
362394 static struct i2c_client *i2c_acpi_find_client_by_adev(struct acpi_device *adev)
363395 {
364396 struct device *dev;
365397 struct i2c_client *client;
366398
367
- dev = bus_find_device(&i2c_bus_type, NULL, adev,
368
- i2c_acpi_find_match_device);
399
+ dev = bus_find_device_by_acpi_dev(&i2c_bus_type, adev);
369400 if (!dev)
370401 return NULL;
371402
....@@ -429,22 +460,20 @@
429460 * resources, in that case this function can be used to create an i2c-client
430461 * for other I2cSerialBus resources in the Current Resource Settings table.
431462 *
432
- * Also see i2c_new_device, which this function calls to create the i2c-client.
463
+ * Also see i2c_new_client_device, which this function calls to create the
464
+ * i2c-client.
433465 *
434
- * Returns a pointer to the new i2c-client, or NULL if the adapter is not found.
466
+ * Returns a pointer to the new i2c-client, or error pointer in case of failure.
467
+ * Specifically, -EPROBE_DEFER is returned if the adapter is not found.
435468 */
436469 struct i2c_client *i2c_acpi_new_device(struct device *dev, int index,
437470 struct i2c_board_info *info)
438471 {
472
+ struct acpi_device *adev = ACPI_COMPANION(dev);
439473 struct i2c_acpi_lookup lookup;
440474 struct i2c_adapter *adapter;
441
- struct acpi_device *adev;
442475 LIST_HEAD(resource_list);
443476 int ret;
444
-
445
- adev = ACPI_COMPANION(dev);
446
- if (!adev)
447
- return NULL;
448477
449478 memset(&lookup, 0, sizeof(lookup));
450479 lookup.info = info;
....@@ -453,16 +482,19 @@
453482
454483 ret = acpi_dev_get_resources(adev, &resource_list,
455484 i2c_acpi_fill_info, &lookup);
485
+ if (ret < 0)
486
+ return ERR_PTR(ret);
487
+
456488 acpi_dev_free_resource_list(&resource_list);
457489
458
- if (ret < 0 || !info->addr)
459
- return NULL;
490
+ if (!info->addr)
491
+ return ERR_PTR(-EADDRNOTAVAIL);
460492
461493 adapter = i2c_acpi_find_adapter_by_handle(lookup.adapter_handle);
462494 if (!adapter)
463
- return NULL;
495
+ return ERR_PTR(-EPROBE_DEFER);
464496
465
- return i2c_new_device(adapter, info);
497
+ return i2c_new_client_device(adapter, info);
466498 }
467499 EXPORT_SYMBOL_GPL(i2c_acpi_new_device);
468500
....@@ -570,13 +602,7 @@
570602 goto err;
571603 }
572604
573
- if (!value64 || ares->type != ACPI_RESOURCE_TYPE_SERIAL_BUS) {
574
- ret = AE_BAD_PARAMETER;
575
- goto err;
576
- }
577
-
578
- sb = &ares->data.i2c_serial_bus;
579
- if (sb->type != ACPI_RESOURCE_SERIAL_TYPE_I2C) {
605
+ if (!value64 || !i2c_acpi_get_i2c_resource(ares, &sb)) {
580606 ret = AE_BAD_PARAMETER;
581607 goto err;
582608 }