diff options
author | Linus Walleij <linus.walleij@stericsson.com> | 2012-09-26 10:48:36 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-09-28 09:05:06 -0400 |
commit | aeef9915b9a40d257ec94f9900a3fb4a15da2ab7 (patch) | |
tree | 3c3e9d9707b763047f1fe4a445bc5d71d9addd36 /drivers/spi | |
parent | 8e5d0661b3948f3c5a143f32d192710375822af2 (diff) |
spi/pl022: use more managed resources
This switches the PL022 SPI driver to use devm_* managed resources
for IRQ, clocks, ioremap and GPIO. Prior to this, the GPIOs would
even leak.
Signed-off-by: Linus Walleij <linus.walleij@stericsson.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'drivers/spi')
-rw-r--r-- | drivers/spi/spi-pl022.c | 31 |
1 files changed, 10 insertions, 21 deletions
diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c index f8568b43660d..15737bcee9fb 100644 --- a/drivers/spi/spi-pl022.c +++ b/drivers/spi/spi-pl022.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * A driver for the ARM PL022 PrimeCell SSP/SPI bus master. | 2 | * A driver for the ARM PL022 PrimeCell SSP/SPI bus master. |
3 | * | 3 | * |
4 | * Copyright (C) 2008-2009 ST-Ericsson AB | 4 | * Copyright (C) 2008-2012 ST-Ericsson AB |
5 | * Copyright (C) 2006 STMicroelectronics Pvt. Ltd. | 5 | * Copyright (C) 2006 STMicroelectronics Pvt. Ltd. |
6 | * | 6 | * |
7 | * Author: Linus Walleij <linus.walleij@stericsson.com> | 7 | * Author: Linus Walleij <linus.walleij@stericsson.com> |
@@ -2074,24 +2074,21 @@ pl022_probe(struct amba_device *adev, const struct amba_id *id) | |||
2074 | 2074 | ||
2075 | if (!platform_info) { | 2075 | if (!platform_info) { |
2076 | dev_err(dev, "probe: no platform data defined\n"); | 2076 | dev_err(dev, "probe: no platform data defined\n"); |
2077 | status = -ENODEV; | 2077 | return -ENODEV; |
2078 | goto err_no_pdata; | ||
2079 | } | 2078 | } |
2080 | 2079 | ||
2081 | if (platform_info->num_chipselect) { | 2080 | if (platform_info->num_chipselect) { |
2082 | num_cs = platform_info->num_chipselect; | 2081 | num_cs = platform_info->num_chipselect; |
2083 | } else { | 2082 | } else { |
2084 | dev_err(dev, "probe: no chip select defined\n"); | 2083 | dev_err(dev, "probe: no chip select defined\n"); |
2085 | status = -ENODEV; | 2084 | return -ENODEV; |
2086 | goto err_no_pdata; | ||
2087 | } | 2085 | } |
2088 | 2086 | ||
2089 | /* Allocate master with space for data */ | 2087 | /* Allocate master with space for data */ |
2090 | master = spi_alloc_master(dev, sizeof(struct pl022)); | 2088 | master = spi_alloc_master(dev, sizeof(struct pl022)); |
2091 | if (master == NULL) { | 2089 | if (master == NULL) { |
2092 | dev_err(&adev->dev, "probe - cannot alloc SPI master\n"); | 2090 | dev_err(&adev->dev, "probe - cannot alloc SPI master\n"); |
2093 | status = -ENOMEM; | 2091 | return -ENOMEM; |
2094 | goto err_no_master; | ||
2095 | } | 2092 | } |
2096 | 2093 | ||
2097 | pl022 = spi_master_get_devdata(master); | 2094 | pl022 = spi_master_get_devdata(master); |
@@ -2153,7 +2150,7 @@ pl022_probe(struct amba_device *adev, const struct amba_id *id) | |||
2153 | pl022->chipselects[i] = cs_gpio; | 2150 | pl022->chipselects[i] = cs_gpio; |
2154 | 2151 | ||
2155 | if (gpio_is_valid(cs_gpio)) { | 2152 | if (gpio_is_valid(cs_gpio)) { |
2156 | if (gpio_request(cs_gpio, "ssp-pl022")) | 2153 | if (devm_gpio_request(dev, cs_gpio, "ssp-pl022")) |
2157 | dev_err(&adev->dev, | 2154 | dev_err(&adev->dev, |
2158 | "could not request %d gpio\n", | 2155 | "could not request %d gpio\n", |
2159 | cs_gpio); | 2156 | cs_gpio); |
@@ -2180,7 +2177,8 @@ pl022_probe(struct amba_device *adev, const struct amba_id *id) | |||
2180 | goto err_no_ioregion; | 2177 | goto err_no_ioregion; |
2181 | 2178 | ||
2182 | pl022->phybase = adev->res.start; | 2179 | pl022->phybase = adev->res.start; |
2183 | pl022->virtbase = ioremap(adev->res.start, resource_size(&adev->res)); | 2180 | pl022->virtbase = devm_ioremap(dev, adev->res.start, |
2181 | resource_size(&adev->res)); | ||
2184 | if (pl022->virtbase == NULL) { | 2182 | if (pl022->virtbase == NULL) { |
2185 | status = -ENOMEM; | 2183 | status = -ENOMEM; |
2186 | goto err_no_ioremap; | 2184 | goto err_no_ioremap; |
@@ -2190,7 +2188,7 @@ pl022_probe(struct amba_device *adev, const struct amba_id *id) | |||
2190 | 2188 | ||
2191 | pm_runtime_resume(dev); | 2189 | pm_runtime_resume(dev); |
2192 | 2190 | ||
2193 | pl022->clk = clk_get(&adev->dev, NULL); | 2191 | pl022->clk = devm_clk_get(&adev->dev, NULL); |
2194 | if (IS_ERR(pl022->clk)) { | 2192 | if (IS_ERR(pl022->clk)) { |
2195 | status = PTR_ERR(pl022->clk); | 2193 | status = PTR_ERR(pl022->clk); |
2196 | dev_err(&adev->dev, "could not retrieve SSP/SPI bus clock\n"); | 2194 | dev_err(&adev->dev, "could not retrieve SSP/SPI bus clock\n"); |
@@ -2218,8 +2216,8 @@ pl022_probe(struct amba_device *adev, const struct amba_id *id) | |||
2218 | SSP_CR1(pl022->virtbase)); | 2216 | SSP_CR1(pl022->virtbase)); |
2219 | load_ssp_default_config(pl022); | 2217 | load_ssp_default_config(pl022); |
2220 | 2218 | ||
2221 | status = request_irq(adev->irq[0], pl022_interrupt_handler, 0, "pl022", | 2219 | status = devm_request_irq(dev, adev->irq[0], pl022_interrupt_handler, |
2222 | pl022); | 2220 | 0, "pl022", pl022); |
2223 | if (status < 0) { | 2221 | if (status < 0) { |
2224 | dev_err(&adev->dev, "probe - cannot get IRQ (%d)\n", status); | 2222 | dev_err(&adev->dev, "probe - cannot get IRQ (%d)\n", status); |
2225 | goto err_no_irq; | 2223 | goto err_no_irq; |
@@ -2259,24 +2257,18 @@ pl022_probe(struct amba_device *adev, const struct amba_id *id) | |||
2259 | err_spi_register: | 2257 | err_spi_register: |
2260 | if (platform_info->enable_dma) | 2258 | if (platform_info->enable_dma) |
2261 | pl022_dma_remove(pl022); | 2259 | pl022_dma_remove(pl022); |
2262 | |||
2263 | free_irq(adev->irq[0], pl022); | ||
2264 | err_no_irq: | 2260 | err_no_irq: |
2265 | clk_disable(pl022->clk); | 2261 | clk_disable(pl022->clk); |
2266 | err_no_clk_en: | 2262 | err_no_clk_en: |
2267 | clk_unprepare(pl022->clk); | 2263 | clk_unprepare(pl022->clk); |
2268 | err_clk_prep: | 2264 | err_clk_prep: |
2269 | clk_put(pl022->clk); | ||
2270 | err_no_clk: | 2265 | err_no_clk: |
2271 | iounmap(pl022->virtbase); | ||
2272 | err_no_ioremap: | 2266 | err_no_ioremap: |
2273 | amba_release_regions(adev); | 2267 | amba_release_regions(adev); |
2274 | err_no_ioregion: | 2268 | err_no_ioregion: |
2275 | err_no_gpio: | 2269 | err_no_gpio: |
2276 | err_no_pinctrl: | 2270 | err_no_pinctrl: |
2277 | spi_master_put(master); | 2271 | spi_master_put(master); |
2278 | err_no_master: | ||
2279 | err_no_pdata: | ||
2280 | return status; | 2272 | return status; |
2281 | } | 2273 | } |
2282 | 2274 | ||
@@ -2298,12 +2290,9 @@ pl022_remove(struct amba_device *adev) | |||
2298 | if (pl022->master_info->enable_dma) | 2290 | if (pl022->master_info->enable_dma) |
2299 | pl022_dma_remove(pl022); | 2291 | pl022_dma_remove(pl022); |
2300 | 2292 | ||
2301 | free_irq(adev->irq[0], pl022); | ||
2302 | clk_disable(pl022->clk); | 2293 | clk_disable(pl022->clk); |
2303 | clk_unprepare(pl022->clk); | 2294 | clk_unprepare(pl022->clk); |
2304 | clk_put(pl022->clk); | ||
2305 | pm_runtime_disable(&adev->dev); | 2295 | pm_runtime_disable(&adev->dev); |
2306 | iounmap(pl022->virtbase); | ||
2307 | amba_release_regions(adev); | 2296 | amba_release_regions(adev); |
2308 | tasklet_disable(&pl022->pump_transfers); | 2297 | tasklet_disable(&pl022->pump_transfers); |
2309 | spi_unregister_master(pl022->master); | 2298 | spi_unregister_master(pl022->master); |