aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2014-03-18 10:56:00 -0400
committerLee Jones <lee.jones@linaro.org>2014-03-19 05:00:07 -0400
commit3033ee62c0d40561835a6249db80c3eff3a52b0a (patch)
tree32f42b1e20a9d72136698901aca4ce587d254e67
parentb6ab7a8ffea526eb539f6508e3c4b9e47f04c4f2 (diff)
mfd: Remove obsolete ti-ssp driver
The tnetv107x platform is getting removed, so this driver is not needed any more. Signed-off-by: Arnd Bergmann <arnd@arndb.de> Acked-by: Sekhar Nori <nsekhar@ti.com> Acked-by: Kevin Hilman <khilman@linaro.org> Signed-off-by: Lee Jones <lee.jones@linaro.org>
-rw-r--r--drivers/mfd/Kconfig11
-rw-r--r--drivers/mfd/Makefile1
-rw-r--r--drivers/mfd/ti-ssp.c464
3 files changed, 0 insertions, 476 deletions
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 7587c9e1a519..33834120d057 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -789,17 +789,6 @@ config MFD_PALMAS
789 If you say yes here you get support for the Palmas 789 If you say yes here you get support for the Palmas
790 series of PMIC chips from Texas Instruments. 790 series of PMIC chips from Texas Instruments.
791 791
792config MFD_TI_SSP
793 tristate "TI Sequencer Serial Port support"
794 depends on ARCH_DAVINCI_TNETV107X
795 select MFD_CORE
796 ---help---
797 Say Y here if you want support for the Sequencer Serial Port
798 in a Texas Instruments TNETV107X SoC.
799
800 To compile this driver as a module, choose M here: the
801 module will be called ti-ssp.
802
803config TPS6105X 792config TPS6105X
804 tristate "TI TPS61050/61052 Boost Converters" 793 tristate "TI TPS61050/61052 Boost Converters"
805 depends on I2C 794 depends on I2C
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 23835dfa615c..2851275e2656 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -23,7 +23,6 @@ obj-$(CONFIG_HTC_I2CPLD) += htc-i2cpld.o
23 23
24obj-$(CONFIG_MFD_DAVINCI_VOICECODEC) += davinci_voicecodec.o 24obj-$(CONFIG_MFD_DAVINCI_VOICECODEC) += davinci_voicecodec.o
25obj-$(CONFIG_MFD_DM355EVM_MSP) += dm355evm_msp.o 25obj-$(CONFIG_MFD_DM355EVM_MSP) += dm355evm_msp.o
26obj-$(CONFIG_MFD_TI_SSP) += ti-ssp.o
27obj-$(CONFIG_MFD_TI_AM335X_TSCADC) += ti_am335x_tscadc.o 26obj-$(CONFIG_MFD_TI_AM335X_TSCADC) += ti_am335x_tscadc.o
28 27
29obj-$(CONFIG_MFD_STA2X11) += sta2x11-mfd.o 28obj-$(CONFIG_MFD_STA2X11) += sta2x11-mfd.o
diff --git a/drivers/mfd/ti-ssp.c b/drivers/mfd/ti-ssp.c
deleted file mode 100644
index 0769ecdd2b7f..000000000000
--- a/drivers/mfd/ti-ssp.c
+++ /dev/null
@@ -1,464 +0,0 @@
1/*
2 * Sequencer Serial Port (SSP) driver for Texas Instruments' SoCs
3 *
4 * Copyright (C) 2010 Texas Instruments Inc
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include <linux/errno.h>
22#include <linux/kernel.h>
23#include <linux/module.h>
24#include <linux/slab.h>
25#include <linux/err.h>
26#include <linux/wait.h>
27#include <linux/clk.h>
28#include <linux/interrupt.h>
29#include <linux/device.h>
30#include <linux/spinlock.h>
31#include <linux/platform_device.h>
32#include <linux/delay.h>
33#include <linux/io.h>
34#include <linux/sched.h>
35#include <linux/mfd/core.h>
36#include <linux/mfd/ti_ssp.h>
37
38/* Register Offsets */
39#define REG_REV 0x00
40#define REG_IOSEL_1 0x04
41#define REG_IOSEL_2 0x08
42#define REG_PREDIV 0x0c
43#define REG_INTR_ST 0x10
44#define REG_INTR_EN 0x14
45#define REG_TEST_CTRL 0x18
46
47/* Per port registers */
48#define PORT_CFG_2 0x00
49#define PORT_ADDR 0x04
50#define PORT_DATA 0x08
51#define PORT_CFG_1 0x0c
52#define PORT_STATE 0x10
53
54#define SSP_PORT_CONFIG_MASK (SSP_EARLY_DIN | SSP_DELAY_DOUT)
55#define SSP_PORT_CLKRATE_MASK 0x0f
56
57#define SSP_SEQRAM_WR_EN BIT(4)
58#define SSP_SEQRAM_RD_EN BIT(5)
59#define SSP_START BIT(15)
60#define SSP_BUSY BIT(10)
61#define SSP_PORT_ASL BIT(7)
62#define SSP_PORT_CFO1 BIT(6)
63
64#define SSP_PORT_SEQRAM_SIZE 32
65
66static const int ssp_port_base[] = {0x040, 0x080};
67static const int ssp_port_seqram[] = {0x100, 0x180};
68
69struct ti_ssp {
70 struct resource *res;
71 struct device *dev;
72 void __iomem *regs;
73 spinlock_t lock;
74 struct clk *clk;
75 int irq;
76 wait_queue_head_t wqh;
77
78 /*
79 * Some of the iosel2 register bits always read-back as 0, we need to
80 * remember these values so that we don't clobber previously set
81 * values.
82 */
83 u32 iosel2;
84};
85
86static inline struct ti_ssp *dev_to_ssp(struct device *dev)
87{
88 return dev_get_drvdata(dev->parent);
89}
90
91static inline int dev_to_port(struct device *dev)
92{
93 return to_platform_device(dev)->id;
94}
95
96/* Register Access Helpers, rmw() functions need to run locked */
97static inline u32 ssp_read(struct ti_ssp *ssp, int reg)
98{
99 return __raw_readl(ssp->regs + reg);
100}
101
102static inline void ssp_write(struct ti_ssp *ssp, int reg, u32 val)
103{
104 __raw_writel(val, ssp->regs + reg);
105}
106
107static inline void ssp_rmw(struct ti_ssp *ssp, int reg, u32 mask, u32 bits)
108{
109 ssp_write(ssp, reg, (ssp_read(ssp, reg) & ~mask) | bits);
110}
111
112static inline u32 ssp_port_read(struct ti_ssp *ssp, int port, int reg)
113{
114 return ssp_read(ssp, ssp_port_base[port] + reg);
115}
116
117static inline void ssp_port_write(struct ti_ssp *ssp, int port, int reg,
118 u32 val)
119{
120 ssp_write(ssp, ssp_port_base[port] + reg, val);
121}
122
123static inline void ssp_port_rmw(struct ti_ssp *ssp, int port, int reg,
124 u32 mask, u32 bits)
125{
126 ssp_rmw(ssp, ssp_port_base[port] + reg, mask, bits);
127}
128
129static inline void ssp_port_clr_bits(struct ti_ssp *ssp, int port, int reg,
130 u32 bits)
131{
132 ssp_port_rmw(ssp, port, reg, bits, 0);
133}
134
135static inline void ssp_port_set_bits(struct ti_ssp *ssp, int port, int reg,
136 u32 bits)
137{
138 ssp_port_rmw(ssp, port, reg, 0, bits);
139}
140
141/* Called to setup port clock mode, caller must hold ssp->lock */
142static int __set_mode(struct ti_ssp *ssp, int port, int mode)
143{
144 mode &= SSP_PORT_CONFIG_MASK;
145 ssp_port_rmw(ssp, port, PORT_CFG_1, SSP_PORT_CONFIG_MASK, mode);
146
147 return 0;
148}
149
150int ti_ssp_set_mode(struct device *dev, int mode)
151{
152 struct ti_ssp *ssp = dev_to_ssp(dev);
153 int port = dev_to_port(dev);
154 int ret;
155
156 spin_lock(&ssp->lock);
157 ret = __set_mode(ssp, port, mode);
158 spin_unlock(&ssp->lock);
159
160 return ret;
161}
162EXPORT_SYMBOL(ti_ssp_set_mode);
163
164/* Called to setup iosel2, caller must hold ssp->lock */
165static void __set_iosel2(struct ti_ssp *ssp, u32 mask, u32 val)
166{
167 ssp->iosel2 = (ssp->iosel2 & ~mask) | val;
168 ssp_write(ssp, REG_IOSEL_2, ssp->iosel2);
169}
170
171/* Called to setup port iosel, caller must hold ssp->lock */
172static void __set_iosel(struct ti_ssp *ssp, int port, u32 iosel)
173{
174 unsigned val, shift = port ? 16 : 0;
175
176 /* IOSEL1 gets the least significant 16 bits */
177 val = ssp_read(ssp, REG_IOSEL_1);
178 val &= 0xffff << (port ? 0 : 16);
179 val |= (iosel & 0xffff) << (port ? 16 : 0);
180 ssp_write(ssp, REG_IOSEL_1, val);
181
182 /* IOSEL2 gets the most significant 16 bits */
183 val = (iosel >> 16) & 0x7;
184 __set_iosel2(ssp, 0x7 << shift, val << shift);
185}
186
187int ti_ssp_set_iosel(struct device *dev, u32 iosel)
188{
189 struct ti_ssp *ssp = dev_to_ssp(dev);
190 int port = dev_to_port(dev);
191
192 spin_lock(&ssp->lock);
193 __set_iosel(ssp, port, iosel);
194 spin_unlock(&ssp->lock);
195
196 return 0;
197}
198EXPORT_SYMBOL(ti_ssp_set_iosel);
199
200int ti_ssp_load(struct device *dev, int offs, u32* prog, int len)
201{
202 struct ti_ssp *ssp = dev_to_ssp(dev);
203 int port = dev_to_port(dev);
204 int i;
205
206 if (len > SSP_PORT_SEQRAM_SIZE)
207 return -ENOSPC;
208
209 spin_lock(&ssp->lock);
210
211 /* Enable SeqRAM access */
212 ssp_port_set_bits(ssp, port, PORT_CFG_2, SSP_SEQRAM_WR_EN);
213
214 /* Copy code */
215 for (i = 0; i < len; i++) {
216 __raw_writel(prog[i], ssp->regs + offs + 4*i +
217 ssp_port_seqram[port]);
218 }
219
220 /* Disable SeqRAM access */
221 ssp_port_clr_bits(ssp, port, PORT_CFG_2, SSP_SEQRAM_WR_EN);
222
223 spin_unlock(&ssp->lock);
224
225 return 0;
226}
227EXPORT_SYMBOL(ti_ssp_load);
228
229int ti_ssp_raw_read(struct device *dev)
230{
231 struct ti_ssp *ssp = dev_to_ssp(dev);
232 int port = dev_to_port(dev);
233 int shift = port ? 27 : 11;
234
235 return (ssp_read(ssp, REG_IOSEL_2) >> shift) & 0xf;
236}
237EXPORT_SYMBOL(ti_ssp_raw_read);
238
239int ti_ssp_raw_write(struct device *dev, u32 val)
240{
241 struct ti_ssp *ssp = dev_to_ssp(dev);
242 int port = dev_to_port(dev), shift;
243
244 spin_lock(&ssp->lock);
245
246 shift = port ? 22 : 6;
247 val &= 0xf;
248 __set_iosel2(ssp, 0xf << shift, val << shift);
249
250 spin_unlock(&ssp->lock);
251
252 return 0;
253}
254EXPORT_SYMBOL(ti_ssp_raw_write);
255
256static inline int __xfer_done(struct ti_ssp *ssp, int port)
257{
258 return !(ssp_port_read(ssp, port, PORT_CFG_1) & SSP_BUSY);
259}
260
261int ti_ssp_run(struct device *dev, u32 pc, u32 input, u32 *output)
262{
263 struct ti_ssp *ssp = dev_to_ssp(dev);
264 int port = dev_to_port(dev);
265 int ret;
266
267 if (pc & ~(0x3f))
268 return -EINVAL;
269
270 /* Grab ssp->lock to serialize rmw on ssp registers */
271 spin_lock(&ssp->lock);
272
273 ssp_port_write(ssp, port, PORT_ADDR, input >> 16);
274 ssp_port_write(ssp, port, PORT_DATA, input & 0xffff);
275 ssp_port_rmw(ssp, port, PORT_CFG_1, 0x3f, pc);
276
277 /* grab wait queue head lock to avoid race with the isr */
278 spin_lock_irq(&ssp->wqh.lock);
279
280 /* kick off sequence execution in hardware */
281 ssp_port_set_bits(ssp, port, PORT_CFG_1, SSP_START);
282
283 /* drop ssp lock; no register writes beyond this */
284 spin_unlock(&ssp->lock);
285
286 ret = wait_event_interruptible_locked_irq(ssp->wqh,
287 __xfer_done(ssp, port));
288 spin_unlock_irq(&ssp->wqh.lock);
289
290 if (ret < 0)
291 return ret;
292
293 if (output) {
294 *output = (ssp_port_read(ssp, port, PORT_ADDR) << 16) |
295 (ssp_port_read(ssp, port, PORT_DATA) & 0xffff);
296 }
297
298 ret = ssp_port_read(ssp, port, PORT_STATE) & 0x3f; /* stop address */
299
300 return ret;
301}
302EXPORT_SYMBOL(ti_ssp_run);
303
304static irqreturn_t ti_ssp_interrupt(int irq, void *dev_data)
305{
306 struct ti_ssp *ssp = dev_data;
307
308 spin_lock(&ssp->wqh.lock);
309
310 ssp_write(ssp, REG_INTR_ST, 0x3);
311 wake_up_locked(&ssp->wqh);
312
313 spin_unlock(&ssp->wqh.lock);
314
315 return IRQ_HANDLED;
316}
317
318static int ti_ssp_probe(struct platform_device *pdev)
319{
320 static struct ti_ssp *ssp;
321 const struct ti_ssp_data *pdata = dev_get_platdata(&pdev->dev);
322 int error = 0, prediv = 0xff, id;
323 unsigned long sysclk;
324 struct device *dev = &pdev->dev;
325 struct mfd_cell cells[2];
326
327 ssp = kzalloc(sizeof(*ssp), GFP_KERNEL);
328 if (!ssp) {
329 dev_err(dev, "cannot allocate device info\n");
330 return -ENOMEM;
331 }
332
333 ssp->dev = dev;
334 dev_set_drvdata(dev, ssp);
335
336 ssp->res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
337 if (!ssp->res) {
338 error = -ENODEV;
339 dev_err(dev, "cannot determine register area\n");
340 goto error_res;
341 }
342
343 if (!request_mem_region(ssp->res->start, resource_size(ssp->res),
344 pdev->name)) {
345 error = -ENOMEM;
346 dev_err(dev, "cannot claim register memory\n");
347 goto error_res;
348 }
349
350 ssp->regs = ioremap(ssp->res->start, resource_size(ssp->res));
351 if (!ssp->regs) {
352 error = -ENOMEM;
353 dev_err(dev, "cannot map register memory\n");
354 goto error_map;
355 }
356
357 ssp->clk = clk_get(dev, NULL);
358 if (IS_ERR(ssp->clk)) {
359 error = PTR_ERR(ssp->clk);
360 dev_err(dev, "cannot claim device clock\n");
361 goto error_clk;
362 }
363
364 ssp->irq = platform_get_irq(pdev, 0);
365 if (ssp->irq < 0) {
366 error = -ENODEV;
367 dev_err(dev, "unknown irq\n");
368 goto error_irq;
369 }
370
371 error = request_threaded_irq(ssp->irq, NULL, ti_ssp_interrupt, 0,
372 dev_name(dev), ssp);
373 if (error < 0) {
374 dev_err(dev, "cannot acquire irq\n");
375 goto error_irq;
376 }
377
378 spin_lock_init(&ssp->lock);
379 init_waitqueue_head(&ssp->wqh);
380
381 /* Power on and initialize SSP */
382 error = clk_enable(ssp->clk);
383 if (error) {
384 dev_err(dev, "cannot enable device clock\n");
385 goto error_enable;
386 }
387
388 /* Reset registers to a sensible known state */
389 ssp_write(ssp, REG_IOSEL_1, 0);
390 ssp_write(ssp, REG_IOSEL_2, 0);
391 ssp_write(ssp, REG_INTR_EN, 0x3);
392 ssp_write(ssp, REG_INTR_ST, 0x3);
393 ssp_write(ssp, REG_TEST_CTRL, 0);
394 ssp_port_write(ssp, 0, PORT_CFG_1, SSP_PORT_ASL);
395 ssp_port_write(ssp, 1, PORT_CFG_1, SSP_PORT_ASL);
396 ssp_port_write(ssp, 0, PORT_CFG_2, SSP_PORT_CFO1);
397 ssp_port_write(ssp, 1, PORT_CFG_2, SSP_PORT_CFO1);
398
399 sysclk = clk_get_rate(ssp->clk);
400 if (pdata && pdata->out_clock)
401 prediv = (sysclk / pdata->out_clock) - 1;
402 prediv = clamp(prediv, 0, 0xff);
403 ssp_rmw(ssp, REG_PREDIV, 0xff, prediv);
404
405 memset(cells, 0, sizeof(cells));
406 for (id = 0; id < 2; id++) {
407 const struct ti_ssp_dev_data *data = &pdata->dev_data[id];
408
409 cells[id].id = id;
410 cells[id].name = data->dev_name;
411 cells[id].platform_data = data->pdata;
412 }
413
414 error = mfd_add_devices(dev, 0, cells, 2, NULL, 0, NULL);
415 if (error < 0) {
416 dev_err(dev, "cannot add mfd cells\n");
417 goto error_enable;
418 }
419
420 return 0;
421
422error_enable:
423 free_irq(ssp->irq, ssp);
424error_irq:
425 clk_put(ssp->clk);
426error_clk:
427 iounmap(ssp->regs);
428error_map:
429 release_mem_region(ssp->res->start, resource_size(ssp->res));
430error_res:
431 kfree(ssp);
432 return error;
433}
434
435static int ti_ssp_remove(struct platform_device *pdev)
436{
437 struct device *dev = &pdev->dev;
438 struct ti_ssp *ssp = dev_get_drvdata(dev);
439
440 mfd_remove_devices(dev);
441 clk_disable(ssp->clk);
442 free_irq(ssp->irq, ssp);
443 clk_put(ssp->clk);
444 iounmap(ssp->regs);
445 release_mem_region(ssp->res->start, resource_size(ssp->res));
446 kfree(ssp);
447 return 0;
448}
449
450static struct platform_driver ti_ssp_driver = {
451 .probe = ti_ssp_probe,
452 .remove = ti_ssp_remove,
453 .driver = {
454 .name = "ti-ssp",
455 .owner = THIS_MODULE,
456 }
457};
458
459module_platform_driver(ti_ssp_driver);
460
461MODULE_DESCRIPTION("Sequencer Serial Port (SSP) Driver");
462MODULE_AUTHOR("Cyril Chemparathy");
463MODULE_LICENSE("GPL");
464MODULE_ALIAS("platform:ti-ssp");