aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/busses/i2c-designware-platdrv.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-05-02 17:38:53 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-05-02 17:38:53 -0400
commit99bece775f988a4ee21ad3db9fd413caf1704ff6 (patch)
tree5975cdcd92301e54dfe1424ec5d008898b5c9331 /drivers/i2c/busses/i2c-designware-platdrv.c
parent736a2dd2571ac56b11ed95a7814d838d5311be04 (diff)
parentc39e8e4354ce4daf23336de5daa28a3b01f00aa6 (diff)
Merge branch 'i2c/for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux
Pull i2c changes from Wolfram Sang: - an arbitration driver. While the driver is quite simple, it caused discussion if we need additional arbitration on top of the one specified in the I2C standard. Conclusion is that I accept a few generic mechanisms, but not very specific ones. - the core lost the detach_adapter() call. It has no users anymore and was in the way for other cleanups. attach_adapter() is sadly still there since there are users waiting to be converted. - the core gained a bus recovery infrastructure. I2C defines a way to recover if the data line is stalled. This mechanism is now in the core and drivers can now pass some data to make use of it. - bigger driver cleanups for designware, s3c2410 - removing superfluous refcounting from drivers - removing Ben Dooks as second maintainer due to inactivity. Thanks for all your work so far, Ben! - bugfixes, feature additions, devicetree fixups, simplifications... * 'i2c/for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux: (38 commits) i2c: xiic: must always write 16-bit words to TX_FIFO i2c: octeon: use HZ in timeout value i2c: octeon: Fix i2c fail problem when a process is terminated by a signal i2c: designware-pci: drop superfluous {get|put}_device i2c: designware-plat: drop superfluous {get|put}_device i2c: davinci: drop superfluous {get|put}_device MAINTAINERS: Ben Dooks is inactive regarding I2C i2c: mux: Add i2c-arb-gpio-challenge 'mux' driver i2c: at91: convert to dma_request_slave_channel_compat() i2c: mxs: do error checking and handling in PIO mode i2c: mxs: remove races in PIO code i2c-designware: switch to use runtime PM autosuspend i2c-designware: use usleep_range() in the busy-loop i2c-designware: enable/disable the controller properly i2c-designware: use dynamic adapter numbering on Lynxpoint i2c-designware-pci: use managed functions pcim_* and devm_* i2c-designware-pci: use dev_err() instead of printk() i2c-designware: move to managed functions (devm_*) i2c: remove CONFIG_HOTPLUG ifdefs i2c: s3c2410: Add SMBus emulation for block read ...
Diffstat (limited to 'drivers/i2c/busses/i2c-designware-platdrv.c')
-rw-r--r--drivers/i2c/busses/i2c-designware-platdrv.c83
1 files changed, 18 insertions, 65 deletions
diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c
index e3085c487ace..8ec91335d95a 100644
--- a/drivers/i2c/busses/i2c-designware-platdrv.c
+++ b/drivers/i2c/busses/i2c-designware-platdrv.c
@@ -56,20 +56,11 @@ static u32 i2c_dw_get_clk_rate_khz(struct dw_i2c_dev *dev)
56static int dw_i2c_acpi_configure(struct platform_device *pdev) 56static int dw_i2c_acpi_configure(struct platform_device *pdev)
57{ 57{
58 struct dw_i2c_dev *dev = platform_get_drvdata(pdev); 58 struct dw_i2c_dev *dev = platform_get_drvdata(pdev);
59 struct acpi_device *adev;
60 int busno, ret;
61 59
62 if (!ACPI_HANDLE(&pdev->dev)) 60 if (!ACPI_HANDLE(&pdev->dev))
63 return -ENODEV; 61 return -ENODEV;
64 62
65 ret = acpi_bus_get_device(ACPI_HANDLE(&pdev->dev), &adev);
66 if (ret)
67 return -ENODEV;
68
69 dev->adapter.nr = -1; 63 dev->adapter.nr = -1;
70 if (adev->pnp.unique_id && !kstrtoint(adev->pnp.unique_id, 0, &busno))
71 dev->adapter.nr = busno;
72
73 dev->tx_fifo_depth = 32; 64 dev->tx_fifo_depth = 32;
74 dev->rx_fifo_depth = 32; 65 dev->rx_fifo_depth = 32;
75 return 0; 66 return 0;
@@ -92,7 +83,7 @@ static int dw_i2c_probe(struct platform_device *pdev)
92{ 83{
93 struct dw_i2c_dev *dev; 84 struct dw_i2c_dev *dev;
94 struct i2c_adapter *adap; 85 struct i2c_adapter *adap;
95 struct resource *mem, *ioarea; 86 struct resource *mem;
96 int irq, r; 87 int irq, r;
97 88
98 /* NOTE: driver uses the static register mapping */ 89 /* NOTE: driver uses the static register mapping */
@@ -108,32 +99,25 @@ static int dw_i2c_probe(struct platform_device *pdev)
108 return irq; /* -ENXIO */ 99 return irq; /* -ENXIO */
109 } 100 }
110 101
111 ioarea = request_mem_region(mem->start, resource_size(mem), 102 dev = devm_kzalloc(&pdev->dev, sizeof(struct dw_i2c_dev), GFP_KERNEL);
112 pdev->name); 103 if (!dev)
113 if (!ioarea) { 104 return -ENOMEM;
114 dev_err(&pdev->dev, "I2C region already claimed\n");
115 return -EBUSY;
116 }
117 105
118 dev = kzalloc(sizeof(struct dw_i2c_dev), GFP_KERNEL); 106 dev->base = devm_ioremap_resource(&pdev->dev, mem);
119 if (!dev) { 107 if (IS_ERR(dev->base))
120 r = -ENOMEM; 108 return PTR_ERR(dev->base);
121 goto err_release_region;
122 }
123 109
124 init_completion(&dev->cmd_complete); 110 init_completion(&dev->cmd_complete);
125 mutex_init(&dev->lock); 111 mutex_init(&dev->lock);
126 dev->dev = get_device(&pdev->dev); 112 dev->dev = &pdev->dev;
127 dev->irq = irq; 113 dev->irq = irq;
128 platform_set_drvdata(pdev, dev); 114 platform_set_drvdata(pdev, dev);
129 115
130 dev->clk = clk_get(&pdev->dev, NULL); 116 dev->clk = devm_clk_get(&pdev->dev, NULL);
131 dev->get_clk_rate_khz = i2c_dw_get_clk_rate_khz; 117 dev->get_clk_rate_khz = i2c_dw_get_clk_rate_khz;
132 118
133 if (IS_ERR(dev->clk)) { 119 if (IS_ERR(dev->clk))
134 r = -ENODEV; 120 return PTR_ERR(dev->clk);
135 goto err_free_mem;
136 }
137 clk_prepare_enable(dev->clk); 121 clk_prepare_enable(dev->clk);
138 122
139 dev->functionality = 123 dev->functionality =
@@ -146,13 +130,6 @@ static int dw_i2c_probe(struct platform_device *pdev)
146 dev->master_cfg = DW_IC_CON_MASTER | DW_IC_CON_SLAVE_DISABLE | 130 dev->master_cfg = DW_IC_CON_MASTER | DW_IC_CON_SLAVE_DISABLE |
147 DW_IC_CON_RESTART_EN | DW_IC_CON_SPEED_FAST; 131 DW_IC_CON_RESTART_EN | DW_IC_CON_SPEED_FAST;
148 132
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 */ 133 /* Try first if we can configure the device from ACPI */
157 r = dw_i2c_acpi_configure(pdev); 134 r = dw_i2c_acpi_configure(pdev);
158 if (r) { 135 if (r) {
@@ -164,13 +141,14 @@ static int dw_i2c_probe(struct platform_device *pdev)
164 } 141 }
165 r = i2c_dw_init(dev); 142 r = i2c_dw_init(dev);
166 if (r) 143 if (r)
167 goto err_iounmap; 144 return r;
168 145
169 i2c_dw_disable_int(dev); 146 i2c_dw_disable_int(dev);
170 r = request_irq(dev->irq, i2c_dw_isr, IRQF_SHARED, pdev->name, dev); 147 r = devm_request_irq(&pdev->dev, dev->irq, i2c_dw_isr, IRQF_SHARED,
148 pdev->name, dev);
171 if (r) { 149 if (r) {
172 dev_err(&pdev->dev, "failure requesting irq %i\n", dev->irq); 150 dev_err(&pdev->dev, "failure requesting irq %i\n", dev->irq);
173 goto err_iounmap; 151 return r;
174 } 152 }
175 153
176 adap = &dev->adapter; 154 adap = &dev->adapter;
@@ -186,57 +164,32 @@ static int dw_i2c_probe(struct platform_device *pdev)
186 r = i2c_add_numbered_adapter(adap); 164 r = i2c_add_numbered_adapter(adap);
187 if (r) { 165 if (r) {
188 dev_err(&pdev->dev, "failure adding adapter\n"); 166 dev_err(&pdev->dev, "failure adding adapter\n");
189 goto err_free_irq; 167 return r;
190 } 168 }
191 of_i2c_register_devices(adap); 169 of_i2c_register_devices(adap);
192 acpi_i2c_register_devices(adap); 170 acpi_i2c_register_devices(adap);
193 171
172 pm_runtime_set_autosuspend_delay(&pdev->dev, 1000);
173 pm_runtime_use_autosuspend(&pdev->dev);
194 pm_runtime_set_active(&pdev->dev); 174 pm_runtime_set_active(&pdev->dev);
195 pm_runtime_enable(&pdev->dev); 175 pm_runtime_enable(&pdev->dev);
196 pm_runtime_put(&pdev->dev);
197 176
198 return 0; 177 return 0;
199
200err_free_irq:
201 free_irq(dev->irq, dev);
202err_iounmap:
203 iounmap(dev->base);
204err_unuse_clocks:
205 clk_disable_unprepare(dev->clk);
206 clk_put(dev->clk);
207 dev->clk = NULL;
208err_free_mem:
209 put_device(&pdev->dev);
210 kfree(dev);
211err_release_region:
212 release_mem_region(mem->start, resource_size(mem));
213
214 return r;
215} 178}
216 179
217static int dw_i2c_remove(struct platform_device *pdev) 180static int dw_i2c_remove(struct platform_device *pdev)
218{ 181{
219 struct dw_i2c_dev *dev = platform_get_drvdata(pdev); 182 struct dw_i2c_dev *dev = platform_get_drvdata(pdev);
220 struct resource *mem;
221 183
222 pm_runtime_get_sync(&pdev->dev); 184 pm_runtime_get_sync(&pdev->dev);
223 185
224 i2c_del_adapter(&dev->adapter); 186 i2c_del_adapter(&dev->adapter);
225 put_device(&pdev->dev);
226
227 clk_disable_unprepare(dev->clk);
228 clk_put(dev->clk);
229 dev->clk = NULL;
230 187
231 i2c_dw_disable(dev); 188 i2c_dw_disable(dev);
232 free_irq(dev->irq, dev);
233 kfree(dev);
234 189
235 pm_runtime_put(&pdev->dev); 190 pm_runtime_put(&pdev->dev);
236 pm_runtime_disable(&pdev->dev); 191 pm_runtime_disable(&pdev->dev);
237 192
238 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
239 release_mem_region(mem->start, resource_size(mem));
240 return 0; 193 return 0;
241} 194}
242 195