The Greybus specification defines the Vendor Specific bundle
class[1]. Using this class allows vendors to avoid defining a
custom generic class, simplifying driver development. Currently,
drivers can register to either match on a bundle class or a
Vendor & Product ID with `GREYBUS_CLASS` and `GREYBUS_DEVICE`
respectively.
However, when matching to a vendor specific driver, the current
implementation does not check the bundle's class. This has the
effect of matching the vendor specific driver to ANY bundle found
in the device's manifest, regardless of its class. This is
incorrect as only vendor class bundles should be considered.
For instance, a driver registered for `GREYBUS_DEVICE(0xCAFE, 0xBABE)`
would be matched to a Camera class bundle found on that device.
Instead, only a `GREYBUS_CLASS_VENDOR` class bundle should get
matched to the driver.
[1] https://github.com/projectara/greybus-spec/blob/149aa4a8f4422533475e0193ece…
Signed-off-by: Yacin Belmihoub-Martel <yacin.belmihoubmartel(a)gmail.com>
---
drivers/greybus/core.c | 12 ++++--------
include/linux/greybus.h | 10 +++-------
include/linux/greybus/greybus_id.h | 6 ------
3 files changed, 7 insertions(+), 21 deletions(-)
diff --git a/drivers/greybus/core.c b/drivers/greybus/core.c
index 313eb65cf..4cd218d29 100644
--- a/drivers/greybus/core.c
+++ b/drivers/greybus/core.c
@@ -60,16 +60,12 @@ static int is_gb_svc(const struct device *dev)
static bool greybus_match_one_id(struct gb_bundle *bundle,
const struct greybus_bundle_id *id)
{
- if ((id->match_flags & GREYBUS_ID_MATCH_VENDOR) &&
- (id->vendor != bundle->intf->vendor_id))
+ if (id->class != bundle->class)
return false;
- if ((id->match_flags & GREYBUS_ID_MATCH_PRODUCT) &&
- (id->product != bundle->intf->product_id))
- return false;
-
- if ((id->match_flags & GREYBUS_ID_MATCH_CLASS) &&
- (id->class != bundle->class))
+ if ((id->class == GREYBUS_CLASS_VENDOR) &&
+ (id->vendor != bundle->intf->vendor_id ||
+ id->product != bundle->intf->product_id))
return false;
return true;
diff --git a/include/linux/greybus.h b/include/linux/greybus.h
index 4d58e27ce..1f1b3cb5c 100644
--- a/include/linux/greybus.h
+++ b/include/linux/greybus.h
@@ -37,18 +37,14 @@
#define GREYBUS_VERSION_MAJOR 0x00
#define GREYBUS_VERSION_MINOR 0x01
-#define GREYBUS_ID_MATCH_DEVICE \
- (GREYBUS_ID_MATCH_VENDOR | GREYBUS_ID_MATCH_PRODUCT)
+#define GREYBUS_DEVICE_CLASS(c) \
+ .class = (c),
#define GREYBUS_DEVICE(v, p) \
- .match_flags = GREYBUS_ID_MATCH_DEVICE, \
+ GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_VENDOR)\
.vendor = (v), \
.product = (p),
-#define GREYBUS_DEVICE_CLASS(c) \
- .match_flags = GREYBUS_ID_MATCH_CLASS, \
- .class = (c),
-
/* Maximum number of CPorts */
#define CPORT_ID_MAX 4095 /* UniPro max id is 4095 */
#define CPORT_ID_BAD U16_MAX
diff --git a/include/linux/greybus/greybus_id.h b/include/linux/greybus/greybus_id.h
index f4c844009..e33ed0061 100644
--- a/include/linux/greybus/greybus_id.h
+++ b/include/linux/greybus/greybus_id.h
@@ -11,7 +11,6 @@
struct greybus_bundle_id {
- __u16 match_flags;
__u32 vendor;
__u32 product;
__u8 class;
@@ -19,9 +18,4 @@ struct greybus_bundle_id {
kernel_ulong_t driver_info __aligned(sizeof(kernel_ulong_t));
};
-/* Used to match the greybus_bundle_id */
-#define GREYBUS_ID_MATCH_VENDOR BIT(0)
-#define GREYBUS_ID_MATCH_PRODUCT BIT(1)
-#define GREYBUS_ID_MATCH_CLASS BIT(2)
-
#endif /* __LINUX_GREYBUS_ID_H */
--
2.52.0
Hello everyone,
I’ve recently been experimenting with chaining multiple Greybus nodes to
a single host over I²C (QWIIC port [0]). This general idea is not new
(see MicroMod Qwiic Pro Kit [1]), although those setups do not use Greybus.
Since I²C does not allow a slave to initiate transfers, it is not well
suited for node-initiated events (e.g. interrupts, SVC-initiated
control). However, for my current use case I am primarily interested in
polling-based functionality, so this limitation is acceptable.
In a typical Greybus topology, an Application Processor (AP), an SVC,
and one or more modules are connected via UniPro. In practice, because
most application processors lack a native UniPro interface, they connect
through a bridge device that also implements the SVC.
For the I²C-based setup described above, I have considered the following
topologies:
1. Separate co-processor (SVC/Bridge)
This approach is reasonable on SoCs such as TI AM6254, which include
an M4F core that can serve as the SVC/bridge and control the I²C bus.
However, on devices like TI AM62L, which lack such a core, introducing
an additional processor solely for Greybus does not seem justified.
Also, this would make the above much less portable, since it expects a
hardware component, not all BeagleBoard.org boards have.
```
+----+ +---------------+ +----------+
| AP | <--- bus ----> | SVC / Bridge | <--- I2C ----> |
Module |
+----+ +---------------+ +----------+
|
| +----------+
`----------- I2C ----> | Module |
+----------+
```
2. SVC per node
Each node implements its own SVC. Since an I²C slave cannot initiate
communication, the AP must already know the address of each SVC/module.
This also seems inefficient when chaining multiple nodes.
```
+----+ +----------------+
| AP | <--- I2C ---> | SVC / Module |
+----+ +----------------+
|
| +----------------+
`---- I2C ----> | SVC / Module |
+----------------+
```
3. SVC/Bridge functionality inside the AP
For this use case, this seems to be the most practical option.
To clarify, I am not proposing any new data paths in the Greybus
pipeline. The idea is to have a reusable an SVC/bridge implementation
similar to what exists in greybus-zephyr [2][3], but hosted within the AP.
```
+-------------+ +-----------+
| AP / SVC | <--- I2C ---> | Module |
+-------------+ +-----------+
|
| +----------+
`-- I2C ---> | Module |
+----------+
```
Before proceeding further, I would appreciate feedback on this
approach—particularly whether there are concerns with option 3, or if
there are alternative designs I should consider.
Best regards,
Ayush Singh
[0]: https://www.sparkfun.com/qwiic
[1]:
https://www.digikey.in/en/maker/projects/micromod-qwiic-pro-kit-project-gui…
[2]:
https://github.com/beagleboard/greybus-zephyr/blob/main/subsys/greybus/svc.…
[3]:
https://github.com/beagleboard/greybus-zephyr/blob/main/subsys/greybus/apbr…
This series cleans up dead code in the Greybus audio manager.
gb_audio_manager_get_module() has no in-tree callers. The previously
reported NULL dereference is therefore unreachable. Per review feedback,
the unused function is removed to avoid carrying dead code.
Patch 2 performs a small cleanup in the same area.
Changes in v3:
- Replaced the NULL-deref fix with removal of gb_audio_manager_get_module()
since there are no in-tree callers (per Greg KH).
- No functional changes otherwise.
Thanks for the review.
Signed-off-by: Hardik Phalet <hardik.phalet(a)pm.me>
Hardik Phalet (2):
staging: greybus: audio: remove unused gb_audio_manager_get_module()
staging: greybus: audio: drop stale TODO comment
drivers/staging/greybus/audio_manager.c | 12 ------------
drivers/staging/greybus/audio_manager.h | 7 -------
drivers/staging/greybus/audio_manager_module.c | 1 -
3 files changed, 20 deletions(-)
--
2.53.0
Thank you for the honest feedback. I'm a new contributor and I was
trying to resolve the checkpatch.pl CHECKs to get familiar with the
process, but I see now that vague documentation can be worse than none
at all.
I'll withdraw this patch. Since I'm looking to make my first meaningful
contribution to staging, do you have any suggestions on what types of
issues in Greybus are actually helpful for a beginner to tackle?
regards, jose