diff options
author | Yin, Fengwei <fengwei.yin@linaro.org> | 2015-10-20 10:33:25 +0800 |
---|---|---|
committer | Yin, Fengwei <fengwei.yin@linaro.org> | 2015-10-22 22:01:20 +0800 |
commit | 030cdd5788b20ae33a448aa765a32806e291a8dc (patch) | |
tree | eaa49f257c75547f0f4c63d14a434cfcdd451c37 | |
parent | ece3b3864848fa1a38c10078559c951886a2c1ea (diff) |
soc: qcom: smd: Implement id_table driver matching
Implement a id_table based driver maching mechanism for drivers that
binds to fixed channels and doesn't need any additional configuration,
e.g. IPCRTR and DIAG.
Signed-off-by: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-rw-r--r-- | drivers/soc/qcom/smd.c | 25 | ||||
-rw-r--r-- | include/linux/soc/qcom/smd.h | 11 |
2 files changed, 29 insertions, 7 deletions
diff --git a/drivers/soc/qcom/smd.c b/drivers/soc/qcom/smd.c index 576c89fd8965..179415a8ace7 100644 --- a/drivers/soc/qcom/smd.c +++ b/drivers/soc/qcom/smd.c @@ -667,6 +667,19 @@ static struct qcom_smd_driver *to_smd_driver(struct device *dev) static int qcom_smd_dev_match(struct device *dev, struct device_driver *drv) { + struct qcom_smd_device *qsdev = to_smd_device(dev); + struct qcom_smd_driver *qsdrv = container_of(drv, struct qcom_smd_driver, driver); + const struct qcom_smd_id *match = qsdrv->smd_match_table; + const char *name = qsdev->channel->name; + + if (match) { + while (match->name[0]) { + if (!strcmp(match->name, name)) + return 1; + match++; + } + } + return of_driver_match_device(dev, drv); } @@ -820,19 +833,17 @@ static int qcom_smd_create_device(struct qcom_smd_channel *channel) if (channel->qsdev) return -EEXIST; - node = qcom_smd_match_channel(edge->of_node, channel->name); - if (!node) { - dev_dbg(smd->dev, "no match for '%s'\n", channel->name); - return -ENXIO; - } - dev_dbg(smd->dev, "registering '%s'\n", channel->name); qsdev = kzalloc(sizeof(*qsdev), GFP_KERNEL); if (!qsdev) return -ENOMEM; - dev_set_name(&qsdev->dev, "%s.%s", edge->of_node->name, node->name); + node = qcom_smd_match_channel(edge->of_node, channel->name); + dev_set_name(&qsdev->dev, "%s.%s", + edge->of_node->name, + node ? node->name : channel->name); + qsdev->dev.parent = smd->dev; qsdev->dev.bus = &qcom_smd_bus; qsdev->dev.release = qcom_smd_release_device; diff --git a/include/linux/soc/qcom/smd.h b/include/linux/soc/qcom/smd.h index 13f56e855401..a2fe0372d205 100644 --- a/include/linux/soc/qcom/smd.h +++ b/include/linux/soc/qcom/smd.h @@ -54,6 +54,14 @@ struct qcom_smd_channel { }; /** + * struct qcom_smd_id - struct used for matching a smd device + * @name: name of the channel + */ +struct qcom_smd_id { + char name[20]; +}; + +/** * struct qcom_smd_device - smd device struct * @dev: the device struct * @channel: handle to the smd channel for this device @@ -66,6 +74,7 @@ struct qcom_smd_device { /** * struct qcom_smd_driver - smd driver struct * @driver: underlying device driver + * @smd_match_table: static channel match table * @probe: invoked when the smd channel is found * @remove: invoked when the smd channel is closed * @callback: invoked when an inbound message is received on the channel, @@ -74,6 +83,8 @@ struct qcom_smd_device { */ struct qcom_smd_driver { struct device_driver driver; + const struct qcom_smd_id *smd_match_table; + int (*probe)(struct qcom_smd_device *dev); void (*remove)(struct qcom_smd_device *dev); int (*callback)(struct qcom_smd_device *, const void *, size_t); |