0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #include <linux/of_address.h>
0018 #include <asm/io.h>
0019
0020 #include "emac.h"
0021 #include "core.h"
0022
0023 int tah_attach(struct platform_device *ofdev, int channel)
0024 {
0025 struct tah_instance *dev = platform_get_drvdata(ofdev);
0026
0027 mutex_lock(&dev->lock);
0028
0029 ++dev->users;
0030 mutex_unlock(&dev->lock);
0031
0032 return 0;
0033 }
0034
0035 void tah_detach(struct platform_device *ofdev, int channel)
0036 {
0037 struct tah_instance *dev = platform_get_drvdata(ofdev);
0038
0039 mutex_lock(&dev->lock);
0040 --dev->users;
0041 mutex_unlock(&dev->lock);
0042 }
0043
0044 void tah_reset(struct platform_device *ofdev)
0045 {
0046 struct tah_instance *dev = platform_get_drvdata(ofdev);
0047 struct tah_regs __iomem *p = dev->base;
0048 int n;
0049
0050
0051 out_be32(&p->mr, TAH_MR_SR);
0052 n = 100;
0053 while ((in_be32(&p->mr) & TAH_MR_SR) && n)
0054 --n;
0055
0056 if (unlikely(!n))
0057 printk(KERN_ERR "%pOF: reset timeout\n", ofdev->dev.of_node);
0058
0059
0060 out_be32(&p->mr,
0061 TAH_MR_CVR | TAH_MR_ST_768 | TAH_MR_TFS_10KB | TAH_MR_DTFP |
0062 TAH_MR_DIG);
0063 }
0064
0065 int tah_get_regs_len(struct platform_device *ofdev)
0066 {
0067 return sizeof(struct emac_ethtool_regs_subhdr) +
0068 sizeof(struct tah_regs);
0069 }
0070
0071 void *tah_dump_regs(struct platform_device *ofdev, void *buf)
0072 {
0073 struct tah_instance *dev = platform_get_drvdata(ofdev);
0074 struct emac_ethtool_regs_subhdr *hdr = buf;
0075 struct tah_regs *regs = (struct tah_regs *)(hdr + 1);
0076
0077 hdr->version = 0;
0078 hdr->index = 0;
0079
0080
0081
0082 memcpy_fromio(regs, dev->base, sizeof(struct tah_regs));
0083 return regs + 1;
0084 }
0085
0086 static int tah_probe(struct platform_device *ofdev)
0087 {
0088 struct device_node *np = ofdev->dev.of_node;
0089 struct tah_instance *dev;
0090 struct resource regs;
0091 int rc;
0092
0093 rc = -ENOMEM;
0094 dev = kzalloc(sizeof(struct tah_instance), GFP_KERNEL);
0095 if (dev == NULL)
0096 goto err_gone;
0097
0098 mutex_init(&dev->lock);
0099 dev->ofdev = ofdev;
0100
0101 rc = -ENXIO;
0102 if (of_address_to_resource(np, 0, ®s)) {
0103 printk(KERN_ERR "%pOF: Can't get registers address\n", np);
0104 goto err_free;
0105 }
0106
0107 rc = -ENOMEM;
0108 dev->base = (struct tah_regs __iomem *)ioremap(regs.start,
0109 sizeof(struct tah_regs));
0110 if (dev->base == NULL) {
0111 printk(KERN_ERR "%pOF: Can't map device registers!\n", np);
0112 goto err_free;
0113 }
0114
0115 platform_set_drvdata(ofdev, dev);
0116
0117
0118 tah_reset(ofdev);
0119
0120 printk(KERN_INFO "TAH %pOF initialized\n", ofdev->dev.of_node);
0121 wmb();
0122
0123 return 0;
0124
0125 err_free:
0126 kfree(dev);
0127 err_gone:
0128 return rc;
0129 }
0130
0131 static int tah_remove(struct platform_device *ofdev)
0132 {
0133 struct tah_instance *dev = platform_get_drvdata(ofdev);
0134
0135 WARN_ON(dev->users != 0);
0136
0137 iounmap(dev->base);
0138 kfree(dev);
0139
0140 return 0;
0141 }
0142
0143 static const struct of_device_id tah_match[] =
0144 {
0145 {
0146 .compatible = "ibm,tah",
0147 },
0148
0149 {
0150 .type = "tah",
0151 },
0152 {},
0153 };
0154
0155 static struct platform_driver tah_driver = {
0156 .driver = {
0157 .name = "emac-tah",
0158 .of_match_table = tah_match,
0159 },
0160 .probe = tah_probe,
0161 .remove = tah_remove,
0162 };
0163
0164 int __init tah_init(void)
0165 {
0166 return platform_driver_register(&tah_driver);
0167 }
0168
0169 void tah_exit(void)
0170 {
0171 platform_driver_unregister(&tah_driver);
0172 }