diff options
author | Andy Shevchenko <andriy.shevchenko@linux.intel.com> | 2013-04-09 20:36:36 -0400 |
---|---|---|
committer | Wolfram Sang <wsa@the-dreams.de> | 2013-04-15 12:16:52 -0400 |
commit | 1cb715ca46946b1ad32735d11830a84a433f2b1b (patch) | |
tree | 2d9f2e490a1f90bec9c0adc434bfe1d98b2df83e /drivers/i2c | |
parent | e5a7074a753623505ad20289abbea7a6c8c47bf7 (diff) |
i2c-designware: move to managed functions (devm_*)
This makes the error handling much more simpler than open-coding everything
and in addition makes the probe function smaller and tidier.
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
Diffstat (limited to 'drivers/i2c')
-rw-r--r-- | drivers/i2c/busses/i2c-designware-platdrv.c | 73 |
1 files changed, 19 insertions, 54 deletions
diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c index 0ceb6e1b0f65..c53a3127f694 100644 --- a/drivers/i2c/busses/i2c-designware-platdrv.c +++ b/drivers/i2c/busses/i2c-designware-platdrv.c | |||
@@ -92,7 +92,7 @@ static int dw_i2c_probe(struct platform_device *pdev) | |||
92 | { | 92 | { |
93 | struct dw_i2c_dev *dev; | 93 | struct dw_i2c_dev *dev; |
94 | struct i2c_adapter *adap; | 94 | struct i2c_adapter *adap; |
95 | struct resource *mem, *ioarea; | 95 | struct resource *mem; |
96 | int irq, r; | 96 | int irq, r; |
97 | 97 | ||
98 | /* NOTE: driver uses the static register mapping */ | 98 | /* NOTE: driver uses the static register mapping */ |
@@ -108,32 +108,25 @@ static int dw_i2c_probe(struct platform_device *pdev) | |||
108 | return irq; /* -ENXIO */ | 108 | return irq; /* -ENXIO */ |
109 | } | 109 | } |
110 | 110 | ||
111 | ioarea = request_mem_region(mem->start, resource_size(mem), | 111 | dev = devm_kzalloc(&pdev->dev, sizeof(struct dw_i2c_dev), GFP_KERNEL); |
112 | pdev->name); | 112 | if (!dev) |
113 | if (!ioarea) { | 113 | return -ENOMEM; |
114 | dev_err(&pdev->dev, "I2C region already claimed\n"); | ||
115 | return -EBUSY; | ||
116 | } | ||
117 | 114 | ||
118 | dev = kzalloc(sizeof(struct dw_i2c_dev), GFP_KERNEL); | 115 | dev->base = devm_ioremap_resource(&pdev->dev, mem); |
119 | if (!dev) { | 116 | if (IS_ERR(dev->base)) |
120 | r = -ENOMEM; | 117 | return PTR_ERR(dev->base); |
121 | goto err_release_region; | ||
122 | } | ||
123 | 118 | ||
124 | init_completion(&dev->cmd_complete); | 119 | init_completion(&dev->cmd_complete); |
125 | mutex_init(&dev->lock); | 120 | mutex_init(&dev->lock); |
126 | dev->dev = get_device(&pdev->dev); | 121 | dev->dev = &pdev->dev; |
127 | dev->irq = irq; | 122 | dev->irq = irq; |
128 | platform_set_drvdata(pdev, dev); | 123 | platform_set_drvdata(pdev, dev); |
129 | 124 | ||
130 | dev->clk = clk_get(&pdev->dev, NULL); | 125 | dev->clk = devm_clk_get(&pdev->dev, NULL); |
131 | dev->get_clk_rate_khz = i2c_dw_get_clk_rate_khz; | 126 | dev->get_clk_rate_khz = i2c_dw_get_clk_rate_khz; |
132 | 127 | ||
133 | if (IS_ERR(dev->clk)) { | 128 | if (IS_ERR(dev->clk)) |
134 | r = -ENODEV; | 129 | return PTR_ERR(dev->clk); |
135 | goto err_free_mem; | ||
136 | } | ||
137 | clk_prepare_enable(dev->clk); | 130 | clk_prepare_enable(dev->clk); |
138 | 131 | ||
139 | dev->functionality = | 132 | dev->functionality = |
@@ -146,13 +139,6 @@ static int dw_i2c_probe(struct platform_device *pdev) | |||
146 | dev->master_cfg = DW_IC_CON_MASTER | DW_IC_CON_SLAVE_DISABLE | | 139 | dev->master_cfg = DW_IC_CON_MASTER | DW_IC_CON_SLAVE_DISABLE | |
147 | DW_IC_CON_RESTART_EN | DW_IC_CON_SPEED_FAST; | 140 | DW_IC_CON_RESTART_EN | DW_IC_CON_SPEED_FAST; |
148 | 141 | ||
149 | dev->base = ioremap(mem->start, resource_size(mem)); | ||
150 | if (dev->base == NULL) { | ||
151 | dev_err(&pdev->dev, "failure mapping io resources\n"); | ||
152 | r = -EBUSY; | ||
153 | goto err_unuse_clocks; | ||
154 | } | ||
155 | |||
156 | /* Try first if we can configure the device from ACPI */ | 142 | /* Try first if we can configure the device from ACPI */ |
157 | r = dw_i2c_acpi_configure(pdev); | 143 | r = dw_i2c_acpi_configure(pdev); |
158 | if (r) { | 144 | if (r) { |
@@ -164,13 +150,14 @@ static int dw_i2c_probe(struct platform_device *pdev) | |||
164 | } | 150 | } |
165 | r = i2c_dw_init(dev); | 151 | r = i2c_dw_init(dev); |
166 | if (r) | 152 | if (r) |
167 | goto err_iounmap; | 153 | return r; |
168 | 154 | ||
169 | i2c_dw_disable_int(dev); | 155 | i2c_dw_disable_int(dev); |
170 | r = request_irq(dev->irq, i2c_dw_isr, IRQF_SHARED, pdev->name, dev); | 156 | r = devm_request_irq(&pdev->dev, dev->irq, i2c_dw_isr, IRQF_SHARED, |
157 | pdev->name, dev); | ||
171 | if (r) { | 158 | if (r) { |
172 | dev_err(&pdev->dev, "failure requesting irq %i\n", dev->irq); | 159 | dev_err(&pdev->dev, "failure requesting irq %i\n", dev->irq); |
173 | goto err_iounmap; | 160 | return r; |
174 | } | 161 | } |
175 | 162 | ||
176 | adap = &dev->adapter; | 163 | adap = &dev->adapter; |
@@ -187,57 +174,35 @@ static int dw_i2c_probe(struct platform_device *pdev) | |||
187 | r = i2c_add_numbered_adapter(adap); | 174 | r = i2c_add_numbered_adapter(adap); |
188 | if (r) { | 175 | if (r) { |
189 | dev_err(&pdev->dev, "failure adding adapter\n"); | 176 | dev_err(&pdev->dev, "failure adding adapter\n"); |
190 | goto err_free_irq; | 177 | return r; |
191 | } | 178 | } |
192 | of_i2c_register_devices(adap); | 179 | of_i2c_register_devices(adap); |
193 | acpi_i2c_register_devices(adap); | 180 | acpi_i2c_register_devices(adap); |
194 | 181 | ||
182 | /* Increase reference counter */ | ||
183 | get_device(&pdev->dev); | ||
184 | |||
195 | pm_runtime_set_active(&pdev->dev); | 185 | pm_runtime_set_active(&pdev->dev); |
196 | pm_runtime_enable(&pdev->dev); | 186 | pm_runtime_enable(&pdev->dev); |
197 | pm_runtime_put(&pdev->dev); | 187 | pm_runtime_put(&pdev->dev); |
198 | 188 | ||
199 | return 0; | 189 | return 0; |
200 | |||
201 | err_free_irq: | ||
202 | free_irq(dev->irq, dev); | ||
203 | err_iounmap: | ||
204 | iounmap(dev->base); | ||
205 | err_unuse_clocks: | ||
206 | clk_disable_unprepare(dev->clk); | ||
207 | clk_put(dev->clk); | ||
208 | dev->clk = NULL; | ||
209 | err_free_mem: | ||
210 | put_device(&pdev->dev); | ||
211 | kfree(dev); | ||
212 | err_release_region: | ||
213 | release_mem_region(mem->start, resource_size(mem)); | ||
214 | |||
215 | return r; | ||
216 | } | 190 | } |
217 | 191 | ||
218 | static int dw_i2c_remove(struct platform_device *pdev) | 192 | static int dw_i2c_remove(struct platform_device *pdev) |
219 | { | 193 | { |
220 | struct dw_i2c_dev *dev = platform_get_drvdata(pdev); | 194 | struct dw_i2c_dev *dev = platform_get_drvdata(pdev); |
221 | struct resource *mem; | ||
222 | 195 | ||
223 | pm_runtime_get_sync(&pdev->dev); | 196 | pm_runtime_get_sync(&pdev->dev); |
224 | 197 | ||
225 | i2c_del_adapter(&dev->adapter); | 198 | i2c_del_adapter(&dev->adapter); |
226 | put_device(&pdev->dev); | 199 | put_device(&pdev->dev); |
227 | 200 | ||
228 | clk_disable_unprepare(dev->clk); | ||
229 | clk_put(dev->clk); | ||
230 | dev->clk = NULL; | ||
231 | |||
232 | i2c_dw_disable(dev); | 201 | i2c_dw_disable(dev); |
233 | free_irq(dev->irq, dev); | ||
234 | kfree(dev); | ||
235 | 202 | ||
236 | pm_runtime_put(&pdev->dev); | 203 | pm_runtime_put(&pdev->dev); |
237 | pm_runtime_disable(&pdev->dev); | 204 | pm_runtime_disable(&pdev->dev); |
238 | 205 | ||
239 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
240 | release_mem_region(mem->start, resource_size(mem)); | ||
241 | return 0; | 206 | return 0; |
242 | } | 207 | } |
243 | 208 | ||