aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@linaro.org>2013-08-31 13:50:52 -0400
committerNitin Garg <nitin.garg@freescale.com>2014-04-16 09:05:54 -0400
commit732c1b3904cb71f4347670e0702ddb40beec9f42 (patch)
treeb6da05b277a0becb3174fcf9f1bacdb9217ac129
parentb09223dc33ecb848d2819330d55ac6127d8bc358 (diff)
spi: core: Add devm_spi_register_master()
Help simplify the cleanup code for SPI master drivers by providing a managed master registration function, ensuring that the master is automatically unregistered whenever the device is unbound. Signed-off-by: Mark Brown <broonie@linaro.org> Signed-off-by: Huang Shijie <b32955@freescale.com>
-rw-r--r--Documentation/driver-model/devres.txt3
-rw-r--r--drivers/spi/spi.c35
-rw-r--r--include/linux/spi/spi.h2
3 files changed, 40 insertions, 0 deletions
diff --git a/Documentation/driver-model/devres.txt b/Documentation/driver-model/devres.txt
index b4671459857f..d4b64589cc41 100644
--- a/Documentation/driver-model/devres.txt
+++ b/Documentation/driver-model/devres.txt
@@ -293,3 +293,6 @@ PWM
293PHY 293PHY
294 devm_usb_get_phy() 294 devm_usb_get_phy()
295 devm_usb_put_phy() 295 devm_usb_put_phy()
296
297SPI
298 devm_spi_register_master()
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index bb1f86fb2c3d..600be70ec92d 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -1247,6 +1247,41 @@ done:
1247} 1247}
1248EXPORT_SYMBOL_GPL(spi_register_master); 1248EXPORT_SYMBOL_GPL(spi_register_master);
1249 1249
1250static void devm_spi_unregister(struct device *dev, void *res)
1251{
1252 spi_unregister_master(*(struct spi_master **)res);
1253}
1254
1255/**
1256 * dev_spi_register_master - register managed SPI master controller
1257 * @dev: device managing SPI master
1258 * @master: initialized master, originally from spi_alloc_master()
1259 * Context: can sleep
1260 *
1261 * Register a SPI device as with spi_register_master() which will
1262 * automatically be unregister
1263 */
1264int devm_spi_register_master(struct device *dev, struct spi_master *master)
1265{
1266 struct spi_master **ptr;
1267 int ret;
1268
1269 ptr = devres_alloc(devm_spi_unregister, sizeof(*ptr), GFP_KERNEL);
1270 if (!ptr)
1271 return -ENOMEM;
1272
1273 ret = spi_register_master(master);
1274 if (ret != 0) {
1275 *ptr = master;
1276 devres_add(dev, ptr);
1277 } else {
1278 devres_free(ptr);
1279 }
1280
1281 return ret;
1282}
1283EXPORT_SYMBOL_GPL(devm_spi_register_master);
1284
1250static int __unregister(struct device *dev, void *null) 1285static int __unregister(struct device *dev, void *null)
1251{ 1286{
1252 spi_unregister_device(to_spi_device(dev)); 1287 spi_unregister_device(to_spi_device(dev));
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index 887116dbce2c..4d634d66ba0b 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -434,6 +434,8 @@ extern struct spi_master *
434spi_alloc_master(struct device *host, unsigned size); 434spi_alloc_master(struct device *host, unsigned size);
435 435
436extern int spi_register_master(struct spi_master *master); 436extern int spi_register_master(struct spi_master *master);
437extern int devm_spi_register_master(struct device *dev,
438 struct spi_master *master);
437extern void spi_unregister_master(struct spi_master *master); 439extern void spi_unregister_master(struct spi_master *master);
438 440
439extern struct spi_master *spi_busnum_to_master(u16 busnum); 441extern struct spi_master *spi_busnum_to_master(u16 busnum);