mirror of
https://github.com/torvalds/linux.git
synced 2024-12-10 05:01:26 +00:00
firmware: arm_scpi: make freeing mbox channels device-managed
Make freeing the mbox channels device-managed, thus further simplifying scpi_remove and and one further step to get rid of scpi_remove. Tested-by: Kevin Hilman <khilman@baylibre.com> Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com> Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
This commit is contained in:
parent
cd6f0602d2
commit
c14f1db41d
@ -889,16 +889,13 @@ static struct attribute *versions_attrs[] = {
|
|||||||
};
|
};
|
||||||
ATTRIBUTE_GROUPS(versions);
|
ATTRIBUTE_GROUPS(versions);
|
||||||
|
|
||||||
static void
|
static void scpi_free_channels(void *data)
|
||||||
scpi_free_channels(struct device *dev, struct scpi_chan *pchan, int count)
|
|
||||||
{
|
{
|
||||||
|
struct scpi_drvinfo *info = data;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < count && pchan->chan; i++, pchan++) {
|
for (i = 0; i < info->num_chans; i++)
|
||||||
mbox_free_channel(pchan->chan);
|
mbox_free_channel(info->channels[i].chan);
|
||||||
devm_kfree(dev, pchan->xfers);
|
|
||||||
devm_iounmap(dev, pchan->rx_payload);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int scpi_remove(struct platform_device *pdev)
|
static int scpi_remove(struct platform_device *pdev)
|
||||||
@ -911,7 +908,6 @@ static int scpi_remove(struct platform_device *pdev)
|
|||||||
|
|
||||||
of_platform_depopulate(dev);
|
of_platform_depopulate(dev);
|
||||||
sysfs_remove_groups(&dev->kobj, versions_groups);
|
sysfs_remove_groups(&dev->kobj, versions_groups);
|
||||||
scpi_free_channels(dev, info->channels, info->num_chans);
|
|
||||||
platform_set_drvdata(pdev, NULL);
|
platform_set_drvdata(pdev, NULL);
|
||||||
|
|
||||||
for (i = 0; i < MAX_DVFS_DOMAINS && info->dvfs[i]; i++) {
|
for (i = 0; i < MAX_DVFS_DOMAINS && info->dvfs[i]; i++) {
|
||||||
@ -950,7 +946,6 @@ static int scpi_probe(struct platform_device *pdev)
|
|||||||
{
|
{
|
||||||
int count, idx, ret;
|
int count, idx, ret;
|
||||||
struct resource res;
|
struct resource res;
|
||||||
struct scpi_chan *scpi_chan;
|
|
||||||
struct device *dev = &pdev->dev;
|
struct device *dev = &pdev->dev;
|
||||||
struct device_node *np = dev->of_node;
|
struct device_node *np = dev->of_node;
|
||||||
|
|
||||||
@ -967,13 +962,19 @@ static int scpi_probe(struct platform_device *pdev)
|
|||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
scpi_chan = devm_kcalloc(dev, count, sizeof(*scpi_chan), GFP_KERNEL);
|
scpi_info->channels = devm_kcalloc(dev, count, sizeof(struct scpi_chan),
|
||||||
if (!scpi_chan)
|
GFP_KERNEL);
|
||||||
|
if (!scpi_info->channels)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
for (idx = 0; idx < count; idx++) {
|
ret = devm_add_action(dev, scpi_free_channels, scpi_info);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
for (; scpi_info->num_chans < count; scpi_info->num_chans++) {
|
||||||
resource_size_t size;
|
resource_size_t size;
|
||||||
struct scpi_chan *pchan = scpi_chan + idx;
|
int idx = scpi_info->num_chans;
|
||||||
|
struct scpi_chan *pchan = scpi_info->channels + idx;
|
||||||
struct mbox_client *cl = &pchan->cl;
|
struct mbox_client *cl = &pchan->cl;
|
||||||
struct device_node *shmem = of_parse_phandle(np, "shmem", idx);
|
struct device_node *shmem = of_parse_phandle(np, "shmem", idx);
|
||||||
|
|
||||||
@ -981,15 +982,14 @@ static int scpi_probe(struct platform_device *pdev)
|
|||||||
of_node_put(shmem);
|
of_node_put(shmem);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(dev, "failed to get SCPI payload mem resource\n");
|
dev_err(dev, "failed to get SCPI payload mem resource\n");
|
||||||
goto err;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
size = resource_size(&res);
|
size = resource_size(&res);
|
||||||
pchan->rx_payload = devm_ioremap(dev, res.start, size);
|
pchan->rx_payload = devm_ioremap(dev, res.start, size);
|
||||||
if (!pchan->rx_payload) {
|
if (!pchan->rx_payload) {
|
||||||
dev_err(dev, "failed to ioremap SCPI payload\n");
|
dev_err(dev, "failed to ioremap SCPI payload\n");
|
||||||
ret = -EADDRNOTAVAIL;
|
return -EADDRNOTAVAIL;
|
||||||
goto err;
|
|
||||||
}
|
}
|
||||||
pchan->tx_payload = pchan->rx_payload + (size >> 1);
|
pchan->tx_payload = pchan->rx_payload + (size >> 1);
|
||||||
|
|
||||||
@ -1015,14 +1015,9 @@ static int scpi_probe(struct platform_device *pdev)
|
|||||||
dev_err(dev, "failed to get channel%d err %d\n",
|
dev_err(dev, "failed to get channel%d err %d\n",
|
||||||
idx, ret);
|
idx, ret);
|
||||||
}
|
}
|
||||||
err:
|
|
||||||
scpi_free_channels(dev, scpi_chan, idx);
|
|
||||||
scpi_info = NULL;
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
scpi_info->channels = scpi_chan;
|
|
||||||
scpi_info->num_chans = count;
|
|
||||||
scpi_info->commands = scpi_std_commands;
|
scpi_info->commands = scpi_std_commands;
|
||||||
|
|
||||||
platform_set_drvdata(pdev, scpi_info);
|
platform_set_drvdata(pdev, scpi_info);
|
||||||
|
Loading…
Reference in New Issue
Block a user