Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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) ==============================================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4) Intel(R) Management Engine (ME) Client bus API
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) ==============================================
^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) Rationale
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) =========
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) The MEI character device is useful for dedicated applications to send and receive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) data to the many FW appliance found in Intel's ME from the user space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) However, for some of the ME functionalities it makes sense to leverage existing software
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) stack and expose them through existing kernel subsystems.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) In order to plug seamlessly into the kernel device driver model we add kernel virtual
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) bus abstraction on top of the MEI driver. This allows implementing Linux kernel drivers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) for the various MEI features as a stand alone entities found in their respective subsystem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) Existing device drivers can even potentially be re-used by adding an MEI CL bus layer to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) the existing code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) MEI CL bus API
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) ==============
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) A driver implementation for an MEI Client is very similar to any other existing bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) based device drivers. The driver registers itself as an MEI CL bus driver through
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) the ``struct mei_cl_driver`` structure defined in :file:`include/linux/mei_cl_bus.c`
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) .. code-block:: C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32)         struct mei_cl_driver {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33)                 struct device_driver driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34)                 const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36)                 const struct mei_cl_device_id *id_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38)                 int (*probe)(struct mei_cl_device *dev, const struct mei_cl_id *id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39)                 int (*remove)(struct mei_cl_device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40)         };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) The mei_cl_device_id structure defined in :file:`include/linux/mod_devicetable.h` allows a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) driver to bind itself against a device name.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) .. code-block:: C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49)         struct mei_cl_device_id {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50)                 char name[MEI_CL_NAME_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51)                 uuid_le uuid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52)                 __u8    version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53)                 kernel_ulong_t driver_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54)         };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) To actually register a driver on the ME Client bus one must call the :c:func:`mei_cl_add_driver`
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) API. This is typically called at module initialization time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) Once the driver is registered and bound to the device, a driver will typically
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) try to do some I/O on this bus and this should be done through the :c:func:`mei_cl_send`
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) and :c:func:`mei_cl_recv` functions. More detailed information is in :ref:`api` section.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) In order for a driver to be notified about pending traffic or event, the driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) should register a callback via :c:func:`mei_cl_devev_register_rx_cb` and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) :c:func:`mei_cldev_register_notify_cb` function respectively.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) .. _api:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) API:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) ----
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) .. kernel-doc:: drivers/misc/mei/bus.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72)     :export: drivers/misc/mei/bus.c
^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) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) Example
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) =======
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) As a theoretical example let's pretend the ME comes with a "contact" NFC IP.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) The driver init and exit routines for this device would look like:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) .. code-block:: C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84)         #define CONTACT_DRIVER_NAME "contact"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86)         static struct mei_cl_device_id contact_mei_cl_tbl[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87)                 { CONTACT_DRIVER_NAME, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89)                 /* required last entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90)                 { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91)         };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92)         MODULE_DEVICE_TABLE(mei_cl, contact_mei_cl_tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94)         static struct mei_cl_driver contact_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95)                 .id_table = contact_mei_tbl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96)                 .name = CONTACT_DRIVER_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98)                 .probe = contact_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99)                 .remove = contact_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)         };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)         static int contact_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)         {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)                 int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)                 r = mei_cl_driver_register(&contact_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)                 if (r) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)                         pr_err(CONTACT_DRIVER_NAME ": driver registration failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)                         return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)                 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)                 return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)         static void __exit contact_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)         {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)                 mei_cl_driver_unregister(&contact_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)         module_init(contact_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)         module_exit(contact_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) And the driver's simplified probe routine would look like that:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) .. code-block:: C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)         int contact_probe(struct mei_cl_device *dev, struct mei_cl_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)         {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)                 [...]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)                 mei_cldev_enable(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)                 mei_cldev_register_rx_cb(dev, contact_rx_cb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)                 return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) In the probe routine the driver first enable the MEI device and then registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) an rx handler which is as close as it can get to registering a threaded IRQ handler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) The handler implementation will typically call :c:func:`mei_cldev_recv` and then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) process received data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) .. code-block:: C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)         #define MAX_PAYLOAD 128
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)         #define HDR_SIZE 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)         static void conntact_rx_cb(struct mei_cl_device *cldev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)         {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)                 struct contact *c = mei_cldev_get_drvdata(cldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)                 unsigned char payload[MAX_PAYLOAD];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)                 ssize_t payload_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)                 payload_sz = mei_cldev_recv(cldev, payload,  MAX_PAYLOAD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)                 if (reply_size < HDR_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)                         return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)                 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)                 c->process_rx(payload);
^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) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) MEI Client Bus Drivers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) ======================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) .. toctree::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)    :maxdepth: 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)    hdcp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)    nfc