Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  1 /*
  2  * drivers/net/ibm_newemac/tah.c
  3  *
  4  * Driver for PowerPC 4xx on-chip ethernet controller, TAH support.
  5  *
  6  * Copyright 2007 Benjamin Herrenschmidt, IBM Corp.
  7  *                <benh@kernel.crashing.org>
  8  *
  9  * Based on the arch/ppc version of the driver:
 10  *
 11  * Copyright 2004 MontaVista Software, Inc.
 12  * Matt Porter <mporter@kernel.crashing.org>
 13  *
 14  * Copyright (c) 2005 Eugene Surovegin <ebs@ebshome.net>
 15  *
 16  * This program is free software; you can redistribute  it and/or modify it
 17  * under  the terms of  the GNU General  Public License as published by the
 18  * Free Software Foundation;  either version 2 of the  License, or (at your
 19  * option) any later version.
 20  */
 21 #include <asm/io.h>
 22 
 23 #include "emac.h"
 24 #include "core.h"
 25 
 26 int __devinit tah_attach(struct of_device *ofdev, int channel)
 27 {
 28         struct tah_instance *dev = dev_get_drvdata(&ofdev->dev);
 29 
 30         mutex_lock(&dev->lock);
 31         /* Reset has been done at probe() time... nothing else to do for now */
 32         ++dev->users;
 33         mutex_unlock(&dev->lock);
 34 
 35         return 0;
 36 }
 37 
 38 void __devexit tah_detach(struct of_device *ofdev, int channel)
 39 {
 40         struct tah_instance *dev = dev_get_drvdata(&ofdev->dev);
 41 
 42         mutex_lock(&dev->lock);
 43         --dev->users;
 44         mutex_unlock(&dev->lock);
 45 }
 46 
 47 void tah_reset(struct of_device *ofdev)
 48 {
 49         struct tah_instance *dev = dev_get_drvdata(&ofdev->dev);
 50         struct tah_regs __iomem *p = dev->base;
 51         int n;
 52 
 53         /* Reset TAH */
 54         out_be32(&p->mr, TAH_MR_SR);
 55         n = 100;
 56         while ((in_be32(&p->mr) & TAH_MR_SR) && n)
 57                 --n;
 58 
 59         if (unlikely(!n))
 60                 printk(KERN_ERR "%s: reset timeout\n", ofdev->node->full_name);
 61 
 62         /* 10KB TAH TX FIFO accomodates the max MTU of 9000 */
 63         out_be32(&p->mr,
 64                  TAH_MR_CVR | TAH_MR_ST_768 | TAH_MR_TFS_10KB | TAH_MR_DTFP |
 65                  TAH_MR_DIG);
 66 }
 67 
 68 int tah_get_regs_len(struct of_device *ofdev)
 69 {
 70         return sizeof(struct emac_ethtool_regs_subhdr) +
 71                 sizeof(struct tah_regs);
 72 }
 73 
 74 void *tah_dump_regs(struct of_device *ofdev, void *buf)
 75 {
 76         struct tah_instance *dev = dev_get_drvdata(&ofdev->dev);
 77         struct emac_ethtool_regs_subhdr *hdr = buf;
 78         struct tah_regs *regs = (struct tah_regs *)(hdr + 1);
 79 
 80         hdr->version = 0;
 81         hdr->index = 0; /* for now, are there chips with more than one
 82                          * zmii ? if yes, then we'll add a cell_index
 83                          * like we do for emac
 84                          */
 85         memcpy_fromio(regs, dev->base, sizeof(struct tah_regs));
 86         return regs + 1;
 87 }
 88 
 89 static int __devinit tah_probe(struct of_device *ofdev,
 90                                const struct of_device_id *match)
 91 {
 92         struct device_node *np = ofdev->node;
 93         struct tah_instance *dev;
 94         struct resource regs;
 95         int rc;
 96 
 97         rc = -ENOMEM;
 98         dev = kzalloc(sizeof(struct tah_instance), GFP_KERNEL);
 99         if (dev == NULL) {
100                 printk(KERN_ERR "%s: could not allocate TAH device!\n",
101                        np->full_name);
102                 goto err_gone;
103         }
104 
105         mutex_init(&dev->lock);
106         dev->ofdev = ofdev;
107 
108         rc = -ENXIO;
109         if (of_address_to_resource(np, 0, &regs)) {
110                 printk(KERN_ERR "%s: Can't get registers address\n",
111                        np->full_name);
112                 goto err_free;
113         }
114 
115         rc = -ENOMEM;
116         dev->base = (struct tah_regs __iomem *)ioremap(regs.start,
117                                                sizeof(struct tah_regs));
118         if (dev->base == NULL) {
119                 printk(KERN_ERR "%s: Can't map device registers!\n",
120                        np->full_name);
121                 goto err_free;
122         }
123 
124         dev_set_drvdata(&ofdev->dev, dev);
125 
126         /* Initialize TAH and enable IPv4 checksum verification, no TSO yet */
127         tah_reset(ofdev);
128 
129         printk(KERN_INFO
130                "TAH %s initialized\n", ofdev->node->full_name);
131         wmb();
132 
133         return 0;
134 
135  err_free:
136         kfree(dev);
137  err_gone:
138         return rc;
139 }
140 
141 static int __devexit tah_remove(struct of_device *ofdev)
142 {
143         struct tah_instance *dev = dev_get_drvdata(&ofdev->dev);
144 
145         dev_set_drvdata(&ofdev->dev, NULL);
146 
147         WARN_ON(dev->users != 0);
148 
149         iounmap(dev->base);
150         kfree(dev);
151 
152         return 0;
153 }
154 
155 static struct of_device_id tah_match[] =
156 {
157         {
158                 .compatible     = "ibm,tah",
159         },
160         /* For backward compat with old DT */
161         {
162                 .type           = "tah",
163         },
164         {},
165 };
166 
167 static struct of_platform_driver tah_driver = {
168         .name = "emac-tah",
169         .match_table = tah_match,
170 
171         .probe = tah_probe,
172         .remove = tah_remove,
173 };
174 
175 int __init tah_init(void)
176 {
177         return of_register_platform_driver(&tah_driver);
178 }
179 
180 void tah_exit(void)
181 {
182         of_unregister_platform_driver(&tah_driver);
183 }
184 
  This page was automatically generated by the LXR engine.