Merge tag 'usb-5.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
Pull USB/PHY updates from Greg KH: "Here is the big USB/PHY driver pull request for 5.1-rc1. The usual set of gadget driver updates, phy driver updates, xhci updates, and typec additions. Also included in here are a lot of small cleanups and fixes and driver updates where needed. All of these have been in linux-next for a while with no reported issues" * tag 'usb-5.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (167 commits) wusb: Remove unnecessary static function ckhdid_printf usb: core: make default autosuspend delay configurable usb: core: Fix typo in description of "authorized_default" usb: chipidea: Refactor USB PHY selection and keep a single PHY usb: chipidea: Grab the (legacy) USB PHY by phandle first usb: chipidea: imx: set power polarity dt-bindings: usb: ci-hdrc-usb2: add property power-active-high usb: chipidea: imx: remove unused header files usb: chipidea: tegra: Fix missed ci_hdrc_remove_device() usb: core: add option of only authorizing internal devices usb: typec: tps6598x: handle block writes separately with plain-I2C adapters usb: xhci: Fix for Enabling USB ROLE SWITCH QUIRK on INTEL_SUNRISEPOINT_LP_XHCI usb: xhci: fix build warning - missing prototype usb: xhci: dbc: Fixing typo error. usb: xhci: remove unused member 'parent' in xhci_regset struct xhci: tegra: Prevent error pointer dereference USB: serial: option: add Telit ME910 ECM composition usb: core: Replace hardcoded check with inline function from usb.h usb: core: skip interfaces disabled in devicetree usb: typec: mux: remove redundant check on variable match ...
This commit is contained in:
@@ -7,10 +7,37 @@
|
||||
*/
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/property.h>
|
||||
|
||||
static DEFINE_MUTEX(devcon_lock);
|
||||
static LIST_HEAD(devcon_list);
|
||||
|
||||
typedef void *(*devcon_match_fn_t)(struct device_connection *con, int ep,
|
||||
void *data);
|
||||
|
||||
static void *
|
||||
fwnode_graph_devcon_match(struct fwnode_handle *fwnode, const char *con_id,
|
||||
void *data, devcon_match_fn_t match)
|
||||
{
|
||||
struct device_connection con = { .id = con_id };
|
||||
struct fwnode_handle *ep;
|
||||
void *ret;
|
||||
|
||||
fwnode_graph_for_each_endpoint(fwnode, ep) {
|
||||
con.fwnode = fwnode_graph_get_remote_port_parent(ep);
|
||||
if (!fwnode_device_is_available(con.fwnode))
|
||||
continue;
|
||||
|
||||
ret = match(&con, -1, data);
|
||||
fwnode_handle_put(con.fwnode);
|
||||
if (ret) {
|
||||
fwnode_handle_put(ep);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* device_connection_find_match - Find physical connection to a device
|
||||
* @dev: Device with the connection
|
||||
@@ -23,10 +50,9 @@ static LIST_HEAD(devcon_list);
|
||||
* caller is expecting to be returned.
|
||||
*/
|
||||
void *device_connection_find_match(struct device *dev, const char *con_id,
|
||||
void *data,
|
||||
void *(*match)(struct device_connection *con,
|
||||
int ep, void *data))
|
||||
void *data, devcon_match_fn_t match)
|
||||
{
|
||||
struct fwnode_handle *fwnode = dev_fwnode(dev);
|
||||
const char *devname = dev_name(dev);
|
||||
struct device_connection *con;
|
||||
void *ret = NULL;
|
||||
@@ -35,6 +61,12 @@ void *device_connection_find_match(struct device *dev, const char *con_id,
|
||||
if (!match)
|
||||
return NULL;
|
||||
|
||||
if (fwnode) {
|
||||
ret = fwnode_graph_devcon_match(fwnode, con_id, data, match);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
mutex_lock(&devcon_lock);
|
||||
|
||||
list_for_each_entry(con, &devcon_list, list) {
|
||||
@@ -75,12 +107,36 @@ static struct bus_type *generic_match_buses[] = {
|
||||
NULL,
|
||||
};
|
||||
|
||||
static int device_fwnode_match(struct device *dev, void *fwnode)
|
||||
{
|
||||
return dev_fwnode(dev) == fwnode;
|
||||
}
|
||||
|
||||
static void *device_connection_fwnode_match(struct device_connection *con)
|
||||
{
|
||||
struct bus_type *bus;
|
||||
struct device *dev;
|
||||
|
||||
for (bus = generic_match_buses[0]; bus; bus++) {
|
||||
dev = bus_find_device(bus, NULL, (void *)con->fwnode,
|
||||
device_fwnode_match);
|
||||
if (dev && !strncmp(dev_name(dev), con->id, strlen(con->id)))
|
||||
return dev;
|
||||
|
||||
put_device(dev);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* This tries to find the device from the most common bus types by name. */
|
||||
static void *generic_match(struct device_connection *con, int ep, void *data)
|
||||
{
|
||||
struct bus_type *bus;
|
||||
struct device *dev;
|
||||
|
||||
if (con->fwnode)
|
||||
return device_connection_fwnode_match(con);
|
||||
|
||||
for (bus = generic_match_buses[0]; bus; bus++) {
|
||||
dev = bus_find_device_by_name(bus, NULL, con->endpoint[ep]);
|
||||
if (dev)
|
||||
|
Reference in New Issue
Block a user