^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2018 Cadence Design Systems Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Author: Boris Brezillon <boris.brezillon@bootlin.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/atomic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/bug.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/completion.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "internals.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * i3c_device_do_priv_xfers() - do I3C SDR private transfers directed to a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * specific device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * @dev: device with which the transfers should be done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * @xfers: array of transfers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * @nxfers: number of transfers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * Initiate one or several private SDR transfers with @dev.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * This function can sleep and thus cannot be called in atomic context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * Return: 0 in case of success, a negative error core otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) int i3c_device_do_priv_xfers(struct i3c_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) struct i3c_priv_xfer *xfers,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) int nxfers)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) if (nxfers < 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) for (i = 0; i < nxfers; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) if (!xfers[i].len || !xfers[i].data.in)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) i3c_bus_normaluse_lock(dev->bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) ret = i3c_dev_do_priv_xfers_locked(dev->desc, xfers, nxfers);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) i3c_bus_normaluse_unlock(dev->bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) EXPORT_SYMBOL_GPL(i3c_device_do_priv_xfers);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * i3c_device_get_info() - get I3C device information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * @dev: device we want information on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * @info: the information object to fill in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * Retrieve I3C dev info.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) void i3c_device_get_info(struct i3c_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) struct i3c_device_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) if (!info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) i3c_bus_normaluse_lock(dev->bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) if (dev->desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) *info = dev->desc->info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) i3c_bus_normaluse_unlock(dev->bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) EXPORT_SYMBOL_GPL(i3c_device_get_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) * i3c_device_disable_ibi() - Disable IBIs coming from a specific device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) * @dev: device on which IBIs should be disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) * This function disable IBIs coming from a specific device and wait for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) * all pending IBIs to be processed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * Return: 0 in case of success, a negative error core otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) int i3c_device_disable_ibi(struct i3c_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) int ret = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) i3c_bus_normaluse_lock(dev->bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) if (dev->desc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) mutex_lock(&dev->desc->ibi_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) ret = i3c_dev_disable_ibi_locked(dev->desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) mutex_unlock(&dev->desc->ibi_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) i3c_bus_normaluse_unlock(dev->bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) EXPORT_SYMBOL_GPL(i3c_device_disable_ibi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) * i3c_device_enable_ibi() - Enable IBIs coming from a specific device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) * @dev: device on which IBIs should be enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) * This function enable IBIs coming from a specific device and wait for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) * all pending IBIs to be processed. This should be called on a device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * where i3c_device_request_ibi() has succeeded.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * Note that IBIs from this device might be received before this function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) * returns to its caller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) * Return: 0 in case of success, a negative error core otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) int i3c_device_enable_ibi(struct i3c_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) int ret = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) i3c_bus_normaluse_lock(dev->bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) if (dev->desc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) mutex_lock(&dev->desc->ibi_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) ret = i3c_dev_enable_ibi_locked(dev->desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) mutex_unlock(&dev->desc->ibi_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) i3c_bus_normaluse_unlock(dev->bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) EXPORT_SYMBOL_GPL(i3c_device_enable_ibi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) * i3c_device_request_ibi() - Request an IBI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) * @dev: device for which we should enable IBIs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) * @req: setup requested for this IBI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) * This function is responsible for pre-allocating all resources needed to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) * process IBIs coming from @dev. When this function returns, the IBI is not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) * enabled until i3c_device_enable_ibi() is called.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) * Return: 0 in case of success, a negative error core otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) int i3c_device_request_ibi(struct i3c_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) const struct i3c_ibi_setup *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) int ret = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) if (!req->handler || !req->num_slots)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) i3c_bus_normaluse_lock(dev->bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) if (dev->desc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) mutex_lock(&dev->desc->ibi_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) ret = i3c_dev_request_ibi_locked(dev->desc, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) mutex_unlock(&dev->desc->ibi_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) i3c_bus_normaluse_unlock(dev->bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) EXPORT_SYMBOL_GPL(i3c_device_request_ibi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) * i3c_device_free_ibi() - Free all resources needed for IBI handling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) * @dev: device on which you want to release IBI resources
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) * This function is responsible for de-allocating resources previously
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) * allocated by i3c_device_request_ibi(). It should be called after disabling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) * IBIs with i3c_device_disable_ibi().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) void i3c_device_free_ibi(struct i3c_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) i3c_bus_normaluse_lock(dev->bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) if (dev->desc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) mutex_lock(&dev->desc->ibi_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) i3c_dev_free_ibi_locked(dev->desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) mutex_unlock(&dev->desc->ibi_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) i3c_bus_normaluse_unlock(dev->bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) EXPORT_SYMBOL_GPL(i3c_device_free_ibi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) * i3cdev_to_dev() - Returns the device embedded in @i3cdev
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) * @i3cdev: I3C device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) * Return: a pointer to a device object.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) struct device *i3cdev_to_dev(struct i3c_device *i3cdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) return &i3cdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) EXPORT_SYMBOL_GPL(i3cdev_to_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) * dev_to_i3cdev() - Returns the I3C device containing @dev
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) * @dev: device object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) * Return: a pointer to an I3C device object.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) struct i3c_device *dev_to_i3cdev(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) return container_of(dev, struct i3c_device, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) EXPORT_SYMBOL_GPL(dev_to_i3cdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) * i3c_device_match_id() - Returns the i3c_device_id entry matching @i3cdev
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) * @i3cdev: I3C device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) * @id_table: I3C device match table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) * Return: a pointer to an i3c_device_id object or NULL if there's no match.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) const struct i3c_device_id *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) i3c_device_match_id(struct i3c_device *i3cdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) const struct i3c_device_id *id_table)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) struct i3c_device_info devinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) const struct i3c_device_id *id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) u16 manuf, part, ext_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) bool rndpid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) i3c_device_get_info(i3cdev, &devinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) manuf = I3C_PID_MANUF_ID(devinfo.pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) part = I3C_PID_PART_ID(devinfo.pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) ext_info = I3C_PID_EXTRA_INFO(devinfo.pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) rndpid = I3C_PID_RND_LOWER_32BITS(devinfo.pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) for (id = id_table; id->match_flags != 0; id++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) if ((id->match_flags & I3C_MATCH_DCR) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) id->dcr != devinfo.dcr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) if ((id->match_flags & I3C_MATCH_MANUF) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) id->manuf_id != manuf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) if ((id->match_flags & I3C_MATCH_PART) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) (rndpid || id->part_id != part))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) if ((id->match_flags & I3C_MATCH_EXTRA_INFO) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) (rndpid || id->extra_info != ext_info))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) return id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) EXPORT_SYMBOL_GPL(i3c_device_match_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) * i3c_driver_register_with_owner() - register an I3C device driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) * @drv: driver to register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) * @owner: module that owns this driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) * Register @drv to the core.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) * Return: 0 in case of success, a negative error core otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) int i3c_driver_register_with_owner(struct i3c_driver *drv, struct module *owner)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) drv->driver.owner = owner;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) drv->driver.bus = &i3c_bus_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) return driver_register(&drv->driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) EXPORT_SYMBOL_GPL(i3c_driver_register_with_owner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) * i3c_driver_unregister() - unregister an I3C device driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) * @drv: driver to unregister
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) * Unregister @drv.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) void i3c_driver_unregister(struct i3c_driver *drv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) driver_unregister(&drv->driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) EXPORT_SYMBOL_GPL(i3c_driver_unregister);