Provide an API for Bluetooth drivers to retrieve the Bluetooth Device address (BD_ADDR) for a device. If the device node has a property 'local-bd-address' the BD address is read from this property. Signed-off-by: Matthias Kaehlcke <mka@xxxxxxxxxxxx> Reviewed-by: Andy Shevchenko <andy.shevchenko@xxxxxxxxx> --- Changes in v2: - use bdaddr_t instead of byte pointer + len - use EXPORT_SYMBOL_GPL for the new functions instead of EXPORT_SYMBOL - put new functions inside #if IS_ENABLED(CONFIG_BT) - some new line juggling in property.h - added 'Reviewed-by: Andy Shevchenko <andy.shevchenko@xxxxxxxxx>' tag --- drivers/base/property.c | 46 ++++++++++++++++++++++++++++++++++++++++ include/linux/property.h | 3 +++ 2 files changed, 49 insertions(+) diff --git a/drivers/base/property.c b/drivers/base/property.c index 240ab5230ff6..afe412133188 100644 --- a/drivers/base/property.c +++ b/drivers/base/property.c @@ -1315,6 +1315,52 @@ void *device_get_mac_address(struct device *dev, char *addr, int alen) } EXPORT_SYMBOL(device_get_mac_address); +#if IS_ENABLED(CONFIG_BT) + +/** + * fwnode_get_bd_address - Get the Bluetooth Device Address (BD_ADDR) from the + * firmware node + * @fwnode: Pointer to the firmware node + * @bd_addr: Pointer to struct to store the BD address in + * + * Search the firmware node for 'local-bd-address'. + * + * All-zero BD addresses are rejected, because those could be properties + * that exist in the firmware tables, but were not updated by the firmware. For + * example, the DTS could define 'local-bd-address', with zero BD addresses. + */ +int fwnode_get_bd_address(struct fwnode_handle *fwnode, bdaddr_t *bd_addr) +{ + bdaddr_t ba; + int ret; + + ret = fwnode_property_read_u8_array(fwnode, "local-bd-address", + (u8 *)&ba, sizeof(bdaddr_t)); + if (ret < 0) + return ret; + if (is_zero_ether_addr((u8 *)&ba)) + return -ENODATA; + + memcpy(bd_addr, &ba, sizeof(bdaddr_t)); + + return 0; +} +EXPORT_SYMBOL_GPL(fwnode_get_bd_address); + +/** + * device_get_bd_address - Get the Bluetooth Device Address (BD_ADDR) for a + * given device + * @dev: Pointer to the device + * @bd_addr: Pointer to struct to store the BD address in + */ +int device_get_bd_address(struct device *dev, bdaddr_t *bd_addr) +{ + return fwnode_get_bd_address(dev_fwnode(dev), bd_addr); +} +EXPORT_SYMBOL_GPL(device_get_bd_address); + +#endif + /** * fwnode_irq_get - Get IRQ directly from a fwnode * @fwnode: Pointer to the firmware node diff --git a/include/linux/property.h b/include/linux/property.h index ac8a1ebc4c1b..8926cf95d27e 100644 --- a/include/linux/property.h +++ b/include/linux/property.h @@ -15,6 +15,7 @@ #include <linux/fwnode.h> #include <linux/types.h> +#include <net/bluetooth/bluetooth.h> struct device; @@ -286,10 +287,12 @@ const void *device_get_match_data(struct device *dev); int device_get_phy_mode(struct device *dev); void *device_get_mac_address(struct device *dev, char *addr, int alen); +int device_get_bd_address(struct device *dev, bdaddr_t *bd_addr); int fwnode_get_phy_mode(struct fwnode_handle *fwnode); void *fwnode_get_mac_address(struct fwnode_handle *fwnode, char *addr, int alen); +int fwnode_get_bd_address(struct fwnode_handle *fwnode, bdaddr_t *bd_addr); struct fwnode_handle *fwnode_graph_get_next_endpoint( const struct fwnode_handle *fwnode, struct fwnode_handle *prev); struct fwnode_handle * -- 2.19.0.444.g18242da7ef-goog