1 --- a/drivers/vlynq/vlynq.c 2009-05-31 20:41:57.000000000 +0200
2 +++ b/drivers/vlynq/vlynq.c 2009-07-28 21:27:52.000000000 +0200
4 * You should have received a copy of the GNU General Public License
5 * along with this program; if not, write to the Free Software
6 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
8 + * Parts of the VLYNQ specification can be found here:
9 + * http://www.ti.com/litv/pdf/sprue36a
12 #include <linux/init.h>
14 #include <linux/errno.h>
15 #include <linux/platform_device.h>
16 #include <linux/interrupt.h>
17 -#include <linux/device.h>
18 #include <linux/delay.h>
25 -#define vlynq_reg_read(reg) readl(&(reg))
26 -#define vlynq_reg_write(reg, val) writel(val, &(reg))
28 -static int __vlynq_enable_device(struct vlynq_device *dev);
31 +#ifdef CONFIG_VLYNQ_DEBUG
32 static void vlynq_dump_regs(struct vlynq_device *dev)
36 printk(KERN_DEBUG "VLYNQ local=%p remote=%p\n",
37 dev->local, dev->remote);
38 for (i = 0; i < 32; i++) {
40 static void vlynq_dump_mem(u32 *base, int count)
44 for (i = 0; i < (count + 3) / 4; i++) {
45 - if (i % 4 == 0) printk(KERN_DEBUG "\nMEM[0x%04x]:", i * 4);
47 + printk(KERN_DEBUG "\nMEM[0x%04x]:", i * 4);
48 printk(KERN_DEBUG " 0x%08x", *(base + i));
50 printk(KERN_DEBUG "\n");
54 -int vlynq_linked(struct vlynq_device *dev)
55 +/* Check the VLYNQ link status with a given device */
56 +static int vlynq_linked(struct vlynq_device *dev)
60 for (i = 0; i < 100; i++)
61 - if (vlynq_reg_read(dev->local->status) & VLYNQ_STATUS_LINK)
62 + if (readl(&dev->local->status) & VLYNQ_STATUS_LINK)
68 static void vlynq_reset(struct vlynq_device *dev)
70 - vlynq_reg_write(dev->local->control,
71 - vlynq_reg_read(dev->local->control) |
73 + writel(readl(&dev->local->control) | VLYNQ_CTRL_RESET,
74 + &dev->local->control);
76 /* Wait for the devices to finish resetting */
79 /* Remove reset bit */
80 - vlynq_reg_write(dev->local->control,
81 - vlynq_reg_read(dev->local->control) &
83 + writel(readl(&dev->local->control) & ~VLYNQ_CTRL_RESET,
84 + &dev->local->control);
86 /* Give some time for the devices to settle */
91 virq = irq - dev->irq_start;
92 - val = vlynq_reg_read(dev->remote->int_device[virq >> 2]);
93 + val = readl(&dev->remote->int_device[virq >> 2]);
94 val |= (VINT_ENABLE | virq) << VINT_OFFSET(virq);
95 - vlynq_reg_write(dev->remote->int_device[virq >> 2], val);
96 + writel(val, &dev->remote->int_device[virq >> 2]);
99 static void vlynq_irq_mask(unsigned int irq)
103 virq = irq - dev->irq_start;
104 - val = vlynq_reg_read(dev->remote->int_device[virq >> 2]);
105 + val = readl(&dev->remote->int_device[virq >> 2]);
106 val &= ~(VINT_ENABLE << VINT_OFFSET(virq));
107 - vlynq_reg_write(dev->remote->int_device[virq >> 2], val);
108 + writel(val, &dev->remote->int_device[virq >> 2]);
111 static int vlynq_irq_type(unsigned int irq, unsigned int flow_type)
115 virq = irq - dev->irq_start;
116 - val = vlynq_reg_read(dev->remote->int_device[virq >> 2]);
117 + val = readl(&dev->remote->int_device[virq >> 2]);
118 switch (flow_type & IRQ_TYPE_SENSE_MASK) {
119 case IRQ_TYPE_EDGE_RISING:
120 case IRQ_TYPE_EDGE_FALLING:
121 @@ -187,28 +186,30 @@
125 - vlynq_reg_write(dev->remote->int_device[virq >> 2], val);
126 + writel(val, &dev->remote->int_device[virq >> 2]);
130 static void vlynq_local_ack(unsigned int irq)
132 struct vlynq_device *dev = get_irq_chip_data(irq);
133 - u32 status = vlynq_reg_read(dev->local->status);
134 - if (printk_ratelimit())
135 - printk(KERN_DEBUG "%s: local status: 0x%08x\n",
136 - dev->dev.bus_id, status);
137 - vlynq_reg_write(dev->local->status, status);
139 + u32 status = readl(&dev->local->status);
141 + pr_debug("%s: local status: 0x%08x\n",
142 + dev_name(&dev->dev), status);
143 + writel(status, &dev->local->status);
146 static void vlynq_remote_ack(unsigned int irq)
148 struct vlynq_device *dev = get_irq_chip_data(irq);
149 - u32 status = vlynq_reg_read(dev->remote->status);
150 - if (printk_ratelimit())
151 - printk(KERN_DEBUG "%s: remote status: 0x%08x\n",
152 - dev->dev.bus_id, status);
153 - vlynq_reg_write(dev->remote->status, status);
155 + u32 status = readl(&dev->remote->status);
157 + pr_debug("%s: remote status: 0x%08x\n",
158 + dev_name(&dev->dev), status);
159 + writel(status, &dev->remote->status);
162 static irqreturn_t vlynq_irq(int irq, void *dev_id)
167 - status = vlynq_reg_read(dev->local->int_status);
168 - vlynq_reg_write(dev->local->int_status, status);
169 + status = readl(&dev->local->int_status);
170 + writel(status, &dev->local->int_status);
172 if (unlikely(!status))
173 spurious_interrupt();
174 @@ -262,28 +263,28 @@
175 if (dev->local_irq == dev->remote_irq) {
177 "%s: local vlynq irq should be different from remote\n",
179 + dev_name(&dev->dev));
183 /* Clear local and remote error bits */
184 - vlynq_reg_write(dev->local->status, vlynq_reg_read(dev->local->status));
185 - vlynq_reg_write(dev->remote->status,
186 - vlynq_reg_read(dev->remote->status));
187 + writel(readl(&dev->local->status), &dev->local->status);
188 + writel(readl(&dev->remote->status), &dev->remote->status);
190 /* Now setup interrupts */
191 val = VLYNQ_CTRL_INT_VECTOR(dev->local_irq);
192 val |= VLYNQ_CTRL_INT_ENABLE | VLYNQ_CTRL_INT_LOCAL |
194 - val |= vlynq_reg_read(dev->local->control);
195 - vlynq_reg_write(dev->local->int_ptr, VLYNQ_INT_OFFSET);
196 - vlynq_reg_write(dev->local->control, val);
197 + val |= readl(&dev->local->control);
198 + writel(VLYNQ_INT_OFFSET, &dev->local->int_ptr);
199 + writel(val, &dev->local->control);
201 val = VLYNQ_CTRL_INT_VECTOR(dev->remote_irq);
202 val |= VLYNQ_CTRL_INT_ENABLE;
203 - val |= vlynq_reg_read(dev->remote->control);
204 - vlynq_reg_write(dev->remote->int_ptr, VLYNQ_INT_OFFSET);
205 - vlynq_reg_write(dev->remote->control, val);
206 + val |= readl(&dev->remote->control);
207 + writel(VLYNQ_INT_OFFSET, &dev->remote->int_ptr);
208 + writel(val, &dev->remote->int_ptr);
209 + writel(val, &dev->remote->control);
211 for (i = dev->irq_start; i <= dev->irq_end; i++) {
212 virq = i - dev->irq_start;
213 @@ -299,12 +300,13 @@
214 set_irq_chip_and_handler(i, &vlynq_irq_chip,
216 set_irq_chip_data(i, dev);
217 - vlynq_reg_write(dev->remote->int_device[virq >> 2], 0);
218 + writel(0, &dev->remote->int_device[virq >> 2]);
222 if (request_irq(dev->irq, vlynq_irq, IRQF_SHARED, "vlynq", dev)) {
223 - printk(KERN_ERR "%s: request_irq failed\n", dev->dev.bus_id);
224 + printk(KERN_ERR "%s: request_irq failed\n",
225 + dev_name(&dev->dev));
229 @@ -328,11 +330,11 @@
230 if (ids->id == vdev->dev_id) {
231 vdev->divisor = ids->divisor;
232 vlynq_set_drvdata(vdev, ids);
233 - printk(KERN_INFO "Driver found for VLYNQ " \
234 + printk(KERN_INFO "Driver found for VLYNQ "
235 "device: %08x\n", vdev->dev_id);
238 - printk(KERN_DEBUG "Not using the %08x VLYNQ device's driver" \
239 + printk(KERN_DEBUG "Not using the %08x VLYNQ device's driver"
240 " for VLYNQ device: %08x\n", ids->id, vdev->dev_id);
244 struct vlynq_device_id *id = vlynq_get_drvdata(vdev);
245 int result = -ENODEV;
248 - if (drv && drv->probe)
250 result = drv->probe(vdev, id);
254 static int vlynq_device_remove(struct device *dev)
256 struct vlynq_driver *drv = to_vlynq_driver(dev->driver);
257 - if (drv && drv->remove)
260 drv->remove(to_vlynq_device(dev));
268 EXPORT_SYMBOL(vlynq_unregister_driver);
271 + * A VLYNQ remote device can clock the VLYNQ bus master
272 + * using a dedicated clock line. In that case, both the
273 + * remove device and the bus master should have the same
274 + * serial clock dividers configured. Iterate through the
275 + * 8 possible dividers until we actually link with the
278 static int __vlynq_try_remote(struct vlynq_device *dev)
281 @@ -389,21 +399,21 @@
282 if (!vlynq_linked(dev))
285 - vlynq_reg_write(dev->remote->control,
286 - (vlynq_reg_read(dev->remote->control) &
287 + writel((readl(&dev->remote->control) &
288 ~VLYNQ_CTRL_CLOCK_MASK) |
289 VLYNQ_CTRL_CLOCK_INT |
290 - VLYNQ_CTRL_CLOCK_DIV(i - vlynq_rdiv1));
291 - vlynq_reg_write(dev->local->control,
292 - ((vlynq_reg_read(dev->local->control)
293 + VLYNQ_CTRL_CLOCK_DIV(i - vlynq_rdiv1),
294 + &dev->remote->control);
295 + writel((readl(&dev->local->control)
296 & ~(VLYNQ_CTRL_CLOCK_INT |
297 VLYNQ_CTRL_CLOCK_MASK)) |
298 - VLYNQ_CTRL_CLOCK_DIV(i - vlynq_rdiv1)));
299 + VLYNQ_CTRL_CLOCK_DIV(i - vlynq_rdiv1),
300 + &dev->local->control);
302 if (vlynq_linked(dev)) {
304 "%s: using remote clock divisor %d\n",
305 - dev->dev.bus_id, i - vlynq_rdiv1 + 1);
306 + dev_name(&dev->dev), i - vlynq_rdiv1 + 1);
310 @@ -414,26 +424,33 @@
315 + * A VLYNQ remote device can be clocked by the VLYNQ bus
316 + * master using a dedicated clock line. In that case, only
317 + * the bus master configures the serial clock divider.
318 + * Iterate through the 8 possible dividers until we
319 + * actually get a link with the device.
321 static int __vlynq_try_local(struct vlynq_device *dev)
328 for (i = dev->dev_id ? vlynq_ldiv2 : vlynq_ldiv8; dev->dev_id ?
329 i <= vlynq_ldiv8 : i >= vlynq_ldiv2;
330 dev->dev_id ? i++ : i--) {
332 - vlynq_reg_write(dev->local->control,
333 - (vlynq_reg_read(dev->local->control) &
334 + writel((readl(&dev->local->control) &
335 ~VLYNQ_CTRL_CLOCK_MASK) |
336 VLYNQ_CTRL_CLOCK_INT |
337 - VLYNQ_CTRL_CLOCK_DIV(i - vlynq_ldiv1));
338 + VLYNQ_CTRL_CLOCK_DIV(i - vlynq_ldiv1),
339 + &dev->local->control);
341 if (vlynq_linked(dev)) {
343 "%s: using local clock divisor %d\n",
344 - dev->dev.bus_id, i - vlynq_ldiv1 + 1);
345 + dev_name(&dev->dev), i - vlynq_ldiv1 + 1);
349 @@ -444,27 +461,33 @@
354 + * When using external clocking method, serial clock
355 + * is supplied by an external oscillator, therefore we
356 + * should mask the local clock bit in the clock control
357 + * register for both the bus master and the remote device.
359 static int __vlynq_try_external(struct vlynq_device *dev)
362 if (!vlynq_linked(dev))
365 - vlynq_reg_write(dev->remote->control,
366 - (vlynq_reg_read(dev->remote->control) &
367 - ~VLYNQ_CTRL_CLOCK_INT));
369 - vlynq_reg_write(dev->local->control,
370 - (vlynq_reg_read(dev->local->control) &
371 - ~VLYNQ_CTRL_CLOCK_INT));
372 + writel((readl(&dev->remote->control) &
373 + ~VLYNQ_CTRL_CLOCK_INT),
374 + &dev->remote->control);
376 + writel((readl(&dev->local->control) &
377 + ~VLYNQ_CTRL_CLOCK_INT),
378 + &dev->local->control);
380 if (vlynq_linked(dev)) {
381 printk(KERN_DEBUG "%s: using external clock\n",
383 + dev_name(&dev->dev));
384 dev->divisor = vlynq_div_external;
392 @@ -481,10 +504,10 @@
393 case vlynq_div_external:
395 /* When the device is brought from reset it should have clock
396 - generation negotiated by hardware.
397 - Check which device is generating clocks and perform setup
399 - if (vlynq_linked(dev) && vlynq_reg_read(dev->remote->control) &
400 + * generation negotiated by hardware.
401 + * Check which device is generating clocks and perform setup
403 + if (vlynq_linked(dev) && readl(&dev->remote->control) &
404 VLYNQ_CTRL_CLOCK_INT) {
405 if (!__vlynq_try_remote(dev) ||
406 !__vlynq_try_local(dev) ||
407 @@ -497,31 +520,43 @@
411 - case vlynq_ldiv1: case vlynq_ldiv2: case vlynq_ldiv3: case vlynq_ldiv4:
412 - case vlynq_ldiv5: case vlynq_ldiv6: case vlynq_ldiv7: case vlynq_ldiv8:
413 - vlynq_reg_write(dev->local->control,
414 - VLYNQ_CTRL_CLOCK_INT |
415 - VLYNQ_CTRL_CLOCK_DIV(dev->divisor -
417 - vlynq_reg_write(dev->remote->control, 0);
426 + writel(VLYNQ_CTRL_CLOCK_INT |
427 + VLYNQ_CTRL_CLOCK_DIV(dev->divisor -
428 + vlynq_ldiv1), &dev->local->control);
429 + writel(0, &dev->remote->control);
430 if (vlynq_linked(dev)) {
432 - "%s: using local clock divisor %d\n",
433 - dev->dev.bus_id, dev->divisor - vlynq_ldiv1 + 1);
434 + "%s: using local clock divisor %d\n",
435 + dev_name(&dev->dev),
436 + dev->divisor - vlynq_ldiv1 + 1);
440 - case vlynq_rdiv1: case vlynq_rdiv2: case vlynq_rdiv3: case vlynq_rdiv4:
441 - case vlynq_rdiv5: case vlynq_rdiv6: case vlynq_rdiv7: case vlynq_rdiv8:
442 - vlynq_reg_write(dev->local->control, 0);
443 - vlynq_reg_write(dev->remote->control,
444 - VLYNQ_CTRL_CLOCK_INT |
445 - VLYNQ_CTRL_CLOCK_DIV(dev->divisor -
455 + writel(0, &dev->local->control);
456 + writel(VLYNQ_CTRL_CLOCK_INT |
457 + VLYNQ_CTRL_CLOCK_DIV(dev->divisor -
458 + vlynq_rdiv1), &dev->remote->control);
459 if (vlynq_linked(dev)) {
461 - "%s: using remote clock divisor %d\n",
462 - dev->dev.bus_id, dev->divisor - vlynq_rdiv1 + 1);
463 + "%s: using remote clock divisor %d\n",
464 + dev_name(&dev->dev),
465 + dev->divisor - vlynq_rdiv1 + 1);
469 @@ -568,12 +603,10 @@
473 - vlynq_reg_write(dev->local->tx_offset, tx_offset);
474 + writel(tx_offset, &dev->local->tx_offset);
475 for (i = 0; i < 4; i++) {
476 - vlynq_reg_write(dev->local->rx_mapping[i].offset,
477 - mapping[i].offset);
478 - vlynq_reg_write(dev->local->rx_mapping[i].size,
480 + writel(mapping[i].offset, &dev->local->rx_mapping[i].offset);
481 + writel(mapping[i].size, &dev->local->rx_mapping[i].size);
485 @@ -587,12 +620,10 @@
489 - vlynq_reg_write(dev->remote->tx_offset, tx_offset);
490 + writel(tx_offset, &dev->remote->tx_offset);
491 for (i = 0; i < 4; i++) {
492 - vlynq_reg_write(dev->remote->rx_mapping[i].offset,
493 - mapping[i].offset);
494 - vlynq_reg_write(dev->remote->rx_mapping[i].size,
496 + writel(mapping[i].offset, &dev->remote->rx_mapping[i].offset);
497 + writel(mapping[i].size, &dev->remote->rx_mapping[i].size);
503 dev->dev.bus = &vlynq_bus_type;
504 dev->dev.parent = &pdev->dev;
505 - snprintf(dev->dev.bus_id, BUS_ID_SIZE, "vlynq%d", dev->id);
506 - dev->dev.bus_id[BUS_ID_SIZE - 1] = 0;
507 + dev_set_name(&dev->dev, "vlynq%d", dev->id);
508 dev->dev.platform_data = pdev->dev.platform_data;
509 dev->dev.release = vlynq_device_release;
512 dev->mem_end = mem_res->end;
514 len = regs_res->end - regs_res->start;
515 - if (!request_mem_region(regs_res->start, len, dev->dev.bus_id)) {
516 + if (!request_mem_region(regs_res->start, len, dev_name(&dev->dev))) {
517 printk(KERN_ERR "%s: Can't request vlynq registers\n",
519 + dev_name(&dev->dev));
524 dev->local = ioremap(regs_res->start, len);
526 printk(KERN_ERR "%s: Can't remap vlynq registers\n",
528 + dev_name(&dev->dev));
532 @@ -702,14 +732,14 @@
533 platform_set_drvdata(pdev, dev);
535 printk(KERN_INFO "%s: regs 0x%p, irq %d, mem 0x%p\n",
536 - dev->dev.bus_id, (void *)dev->regs_start, dev->irq,
537 + dev_name(&dev->dev), (void *)dev->regs_start, dev->irq,
538 (void *)dev->mem_start);
541 dev->divisor = vlynq_div_auto;
542 result = __vlynq_enable_device(dev);
544 - dev->dev_id = vlynq_reg_read(dev->remote->chip);
545 + dev->dev_id = readl(&dev->remote->chip);
546 ((struct plat_vlynq_ops *)(dev->dev.platform_data))->off(dev);