diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-05-02 17:38:53 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-05-02 17:38:53 -0400 |
commit | 99bece775f988a4ee21ad3db9fd413caf1704ff6 (patch) | |
tree | 5975cdcd92301e54dfe1424ec5d008898b5c9331 /drivers/i2c/busses/i2c-designware-platdrv.c | |
parent | 736a2dd2571ac56b11ed95a7814d838d5311be04 (diff) | |
parent | c39e8e4354ce4daf23336de5daa28a3b01f00aa6 (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.c | 83 |
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) | |||
56 | static int dw_i2c_acpi_configure(struct platform_device *pdev) | 56 | static 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 | |||
200 | err_free_irq: | ||
201 | free_irq(dev->irq, dev); | ||
202 | err_iounmap: | ||
203 | iounmap(dev->base); | ||
204 | err_unuse_clocks: | ||
205 | clk_disable_unprepare(dev->clk); | ||
206 | clk_put(dev->clk); | ||
207 | dev->clk = NULL; | ||
208 | err_free_mem: | ||
209 | put_device(&pdev->dev); | ||
210 | kfree(dev); | ||
211 | err_release_region: | ||
212 | release_mem_region(mem->start, resource_size(mem)); | ||
213 | |||
214 | return r; | ||
215 | } | 178 | } |
216 | 179 | ||
217 | static int dw_i2c_remove(struct platform_device *pdev) | 180 | static 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 | ||