Merge "soundwire: Remove startup from swr_driver structure"

This commit is contained in:
Linux Build Service Account 2017-06-15 08:36:27 -07:00 committed by Gerrit - the friendly Code Review server
commit dd704b7258
4 changed files with 66 additions and 107 deletions

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. /* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and * it under the terms of the GNU General Public License version 2 and
@ -67,6 +67,27 @@ static void swr_dev_release(struct device *dev)
kfree(swr_dev); kfree(swr_dev);
} }
/**
* swr_remove_device - remove a soundwire device
* @swr_dev: soundwire device to remove
*
* Remove a soundwire device. Go through the soundwire
* device list that master has and remove swr_dev from
* it.
*/
void swr_remove_device(struct swr_device *swr_dev)
{
struct swr_device *swr_dev_loop, *safe;
list_for_each_entry_safe(swr_dev_loop, safe,
&swr_dev->master->devices,
dev_list) {
if (swr_dev == swr_dev_loop)
list_del(&swr_dev_loop->dev_list);
}
}
EXPORT_SYMBOL(swr_remove_device);
/** /**
* swr_new_device - instantiate a new soundwire device * swr_new_device - instantiate a new soundwire device
* @master: Controller to which device is connected * @master: Controller to which device is connected
@ -128,47 +149,6 @@ err_out:
} }
EXPORT_SYMBOL(swr_new_device); EXPORT_SYMBOL(swr_new_device);
/**
* swr_startup_devices - perform additional initialization for child devices
*
* @swr_dev: pointer to soundwire slave device
*
* Performs any additional initialization needed for a soundwire slave device.
* This is a optional functionality defined by slave devices.
* Removes the slave node from the list, in case there is any failure.
*/
int swr_startup_devices(struct swr_device *swr_dev)
{
struct swr_driver *swr_drv;
struct device *dev;
int ret = 0;
if (!swr_dev)
return -EINVAL;
dev = &swr_dev->dev;
if (!dev)
return -EINVAL;
swr_drv = to_swr_driver(dev->driver);
if (!swr_drv)
return -EINVAL;
if (swr_drv->startup) {
ret = swr_drv->startup(swr_dev);
if (ret)
goto out;
dev_dbg(&swr_dev->dev,
"%s: startup complete for device %lx\n",
__func__, swr_dev->addr);
}
out:
return ret;
}
EXPORT_SYMBOL(swr_startup_devices);
/** /**
* of_register_swr_devices - register child devices on to the soundwire bus * of_register_swr_devices - register child devices on to the soundwire bus
* @master: pointer to soundwire master device * @master: pointer to soundwire master device
@ -610,7 +590,7 @@ int swr_device_up(struct swr_device *swr_dev)
dev = &swr_dev->dev; dev = &swr_dev->dev;
sdrv = to_swr_driver(dev->driver); sdrv = to_swr_driver(dev->driver);
if (!sdrv) if (!sdrv)
return -EINVAL; return 0;
if (sdrv->device_up) if (sdrv->device_up)
return sdrv->device_up(to_swr_device(dev)); return sdrv->device_up(to_swr_device(dev));
@ -638,7 +618,7 @@ int swr_device_down(struct swr_device *swr_dev)
dev = &swr_dev->dev; dev = &swr_dev->dev;
sdrv = to_swr_driver(dev->driver); sdrv = to_swr_driver(dev->driver);
if (!sdrv) if (!sdrv)
return -EINVAL; return 0;
if (sdrv->device_down) if (sdrv->device_down)
return sdrv->device_down(to_swr_device(dev)); return sdrv->device_down(to_swr_device(dev));

View file

@ -1369,7 +1369,6 @@ static int swrm_probe(struct platform_device *pdev)
{ {
struct swr_mstr_ctrl *swrm; struct swr_mstr_ctrl *swrm;
struct swr_ctrl_platform_data *pdata; struct swr_ctrl_platform_data *pdata;
struct swr_device *swr_dev, *safe;
int ret; int ret;
/* Allocate soundwire master driver structure */ /* Allocate soundwire master driver structure */
@ -1470,9 +1469,6 @@ static int swrm_probe(struct platform_device *pdev)
goto err_mstr_fail; goto err_mstr_fail;
} }
if (pdev->dev.of_node)
of_register_swr_devices(&swrm->master);
/* Add devices registered with board-info as the /* Add devices registered with board-info as the
controller will be up now controller will be up now
*/ */
@ -1489,15 +1485,11 @@ static int swrm_probe(struct platform_device *pdev)
} }
swrm->version = swrm->read(swrm->handle, SWRM_COMP_HW_VERSION); swrm->version = swrm->read(swrm->handle, SWRM_COMP_HW_VERSION);
/* Enumerate slave devices */
list_for_each_entry_safe(swr_dev, safe, &swrm->master.devices,
dev_list) {
ret = swr_startup_devices(swr_dev);
if (ret)
list_del(&swr_dev->dev_list);
}
mutex_unlock(&swrm->mlock); mutex_unlock(&swrm->mlock);
if (pdev->dev.of_node)
of_register_swr_devices(&swrm->master);
dbgswrm = swrm; dbgswrm = swrm;
debugfs_swrm_dent = debugfs_create_dir(dev_name(&pdev->dev), 0); debugfs_swrm_dent = debugfs_create_dir(dev_name(&pdev->dev), 0);
if (!IS_ERR(debugfs_swrm_dent)) { if (!IS_ERR(debugfs_swrm_dent)) {

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. /* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and * it under the terms of the GNU General Public License version 2 and
@ -196,7 +196,6 @@ static inline struct swr_device *to_swr_device(struct device *dev)
* @shutdown: standard shutdown callback used during power down/halt * @shutdown: standard shutdown callback used during power down/halt
* @suspend: standard suspend callback used during system suspend * @suspend: standard suspend callback used during system suspend
* @resume: standard resume callback used during system resume * @resume: standard resume callback used during system resume
* @startup: additional init operation for slave devices
* @driver: soundwire device drivers should initialize name and * @driver: soundwire device drivers should initialize name and
* owner field of this structure * owner field of this structure
* @id_table: list of soundwire devices supported by this driver * @id_table: list of soundwire devices supported by this driver
@ -210,7 +209,6 @@ struct swr_driver {
int (*device_up)(struct swr_device *swr); int (*device_up)(struct swr_device *swr);
int (*device_down)(struct swr_device *swr); int (*device_down)(struct swr_device *swr);
int (*reset_device)(struct swr_device *swr); int (*reset_device)(struct swr_device *swr);
int (*startup)(struct swr_device *swr);
struct device_driver driver; struct device_driver driver;
const struct swr_device_id *id_table; const struct swr_device_id *id_table;
}; };
@ -309,4 +307,6 @@ extern int swr_reset_device(struct swr_device *swr_dev);
extern int swr_slvdev_datapath_control(struct swr_device *swr_dev, u8 dev_num, extern int swr_slvdev_datapath_control(struct swr_device *swr_dev, u8 dev_num,
bool enable); bool enable);
extern int swr_remove_from_group(struct swr_device *dev, u8 dev_num); extern int swr_remove_from_group(struct swr_device *dev, u8 dev_num);
extern void swr_remove_device(struct swr_device *swr_dev);
#endif /* _LINUX_SOUNDWIRE_H */ #endif /* _LINUX_SOUNDWIRE_H */

View file

@ -1123,54 +1123,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wsa881x = {
.get_regmap = wsa881x_get_regmap, .get_regmap = wsa881x_get_regmap,
}; };
static int wsa881x_swr_startup(struct swr_device *swr_dev)
{
int ret = 0;
u8 devnum = 0;
struct wsa881x_priv *wsa881x;
wsa881x = swr_get_dev_data(swr_dev);
if (!wsa881x) {
dev_err(&swr_dev->dev, "%s: wsa881x is NULL\n", __func__);
return -EINVAL;
}
/*
* Add 5msec delay to provide sufficient time for
* soundwire auto enumeration of slave devices as
* as per HW requirement.
*/
usleep_range(5000, 5010);
ret = swr_get_logical_dev_num(swr_dev, swr_dev->addr, &devnum);
if (ret) {
dev_dbg(&swr_dev->dev,
"%s get devnum %d for dev addr %lx failed\n",
__func__, devnum, swr_dev->addr);
goto err;
}
swr_dev->dev_num = devnum;
wsa881x->regmap = devm_regmap_init_swr(swr_dev,
&wsa881x_regmap_config);
if (IS_ERR(wsa881x->regmap)) {
ret = PTR_ERR(wsa881x->regmap);
dev_err(&swr_dev->dev, "%s: regmap_init failed %d\n",
__func__, ret);
goto err;
}
ret = snd_soc_register_codec(&swr_dev->dev, &soc_codec_dev_wsa881x,
NULL, 0);
if (ret) {
dev_err(&swr_dev->dev, "%s: Codec registration failed\n",
__func__);
goto err;
}
err:
return ret;
}
static int wsa881x_gpio_ctrl(struct wsa881x_priv *wsa881x, bool enable) static int wsa881x_gpio_ctrl(struct wsa881x_priv *wsa881x, bool enable)
{ {
int ret = 0; int ret = 0;
@ -1232,6 +1184,7 @@ static int wsa881x_swr_probe(struct swr_device *pdev)
{ {
int ret = 0; int ret = 0;
struct wsa881x_priv *wsa881x; struct wsa881x_priv *wsa881x;
u8 devnum = 0;
wsa881x = devm_kzalloc(&pdev->dev, sizeof(struct wsa881x_priv), wsa881x = devm_kzalloc(&pdev->dev, sizeof(struct wsa881x_priv),
GFP_KERNEL); GFP_KERNEL);
@ -1291,8 +1244,43 @@ static int wsa881x_swr_probe(struct swr_device *pdev)
&codec_debug_ops); &codec_debug_ops);
} }
} }
/*
* Add 5msec delay to provide sufficient time for
* soundwire auto enumeration of slave devices as
* as per HW requirement.
*/
usleep_range(5000, 5010);
ret = swr_get_logical_dev_num(pdev, pdev->addr, &devnum);
if (ret) {
dev_dbg(&pdev->dev,
"%s get devnum %d for dev addr %lx failed\n",
__func__, devnum, pdev->addr);
goto dev_err;
}
pdev->dev_num = devnum;
wsa881x->regmap = devm_regmap_init_swr(pdev,
&wsa881x_regmap_config);
if (IS_ERR(wsa881x->regmap)) {
ret = PTR_ERR(wsa881x->regmap);
dev_err(&pdev->dev, "%s: regmap_init failed %d\n",
__func__, ret);
goto dev_err;
}
ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wsa881x,
NULL, 0);
if (ret) {
dev_err(&pdev->dev, "%s: Codec registration failed\n",
__func__);
goto dev_err;
}
return 0; return 0;
dev_err:
swr_remove_device(pdev);
err: err:
return ret; return ret;
} }
@ -1425,7 +1413,6 @@ static struct swr_driver wsa881x_codec_driver = {
.device_up = wsa881x_swr_up, .device_up = wsa881x_swr_up,
.device_down = wsa881x_swr_down, .device_down = wsa881x_swr_down,
.reset_device = wsa881x_swr_reset, .reset_device = wsa881x_swr_reset,
.startup = wsa881x_swr_startup,
}; };
static int __init wsa881x_codec_init(void) static int __init wsa881x_codec_init(void)