23 #include <linux/types.h>
24 #include <linux/kernel.h>
25 #include <linux/string.h>
26 #include <linux/device.h>
27 #include <linux/module.h>
28 #include <linux/errno.h>
33 #include <linux/slab.h>
38 #define VLYNQ_CTRL_PM_ENABLE 0x80000000
39 #define VLYNQ_CTRL_CLOCK_INT 0x00008000
40 #define VLYNQ_CTRL_CLOCK_DIV(x) (((x) & 7) << 16)
41 #define VLYNQ_CTRL_INT_LOCAL 0x00004000
42 #define VLYNQ_CTRL_INT_ENABLE 0x00002000
43 #define VLYNQ_CTRL_INT_VECTOR(x) (((x) & 0x1f) << 8)
44 #define VLYNQ_CTRL_INT2CFG 0x00000080
45 #define VLYNQ_CTRL_RESET 0x00000001
47 #define VLYNQ_CTRL_CLOCK_MASK (0x7 << 16)
49 #define VLYNQ_INT_OFFSET 0x00000014
50 #define VLYNQ_REMOTE_OFFSET 0x00000080
52 #define VLYNQ_STATUS_LINK 0x00000001
53 #define VLYNQ_STATUS_LERROR 0x00000080
54 #define VLYNQ_STATUS_RERROR 0x00000100
56 #define VINT_ENABLE 0x00000100
57 #define VINT_TYPE_EDGE 0x00000080
58 #define VINT_LEVEL_LOW 0x00000040
59 #define VINT_VECTOR(x) ((x) & 0x1f)
60 #define VINT_OFFSET(irq) (8 * ((irq) % 4))
62 #define VLYNQ_AUTONEGO_V2 0x00010000
80 #ifdef CONFIG_VLYNQ_DEBUG
87 for (i = 0; i < 32; i++) {
95 static void vlynq_dump_mem(
u32 *base,
int count)
99 for (i = 0; i < (count + 3) / 4; i++) {
113 for (i = 0; i < 100; i++)
125 &dev->
local->control);
132 &dev->
local->control);
138 static void vlynq_irq_unmask(
struct irq_data *
d)
140 struct vlynq_device *dev = irq_data_get_irq_chip_data(d);
151 static void vlynq_irq_mask(
struct irq_data *d)
153 struct vlynq_device *dev = irq_data_get_irq_chip_data(d);
164 static int vlynq_irq_type(
struct irq_data *d,
unsigned int flow_type)
166 struct vlynq_device *dev = irq_data_get_irq_chip_data(d);
195 static void vlynq_local_ack(
struct irq_data *d)
197 struct vlynq_device *dev = irq_data_get_irq_chip_data(d);
200 pr_debug(
"%s: local status: 0x%08x\n",
201 dev_name(&dev->
dev), status);
205 static void vlynq_remote_ack(
struct irq_data *d)
207 struct vlynq_device *dev = irq_data_get_irq_chip_data(d);
210 pr_debug(
"%s: remote status: 0x%08x\n",
211 dev_name(&dev->
dev), status);
237 static struct irq_chip vlynq_irq_chip = {
239 .irq_unmask = vlynq_irq_unmask,
240 .irq_mask = vlynq_irq_mask,
241 .irq_set_type = vlynq_irq_type,
244 static struct irq_chip vlynq_local_chip = {
245 .name =
"vlynq local error",
246 .irq_unmask = vlynq_irq_unmask,
247 .irq_mask = vlynq_irq_mask,
248 .irq_ack = vlynq_local_ack,
251 static struct irq_chip vlynq_remote_chip = {
252 .name =
"vlynq local error",
253 .irq_unmask = vlynq_irq_unmask,
254 .irq_mask = vlynq_irq_mask,
255 .irq_ack = vlynq_remote_ack,
265 "%s: local vlynq irq should be different from remote\n",
266 dev_name(&dev->
dev));
289 for (i = dev->
irq_start; i <= dev->irq_end; i++) {
292 irq_set_chip_and_handler(i, &vlynq_local_chip,
296 irq_set_chip_and_handler(i, &vlynq_remote_chip,
300 irq_set_chip_and_handler(i, &vlynq_irq_chip,
309 dev_name(&dev->
dev));
316 static void vlynq_device_release(
struct device *dev)
322 static int vlynq_device_match(
struct device *dev,
332 vlynq_set_drvdata(vdev, ids);
334 "device: %08x\n", vdev->
dev_id);
338 " for VLYNQ device: %08x\n", ids->
id, vdev->
dev_id);
344 static int vlynq_device_probe(
struct device *dev)
352 result = drv->
probe(vdev,
id);
358 static int vlynq_device_remove(
struct device *dev)
363 drv->
remove(to_vlynq_device(dev));
397 dev->
dev_id ? i++ : i--) {
399 if (!vlynq_linked(dev))
411 &dev->
local->control);
413 if (vlynq_linked(dev)) {
415 "%s: using remote clock divisor %d\n",
442 dev->
dev_id ? i++ : i--) {
448 &dev->
local->control);
450 if (vlynq_linked(dev)) {
452 "%s: using local clock divisor %d\n",
470 static int __vlynq_try_external(
struct vlynq_device *dev)
473 if (!vlynq_linked(dev))
482 &dev->
local->control);
484 if (vlynq_linked(dev)) {
486 dev_name(&dev->
dev));
494 static int __vlynq_enable_device(
struct vlynq_device *dev)
499 result = ops->
on(dev);
510 if (vlynq_linked(dev) &&
readl(&dev->
remote->control) &
512 if (!__vlynq_try_remote(dev) ||
513 !__vlynq_try_local(dev) ||
514 !__vlynq_try_external(dev))
517 if (!__vlynq_try_external(dev) ||
518 !__vlynq_try_local(dev) ||
519 !__vlynq_try_remote(dev))
535 if (vlynq_linked(dev)) {
537 "%s: using local clock divisor %d\n",
555 if (vlynq_linked(dev)) {
557 "%s: using remote clock divisor %d\n",
574 result = __vlynq_enable_device(dev);
578 result = vlynq_setup_irq(dev);
607 for (i = 0; i < 4; i++) {
624 for (i = 0; i < 4; i++) {
638 if ((irq < dev->irq_start) || (irq > dev->
irq_end))
656 if ((irq < dev->irq_start) || (irq > dev->
irq_end))
671 struct resource *regs_res, *mem_res, *irq_res;
689 "vlynq: failed to allocate device structure\n");
695 dev->
dev.parent = &pdev->
dev;
697 dev->
dev.platform_data = pdev->
dev.platform_data;
698 dev->
dev.release = vlynq_device_release;
705 len = resource_size(regs_res);
708 dev_name(&dev->
dev));
716 dev_name(&dev->
dev));
732 platform_set_drvdata(pdev, dev);
740 result = __vlynq_enable_device(dev);
773 .driver.name =
"vlynq",
774 .probe = vlynq_probe,
780 .match = vlynq_device_match,
781 .probe = vlynq_device_probe,
782 .remove = vlynq_device_remove,