diff options
author | Sebastian Reichel <sre@kernel.org> | 2014-03-29 01:48:23 +0400 |
---|---|---|
committer | Sebastian Reichel <sre@kernel.org> | 2014-05-16 02:54:36 +0400 |
commit | a088cf161cc87b39e83c7c53b9f239773422d212 (patch) | |
tree | a58304be6d5e9fd06e2739c1485a87a0824db0e6 /drivers/hsi/hsi.c | |
parent | a0bf37edb4d34c21bdaa19a1624378924b917491 (diff) | |
download | linux-a088cf161cc87b39e83c7c53b9f239773422d212.tar.xz |
HSI: Add channel resource support to HSI clients
Make HSI channel ids platform data, which can be provided
by platform data.
Signed-off-by: Sebastian Reichel <sre@kernel.org>
Tested-By: Ivaylo Dimitrov <ivo.g.dimitrov.75@gmail.com>
Diffstat (limited to 'drivers/hsi/hsi.c')
-rw-r--r-- | drivers/hsi/hsi.c | 46 |
1 files changed, 45 insertions, 1 deletions
diff --git a/drivers/hsi/hsi.c b/drivers/hsi/hsi.c index e96a9874b1a4..de2ad8f20d55 100644 --- a/drivers/hsi/hsi.c +++ b/drivers/hsi/hsi.c @@ -62,18 +62,36 @@ static struct bus_type hsi_bus_type = { static void hsi_client_release(struct device *dev) { - kfree(to_hsi_client(dev)); + struct hsi_client *cl = to_hsi_client(dev); + + kfree(cl->tx_cfg.channels); + kfree(cl->rx_cfg.channels); + kfree(cl); } static void hsi_new_client(struct hsi_port *port, struct hsi_board_info *info) { struct hsi_client *cl; + size_t size; cl = kzalloc(sizeof(*cl), GFP_KERNEL); if (!cl) return; + cl->tx_cfg = info->tx_cfg; + if (cl->tx_cfg.channels) { + size = cl->tx_cfg.num_channels * sizeof(*cl->tx_cfg.channels); + cl->tx_cfg.channels = kzalloc(size , GFP_KERNEL); + memcpy(cl->tx_cfg.channels, info->tx_cfg.channels, size); + } + cl->rx_cfg = info->rx_cfg; + if (cl->rx_cfg.channels) { + size = cl->rx_cfg.num_channels * sizeof(*cl->rx_cfg.channels); + cl->rx_cfg.channels = kzalloc(size , GFP_KERNEL); + memcpy(cl->rx_cfg.channels, info->rx_cfg.channels, size); + } + cl->device.bus = &hsi_bus_type; cl->device.parent = &port->device; cl->device.release = hsi_client_release; @@ -502,6 +520,32 @@ int hsi_event(struct hsi_port *port, unsigned long event) } EXPORT_SYMBOL_GPL(hsi_event); +/** + * hsi_get_channel_id_by_name - acquire channel id by channel name + * @cl: HSI client, which uses the channel + * @name: name the channel is known under + * + * Clients can call this function to get the hsi channel ids similar to + * requesting IRQs or GPIOs by name. This function assumes the same + * channel configuration is used for RX and TX. + * + * Returns -errno on error or channel id on success. + */ +int hsi_get_channel_id_by_name(struct hsi_client *cl, char *name) +{ + int i; + + if (!cl->rx_cfg.channels) + return -ENOENT; + + for (i = 0; i < cl->rx_cfg.num_channels; i++) + if (!strcmp(cl->rx_cfg.channels[i].name, name)) + return cl->rx_cfg.channels[i].id; + + return -ENXIO; +} +EXPORT_SYMBOL_GPL(hsi_get_channel_id_by_name); + static int __init hsi_init(void) { return bus_register(&hsi_bus_type); |