Lines Matching +full:remote +full:- +full:bus

1 // SPDX-License-Identifier: GPL-2.0-or-later
72 printk(KERN_DEBUG "VLYNQ local=%p remote=%p\n", in vlynq_dump_regs()
73 dev->local, dev->remote); in vlynq_dump_regs()
76 i + 1, ((u32 *)dev->local)[i]); in vlynq_dump_regs()
77 printk(KERN_DEBUG "VLYNQ: remote %d: %08x\n", in vlynq_dump_regs()
78 i + 1, ((u32 *)dev->remote)[i]); in vlynq_dump_regs()
101 if (readl(&dev->local->status) & VLYNQ_STATUS_LINK) in vlynq_linked()
111 writel(readl(&dev->local->control) | VLYNQ_CTRL_RESET, in vlynq_reset()
112 &dev->local->control); in vlynq_reset()
118 writel(readl(&dev->local->control) & ~VLYNQ_CTRL_RESET, in vlynq_reset()
119 &dev->local->control); in vlynq_reset()
132 virq = d->irq - dev->irq_start; in vlynq_irq_unmask()
133 val = readl(&dev->remote->int_device[virq >> 2]); in vlynq_irq_unmask()
135 writel(val, &dev->remote->int_device[virq >> 2]); in vlynq_irq_unmask()
145 virq = d->irq - dev->irq_start; in vlynq_irq_mask()
146 val = readl(&dev->remote->int_device[virq >> 2]); in vlynq_irq_mask()
148 writel(val, &dev->remote->int_device[virq >> 2]); in vlynq_irq_mask()
158 virq = d->irq - dev->irq_start; in vlynq_irq_type()
159 val = readl(&dev->remote->int_device[virq >> 2]); in vlynq_irq_type()
176 return -EINVAL; in vlynq_irq_type()
178 writel(val, &dev->remote->int_device[virq >> 2]); in vlynq_irq_type()
185 u32 status = readl(&dev->local->status); in vlynq_local_ack()
188 dev_name(&dev->dev), status); in vlynq_local_ack()
189 writel(status, &dev->local->status); in vlynq_local_ack()
195 u32 status = readl(&dev->remote->status); in vlynq_remote_ack()
197 pr_debug("%s: remote status: 0x%08x\n", in vlynq_remote_ack()
198 dev_name(&dev->dev), status); in vlynq_remote_ack()
199 writel(status, &dev->remote->status); in vlynq_remote_ack()
208 status = readl(&dev->local->int_status); in vlynq_irq()
209 writel(status, &dev->local->int_status); in vlynq_irq()
216 do_IRQ(dev->irq_start + virq); in vlynq_irq()
250 if (dev->local_irq == dev->remote_irq) { in vlynq_setup_irq()
252 "%s: local vlynq irq should be different from remote\n", in vlynq_setup_irq()
253 dev_name(&dev->dev)); in vlynq_setup_irq()
254 return -EINVAL; in vlynq_setup_irq()
257 /* Clear local and remote error bits */ in vlynq_setup_irq()
258 writel(readl(&dev->local->status), &dev->local->status); in vlynq_setup_irq()
259 writel(readl(&dev->remote->status), &dev->remote->status); in vlynq_setup_irq()
262 val = VLYNQ_CTRL_INT_VECTOR(dev->local_irq); in vlynq_setup_irq()
265 val |= readl(&dev->local->control); in vlynq_setup_irq()
266 writel(VLYNQ_INT_OFFSET, &dev->local->int_ptr); in vlynq_setup_irq()
267 writel(val, &dev->local->control); in vlynq_setup_irq()
269 val = VLYNQ_CTRL_INT_VECTOR(dev->remote_irq); in vlynq_setup_irq()
271 val |= readl(&dev->remote->control); in vlynq_setup_irq()
272 writel(VLYNQ_INT_OFFSET, &dev->remote->int_ptr); in vlynq_setup_irq()
273 writel(val, &dev->remote->int_ptr); in vlynq_setup_irq()
274 writel(val, &dev->remote->control); in vlynq_setup_irq()
276 for (i = dev->irq_start; i <= dev->irq_end; i++) { in vlynq_setup_irq()
277 virq = i - dev->irq_start; in vlynq_setup_irq()
278 if (virq == dev->local_irq) { in vlynq_setup_irq()
282 } else if (virq == dev->remote_irq) { in vlynq_setup_irq()
290 writel(0, &dev->remote->int_device[virq >> 2]); in vlynq_setup_irq()
294 if (request_irq(dev->irq, vlynq_irq, IRQF_SHARED, "vlynq", dev)) { in vlynq_setup_irq()
296 dev_name(&dev->dev)); in vlynq_setup_irq()
297 return -EAGAIN; in vlynq_setup_irq()
314 struct vlynq_device_id *ids = vdrv->id_table; in vlynq_device_match()
316 while (ids->id) { in vlynq_device_match()
317 if (ids->id == vdev->dev_id) { in vlynq_device_match()
318 vdev->divisor = ids->divisor; in vlynq_device_match()
321 "device: %08x\n", vdev->dev_id); in vlynq_device_match()
325 " for VLYNQ device: %08x\n", ids->id, vdev->dev_id); in vlynq_device_match()
334 struct vlynq_driver *drv = to_vlynq_driver(dev->driver); in vlynq_device_probe()
336 int result = -ENODEV; in vlynq_device_probe()
338 if (drv->probe) in vlynq_device_probe()
339 result = drv->probe(vdev, id); in vlynq_device_probe()
347 struct vlynq_driver *drv = to_vlynq_driver(dev->driver); in vlynq_device_remove()
349 if (drv->remove) in vlynq_device_remove()
350 drv->remove(to_vlynq_device(dev)); in vlynq_device_remove()
357 driver->driver.name = driver->name; in __vlynq_register_driver()
358 driver->driver.bus = &vlynq_bus_type; in __vlynq_register_driver()
359 return driver_register(&driver->driver); in __vlynq_register_driver()
365 driver_unregister(&driver->driver); in vlynq_unregister_driver()
370 * A VLYNQ remote device can clock the VLYNQ bus master
372 * remove device and the bus master should have the same
382 for (i = dev->dev_id ? vlynq_rdiv2 : vlynq_rdiv8; dev->dev_id ? in __vlynq_try_remote()
384 dev->dev_id ? i++ : i--) { in __vlynq_try_remote()
389 writel((readl(&dev->remote->control) & in __vlynq_try_remote()
392 VLYNQ_CTRL_CLOCK_DIV(i - vlynq_rdiv1), in __vlynq_try_remote()
393 &dev->remote->control); in __vlynq_try_remote()
394 writel((readl(&dev->local->control) in __vlynq_try_remote()
397 VLYNQ_CTRL_CLOCK_DIV(i - vlynq_rdiv1), in __vlynq_try_remote()
398 &dev->local->control); in __vlynq_try_remote()
402 "%s: using remote clock divisor %d\n", in __vlynq_try_remote()
403 dev_name(&dev->dev), i - vlynq_rdiv1 + 1); in __vlynq_try_remote()
404 dev->divisor = i; in __vlynq_try_remote()
411 return -ENODEV; in __vlynq_try_remote()
415 * A VLYNQ remote device can be clocked by the VLYNQ bus
417 * the bus master configures the serial clock divider.
427 for (i = dev->dev_id ? vlynq_ldiv2 : vlynq_ldiv8; dev->dev_id ? in __vlynq_try_local()
429 dev->dev_id ? i++ : i--) { in __vlynq_try_local()
431 writel((readl(&dev->local->control) & in __vlynq_try_local()
434 VLYNQ_CTRL_CLOCK_DIV(i - vlynq_ldiv1), in __vlynq_try_local()
435 &dev->local->control); in __vlynq_try_local()
440 dev_name(&dev->dev), i - vlynq_ldiv1 + 1); in __vlynq_try_local()
441 dev->divisor = i; in __vlynq_try_local()
448 return -ENODEV; in __vlynq_try_local()
455 * register for both the bus master and the remote device.
461 return -ENODEV; in __vlynq_try_external()
463 writel((readl(&dev->remote->control) & in __vlynq_try_external()
465 &dev->remote->control); in __vlynq_try_external()
467 writel((readl(&dev->local->control) & in __vlynq_try_external()
469 &dev->local->control); in __vlynq_try_external()
473 dev_name(&dev->dev)); in __vlynq_try_external()
474 dev->divisor = vlynq_div_external; in __vlynq_try_external()
478 return -ENODEV; in __vlynq_try_external()
484 struct plat_vlynq_ops *ops = dev->dev.platform_data; in __vlynq_enable_device()
486 result = ops->on(dev); in __vlynq_enable_device()
490 switch (dev->divisor) { in __vlynq_enable_device()
497 if (vlynq_linked(dev) && readl(&dev->remote->control) & in __vlynq_enable_device()
519 VLYNQ_CTRL_CLOCK_DIV(dev->divisor - in __vlynq_enable_device()
520 vlynq_ldiv1), &dev->local->control); in __vlynq_enable_device()
521 writel(0, &dev->remote->control); in __vlynq_enable_device()
525 dev_name(&dev->dev), in __vlynq_enable_device()
526 dev->divisor - vlynq_ldiv1 + 1); in __vlynq_enable_device()
538 writel(0, &dev->local->control); in __vlynq_enable_device()
540 VLYNQ_CTRL_CLOCK_DIV(dev->divisor - in __vlynq_enable_device()
541 vlynq_rdiv1), &dev->remote->control); in __vlynq_enable_device()
544 "%s: using remote clock divisor %d\n", in __vlynq_enable_device()
545 dev_name(&dev->dev), in __vlynq_enable_device()
546 dev->divisor - vlynq_rdiv1 + 1); in __vlynq_enable_device()
552 ops->off(dev); in __vlynq_enable_device()
553 return -ENODEV; in __vlynq_enable_device()
558 struct plat_vlynq_ops *ops = dev->dev.platform_data; in vlynq_enable_device()
559 int result = -ENODEV; in vlynq_enable_device()
567 ops->off(dev); in vlynq_enable_device()
569 dev->enabled = !result; in vlynq_enable_device()
577 struct plat_vlynq_ops *ops = dev->dev.platform_data; in vlynq_disable_device()
579 dev->enabled = 0; in vlynq_disable_device()
580 free_irq(dev->irq, dev); in vlynq_disable_device()
581 ops->off(dev); in vlynq_disable_device()
590 if (!dev->enabled) in vlynq_set_local_mapping()
591 return -ENXIO; in vlynq_set_local_mapping()
593 writel(tx_offset, &dev->local->tx_offset); in vlynq_set_local_mapping()
595 writel(mapping[i].offset, &dev->local->rx_mapping[i].offset); in vlynq_set_local_mapping()
596 writel(mapping[i].size, &dev->local->rx_mapping[i].size); in vlynq_set_local_mapping()
607 if (!dev->enabled) in vlynq_set_remote_mapping()
608 return -ENXIO; in vlynq_set_remote_mapping()
610 writel(tx_offset, &dev->remote->tx_offset); in vlynq_set_remote_mapping()
612 writel(mapping[i].offset, &dev->remote->rx_mapping[i].offset); in vlynq_set_remote_mapping()
613 writel(mapping[i].size, &dev->remote->rx_mapping[i].size); in vlynq_set_remote_mapping()
621 int irq = dev->irq_start + virq; in vlynq_set_local_irq()
622 if (dev->enabled) in vlynq_set_local_irq()
623 return -EBUSY; in vlynq_set_local_irq()
625 if ((irq < dev->irq_start) || (irq > dev->irq_end)) in vlynq_set_local_irq()
626 return -EINVAL; in vlynq_set_local_irq()
628 if (virq == dev->remote_irq) in vlynq_set_local_irq()
629 return -EINVAL; in vlynq_set_local_irq()
631 dev->local_irq = virq; in vlynq_set_local_irq()
639 int irq = dev->irq_start + virq; in vlynq_set_remote_irq()
640 if (dev->enabled) in vlynq_set_remote_irq()
641 return -EBUSY; in vlynq_set_remote_irq()
643 if ((irq < dev->irq_start) || (irq > dev->irq_end)) in vlynq_set_remote_irq()
644 return -EINVAL; in vlynq_set_remote_irq()
646 if (virq == dev->local_irq) in vlynq_set_remote_irq()
647 return -EINVAL; in vlynq_set_remote_irq()
649 dev->remote_irq = virq; in vlynq_set_remote_irq()
663 return -ENODEV; in vlynq_probe()
667 return -ENODEV; in vlynq_probe()
671 return -ENODEV; in vlynq_probe()
677 return -ENOMEM; in vlynq_probe()
680 dev->id = pdev->id; in vlynq_probe()
681 dev->dev.bus = &vlynq_bus_type; in vlynq_probe()
682 dev->dev.parent = &pdev->dev; in vlynq_probe()
683 dev_set_name(&dev->dev, "vlynq%d", dev->id); in vlynq_probe()
684 dev->dev.platform_data = pdev->dev.platform_data; in vlynq_probe()
685 dev->dev.release = vlynq_device_release; in vlynq_probe()
687 dev->regs_start = regs_res->start; in vlynq_probe()
688 dev->regs_end = regs_res->end; in vlynq_probe()
689 dev->mem_start = mem_res->start; in vlynq_probe()
690 dev->mem_end = mem_res->end; in vlynq_probe()
693 if (!request_mem_region(regs_res->start, len, dev_name(&dev->dev))) { in vlynq_probe()
695 dev_name(&dev->dev)); in vlynq_probe()
696 result = -ENXIO; in vlynq_probe()
700 dev->local = ioremap(regs_res->start, len); in vlynq_probe()
701 if (!dev->local) { in vlynq_probe()
703 dev_name(&dev->dev)); in vlynq_probe()
704 result = -ENXIO; in vlynq_probe()
708 dev->remote = (struct vlynq_regs *)((void *)dev->local + in vlynq_probe()
711 dev->irq = platform_get_irq_byname(pdev, "irq"); in vlynq_probe()
712 dev->irq_start = irq_res->start; in vlynq_probe()
713 dev->irq_end = irq_res->end; in vlynq_probe()
714 dev->local_irq = dev->irq_end - dev->irq_start; in vlynq_probe()
715 dev->remote_irq = dev->local_irq - 1; in vlynq_probe()
717 if (device_register(&dev->dev)) in vlynq_probe()
722 dev_name(&dev->dev), (void *)dev->regs_start, dev->irq, in vlynq_probe()
723 (void *)dev->mem_start); in vlynq_probe()
725 dev->dev_id = 0; in vlynq_probe()
726 dev->divisor = vlynq_div_auto; in vlynq_probe()
729 dev->dev_id = readl(&dev->remote->chip); in vlynq_probe()
730 ((struct plat_vlynq_ops *)(dev->dev.platform_data))->off(dev); in vlynq_probe()
732 if (dev->dev_id) in vlynq_probe()
733 printk(KERN_INFO "Found a VLYNQ device: %08x\n", dev->dev_id); in vlynq_probe()
738 iounmap(dev->local); in vlynq_probe()
741 release_mem_region(regs_res->start, len); in vlynq_probe()
750 device_unregister(&dev->dev); in vlynq_remove()
751 iounmap(dev->local); in vlynq_remove()
752 release_mem_region(dev->regs_start, in vlynq_remove()
753 dev->regs_end - dev->regs_start + 1); in vlynq_remove()