diff options
Diffstat (limited to 'drivers')
53 files changed, 832 insertions, 3178 deletions
diff --git a/drivers/ata/pata_mpc52xx.c b/drivers/ata/pata_mpc52xx.c index bc79df6e7cb0..a9e827356d06 100644 --- a/drivers/ata/pata_mpc52xx.c +++ b/drivers/ata/pata_mpc52xx.c | |||
@@ -16,10 +16,10 @@ | |||
16 | #include <linux/slab.h> | 16 | #include <linux/slab.h> |
17 | #include <linux/delay.h> | 17 | #include <linux/delay.h> |
18 | #include <linux/libata.h> | 18 | #include <linux/libata.h> |
19 | #include <linux/of_platform.h> | ||
19 | 20 | ||
20 | #include <asm/types.h> | 21 | #include <asm/types.h> |
21 | #include <asm/prom.h> | 22 | #include <asm/prom.h> |
22 | #include <asm/of_platform.h> | ||
23 | #include <asm/mpc52xx.h> | 23 | #include <asm/mpc52xx.h> |
24 | 24 | ||
25 | 25 | ||
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 2d854bb9373e..650e6b44ce65 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig | |||
@@ -649,6 +649,14 @@ config HVCS | |||
649 | which will also be compiled when this driver is built as a | 649 | which will also be compiled when this driver is built as a |
650 | module. | 650 | module. |
651 | 651 | ||
652 | config IBM_BSR | ||
653 | tristate "IBM POWER Barrier Synchronization Register support" | ||
654 | depends on PPC_PSERIES | ||
655 | help | ||
656 | This devices exposes a hardware mechanism for fast synchronization | ||
657 | of threads across a large system which avoids bouncing a cacheline | ||
658 | between several cores on a system | ||
659 | |||
652 | source "drivers/char/ipmi/Kconfig" | 660 | source "drivers/char/ipmi/Kconfig" |
653 | 661 | ||
654 | config DS1620 | 662 | config DS1620 |
diff --git a/drivers/char/Makefile b/drivers/char/Makefile index 81630a68475c..0e0d12a06462 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile | |||
@@ -57,6 +57,7 @@ obj-$(CONFIG_MMTIMER) += mmtimer.o | |||
57 | obj-$(CONFIG_VIOCONS) += viocons.o | 57 | obj-$(CONFIG_VIOCONS) += viocons.o |
58 | obj-$(CONFIG_VIOTAPE) += viotape.o | 58 | obj-$(CONFIG_VIOTAPE) += viotape.o |
59 | obj-$(CONFIG_HVCS) += hvcs.o | 59 | obj-$(CONFIG_HVCS) += hvcs.o |
60 | obj-$(CONFIG_IBM_BSR) += bsr.o | ||
60 | obj-$(CONFIG_SGI_MBCS) += mbcs.o | 61 | obj-$(CONFIG_SGI_MBCS) += mbcs.o |
61 | obj-$(CONFIG_BRIQ_PANEL) += briq_panel.o | 62 | obj-$(CONFIG_BRIQ_PANEL) += briq_panel.o |
62 | obj-$(CONFIG_BFIN_OTP) += bfin-otp.o | 63 | obj-$(CONFIG_BFIN_OTP) += bfin-otp.o |
diff --git a/drivers/char/bsr.c b/drivers/char/bsr.c new file mode 100644 index 000000000000..b650b4e48e50 --- /dev/null +++ b/drivers/char/bsr.c | |||
@@ -0,0 +1,312 @@ | |||
1 | /* IBM POWER Barrier Synchronization Register Driver | ||
2 | * | ||
3 | * Copyright IBM Corporation 2008 | ||
4 | * | ||
5 | * Author: Sonny Rao <sonnyrao@us.ibm.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | */ | ||
21 | |||
22 | #include <linux/kernel.h> | ||
23 | #include <linux/of.h> | ||
24 | #include <linux/of_device.h> | ||
25 | #include <linux/of_platform.h> | ||
26 | #include <linux/module.h> | ||
27 | #include <linux/cdev.h> | ||
28 | #include <linux/list.h> | ||
29 | #include <linux/mm.h> | ||
30 | #include <asm/io.h> | ||
31 | |||
32 | /* | ||
33 | This driver exposes a special register which can be used for fast | ||
34 | synchronization across a large SMP machine. The hardware is exposed | ||
35 | as an array of bytes where each process will write to one of the bytes to | ||
36 | indicate it has finished the current stage and this update is broadcast to | ||
37 | all processors without having to bounce a cacheline between them. In | ||
38 | POWER5 and POWER6 there is one of these registers per SMP, but it is | ||
39 | presented in two forms; first, it is given as a whole and then as a number | ||
40 | of smaller registers which alias to parts of the single whole register. | ||
41 | This can potentially allow multiple groups of processes to each have their | ||
42 | own private synchronization device. | ||
43 | |||
44 | Note that this hardware *must* be written to using *only* single byte writes. | ||
45 | It may be read using 1, 2, 4, or 8 byte loads which must be aligned since | ||
46 | this region is treated as cache-inhibited processes should also use a | ||
47 | full sync before and after writing to the BSR to ensure all stores and | ||
48 | the BSR update have made it to all chips in the system | ||
49 | */ | ||
50 | |||
51 | /* This is arbitrary number, up to Power6 it's been 17 or fewer */ | ||
52 | #define BSR_MAX_DEVS (32) | ||
53 | |||
54 | struct bsr_dev { | ||
55 | u64 bsr_addr; /* Real address */ | ||
56 | u64 bsr_len; /* length of mem region we can map */ | ||
57 | unsigned bsr_bytes; /* size of the BSR reg itself */ | ||
58 | unsigned bsr_stride; /* interval at which BSR repeats in the page */ | ||
59 | unsigned bsr_type; /* maps to enum below */ | ||
60 | unsigned bsr_num; /* bsr id number for its type */ | ||
61 | int bsr_minor; | ||
62 | |||
63 | dev_t bsr_dev; | ||
64 | struct cdev bsr_cdev; | ||
65 | struct device *bsr_device; | ||
66 | char bsr_name[32]; | ||
67 | |||
68 | }; | ||
69 | |||
70 | static unsigned num_bsr_devs; | ||
71 | static struct bsr_dev *bsr_devs; | ||
72 | static struct class *bsr_class; | ||
73 | static int bsr_major; | ||
74 | |||
75 | enum { | ||
76 | BSR_8 = 0, | ||
77 | BSR_16 = 1, | ||
78 | BSR_64 = 2, | ||
79 | BSR_128 = 3, | ||
80 | BSR_UNKNOWN = 4, | ||
81 | BSR_MAX = 5, | ||
82 | }; | ||
83 | |||
84 | static unsigned bsr_types[BSR_MAX]; | ||
85 | |||
86 | static ssize_t | ||
87 | bsr_size_show(struct device *dev, struct device_attribute *attr, char *buf) | ||
88 | { | ||
89 | struct bsr_dev *bsr_dev = dev_get_drvdata(dev); | ||
90 | return sprintf(buf, "%u\n", bsr_dev->bsr_bytes); | ||
91 | } | ||
92 | |||
93 | static ssize_t | ||
94 | bsr_stride_show(struct device *dev, struct device_attribute *attr, char *buf) | ||
95 | { | ||
96 | struct bsr_dev *bsr_dev = dev_get_drvdata(dev); | ||
97 | return sprintf(buf, "%u\n", bsr_dev->bsr_stride); | ||
98 | } | ||
99 | |||
100 | static ssize_t | ||
101 | bsr_len_show(struct device *dev, struct device_attribute *attr, char *buf) | ||
102 | { | ||
103 | struct bsr_dev *bsr_dev = dev_get_drvdata(dev); | ||
104 | return sprintf(buf, "%lu\n", bsr_dev->bsr_len); | ||
105 | } | ||
106 | |||
107 | static struct device_attribute bsr_dev_attrs[] = { | ||
108 | __ATTR(bsr_size, S_IRUGO, bsr_size_show, NULL), | ||
109 | __ATTR(bsr_stride, S_IRUGO, bsr_stride_show, NULL), | ||
110 | __ATTR(bsr_length, S_IRUGO, bsr_len_show, NULL), | ||
111 | __ATTR_NULL | ||
112 | }; | ||
113 | |||
114 | static int bsr_mmap(struct file *filp, struct vm_area_struct *vma) | ||
115 | { | ||
116 | unsigned long size = vma->vm_end - vma->vm_start; | ||
117 | struct bsr_dev *dev = filp->private_data; | ||
118 | |||
119 | if (size > dev->bsr_len || (size & (PAGE_SIZE-1))) | ||
120 | return -EINVAL; | ||
121 | |||
122 | vma->vm_flags |= (VM_IO | VM_DONTEXPAND); | ||
123 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); | ||
124 | |||
125 | if (io_remap_pfn_range(vma, vma->vm_start, dev->bsr_addr >> PAGE_SHIFT, | ||
126 | size, vma->vm_page_prot)) | ||
127 | return -EAGAIN; | ||
128 | |||
129 | return 0; | ||
130 | } | ||
131 | |||
132 | static int bsr_open(struct inode * inode, struct file * filp) | ||
133 | { | ||
134 | struct cdev *cdev = inode->i_cdev; | ||
135 | struct bsr_dev *dev = container_of(cdev, struct bsr_dev, bsr_cdev); | ||
136 | |||
137 | filp->private_data = dev; | ||
138 | return 0; | ||
139 | } | ||
140 | |||
141 | const static struct file_operations bsr_fops = { | ||
142 | .owner = THIS_MODULE, | ||
143 | .mmap = bsr_mmap, | ||
144 | .open = bsr_open, | ||
145 | }; | ||
146 | |||
147 | static void bsr_cleanup_devs(void) | ||
148 | { | ||
149 | int i; | ||
150 | for (i=0 ; i < num_bsr_devs; i++) { | ||
151 | struct bsr_dev *cur = bsr_devs + i; | ||
152 | if (cur->bsr_device) { | ||
153 | cdev_del(&cur->bsr_cdev); | ||
154 | device_del(cur->bsr_device); | ||
155 | } | ||
156 | } | ||
157 | |||
158 | kfree(bsr_devs); | ||
159 | } | ||
160 | |||
161 | static int bsr_create_devs(struct device_node *bn) | ||
162 | { | ||
163 | int bsr_stride_len, bsr_bytes_len; | ||
164 | const u32 *bsr_stride; | ||
165 | const u32 *bsr_bytes; | ||
166 | unsigned i; | ||
167 | |||
168 | bsr_stride = of_get_property(bn, "ibm,lock-stride", &bsr_stride_len); | ||
169 | bsr_bytes = of_get_property(bn, "ibm,#lock-bytes", &bsr_bytes_len); | ||
170 | |||
171 | if (!bsr_stride || !bsr_bytes || | ||
172 | (bsr_stride_len != bsr_bytes_len)) { | ||
173 | printk(KERN_ERR "bsr of-node has missing/incorrect property\n"); | ||
174 | return -ENODEV; | ||
175 | } | ||
176 | |||
177 | num_bsr_devs = bsr_bytes_len / sizeof(u32); | ||
178 | |||
179 | /* only a warning, its informational since we'll fail and exit */ | ||
180 | WARN_ON(num_bsr_devs > BSR_MAX_DEVS); | ||
181 | |||
182 | bsr_devs = kzalloc(sizeof(struct bsr_dev) * num_bsr_devs, GFP_KERNEL); | ||
183 | if (!bsr_devs) | ||
184 | return -ENOMEM; | ||
185 | |||
186 | for (i = 0 ; i < num_bsr_devs; i++) { | ||
187 | struct bsr_dev *cur = bsr_devs + i; | ||
188 | struct resource res; | ||
189 | int result; | ||
190 | |||
191 | result = of_address_to_resource(bn, i, &res); | ||
192 | if (result < 0) { | ||
193 | printk(KERN_ERR "bsr of-node has invalid reg property\n"); | ||
194 | goto out_err; | ||
195 | } | ||
196 | |||
197 | cur->bsr_minor = i; | ||
198 | cur->bsr_addr = res.start; | ||
199 | cur->bsr_len = res.end - res.start + 1; | ||
200 | cur->bsr_bytes = bsr_bytes[i]; | ||
201 | cur->bsr_stride = bsr_stride[i]; | ||
202 | cur->bsr_dev = MKDEV(bsr_major, i); | ||
203 | |||
204 | switch(cur->bsr_bytes) { | ||
205 | case 8: | ||
206 | cur->bsr_type = BSR_8; | ||
207 | break; | ||
208 | case 16: | ||
209 | cur->bsr_type = BSR_16; | ||
210 | break; | ||
211 | case 64: | ||
212 | cur->bsr_type = BSR_64; | ||
213 | break; | ||
214 | case 128: | ||
215 | cur->bsr_type = BSR_128; | ||
216 | break; | ||
217 | default: | ||
218 | cur->bsr_type = BSR_UNKNOWN; | ||
219 | printk(KERN_INFO "unknown BSR size %d\n",cur->bsr_bytes); | ||
220 | } | ||
221 | |||
222 | cur->bsr_num = bsr_types[cur->bsr_type]; | ||
223 | bsr_types[cur->bsr_type] = cur->bsr_num + 1; | ||
224 | snprintf(cur->bsr_name, 32, "bsr%d_%d", | ||
225 | cur->bsr_bytes, cur->bsr_num); | ||
226 | |||
227 | cdev_init(&cur->bsr_cdev, &bsr_fops); | ||
228 | result = cdev_add(&cur->bsr_cdev, cur->bsr_dev, 1); | ||
229 | if (result) | ||
230 | goto out_err; | ||
231 | |||
232 | cur->bsr_device = device_create_drvdata(bsr_class, NULL, | ||
233 | cur->bsr_dev, | ||
234 | cur, cur->bsr_name); | ||
235 | if (!cur->bsr_device) { | ||
236 | printk(KERN_ERR "device_create failed for %s\n", | ||
237 | cur->bsr_name); | ||
238 | cdev_del(&cur->bsr_cdev); | ||
239 | goto out_err; | ||
240 | } | ||
241 | } | ||
242 | |||
243 | return 0; | ||
244 | |||
245 | out_err: | ||
246 | |||
247 | bsr_cleanup_devs(); | ||
248 | return -ENODEV; | ||
249 | } | ||
250 | |||
251 | static int __init bsr_init(void) | ||
252 | { | ||
253 | struct device_node *np; | ||
254 | dev_t bsr_dev = MKDEV(bsr_major, 0); | ||
255 | int ret = -ENODEV; | ||
256 | int result; | ||
257 | |||
258 | np = of_find_compatible_node(NULL, "ibm,bsr", "ibm,bsr"); | ||
259 | if (!np) | ||
260 | goto out_err; | ||
261 | |||
262 | bsr_class = class_create(THIS_MODULE, "bsr"); | ||
263 | if (IS_ERR(bsr_class)) { | ||
264 | printk(KERN_ERR "class_create() failed for bsr_class\n"); | ||
265 | goto out_err_1; | ||
266 | } | ||
267 | bsr_class->dev_attrs = bsr_dev_attrs; | ||
268 | |||
269 | result = alloc_chrdev_region(&bsr_dev, 0, BSR_MAX_DEVS, "bsr"); | ||
270 | bsr_major = MAJOR(bsr_dev); | ||
271 | if (result < 0) { | ||
272 | printk(KERN_ERR "alloc_chrdev_region() failed for bsr\n"); | ||
273 | goto out_err_2; | ||
274 | } | ||
275 | |||
276 | if ((ret = bsr_create_devs(np)) < 0) | ||
277 | goto out_err_3; | ||
278 | |||
279 | of_node_put(np); | ||
280 | |||
281 | return 0; | ||
282 | |||
283 | out_err_3: | ||
284 | unregister_chrdev_region(bsr_dev, BSR_MAX_DEVS); | ||
285 | |||
286 | out_err_2: | ||
287 | class_destroy(bsr_class); | ||
288 | |||
289 | out_err_1: | ||
290 | of_node_put(np); | ||
291 | |||
292 | out_err: | ||
293 | |||
294 | return ret; | ||
295 | } | ||
296 | |||
297 | static void __exit bsr_exit(void) | ||
298 | { | ||
299 | |||
300 | bsr_cleanup_devs(); | ||
301 | |||
302 | if (bsr_class) | ||
303 | class_destroy(bsr_class); | ||
304 | |||
305 | if (bsr_major) | ||
306 | unregister_chrdev_region(MKDEV(bsr_major, 0), BSR_MAX_DEVS); | ||
307 | } | ||
308 | |||
309 | module_init(bsr_init); | ||
310 | module_exit(bsr_exit); | ||
311 | MODULE_LICENSE("GPL"); | ||
312 | MODULE_AUTHOR("Sonny Rao <sonnyrao@us.ibm.com>"); | ||
diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c index 44160d5ebca0..2f9759d625cc 100644 --- a/drivers/char/hvc_console.c +++ b/drivers/char/hvc_console.c | |||
@@ -675,12 +675,6 @@ static int hvc_poll(struct hvc_struct *hp) | |||
675 | return poll_mask; | 675 | return poll_mask; |
676 | } | 676 | } |
677 | 677 | ||
678 | #if defined(CONFIG_XMON) && defined(CONFIG_SMP) | ||
679 | extern cpumask_t cpus_in_xmon; | ||
680 | #else | ||
681 | static const cpumask_t cpus_in_xmon = CPU_MASK_NONE; | ||
682 | #endif | ||
683 | |||
684 | /* | 678 | /* |
685 | * This kthread is either polling or interrupt driven. This is determined by | 679 | * This kthread is either polling or interrupt driven. This is determined by |
686 | * calling hvc_poll() who determines whether a console adapter support | 680 | * calling hvc_poll() who determines whether a console adapter support |
@@ -698,7 +692,7 @@ static int khvcd(void *unused) | |||
698 | hvc_kicked = 0; | 692 | hvc_kicked = 0; |
699 | try_to_freeze(); | 693 | try_to_freeze(); |
700 | wmb(); | 694 | wmb(); |
701 | if (cpus_empty(cpus_in_xmon)) { | 695 | if (!cpus_are_in_xmon()) { |
702 | spin_lock(&hvc_structs_lock); | 696 | spin_lock(&hvc_structs_lock); |
703 | list_for_each_entry(hp, &hvc_structs, next) { | 697 | list_for_each_entry(hp, &hvc_structs, next) { |
704 | poll_mask |= hvc_poll(hp); | 698 | poll_mask |= hvc_poll(hp); |
diff --git a/drivers/char/hvc_console.h b/drivers/char/hvc_console.h index 8c59818050e6..42ffb17e15df 100644 --- a/drivers/char/hvc_console.h +++ b/drivers/char/hvc_console.h | |||
@@ -60,4 +60,14 @@ extern struct hvc_struct * __devinit hvc_alloc(uint32_t vtermno, int irq, | |||
60 | /* remove a vterm from hvc tty operation (modele_exit or hotplug remove) */ | 60 | /* remove a vterm from hvc tty operation (modele_exit or hotplug remove) */ |
61 | extern int __devexit hvc_remove(struct hvc_struct *hp); | 61 | extern int __devexit hvc_remove(struct hvc_struct *hp); |
62 | 62 | ||
63 | |||
64 | #if defined(CONFIG_XMON) && defined(CONFIG_SMP) | ||
65 | #include <asm/xmon.h> | ||
66 | #else | ||
67 | static inline int cpus_are_in_xmon(void) | ||
68 | { | ||
69 | return 0; | ||
70 | } | ||
71 | #endif | ||
72 | |||
63 | #endif // HVC_CONSOLE_H | 73 | #endif // HVC_CONSOLE_H |
diff --git a/drivers/char/hw_random/pasemi-rng.c b/drivers/char/hw_random/pasemi-rng.c index 6d50e9bc700b..7fa61dd1d9d9 100644 --- a/drivers/char/hw_random/pasemi-rng.c +++ b/drivers/char/hw_random/pasemi-rng.c | |||
@@ -24,7 +24,7 @@ | |||
24 | #include <linux/platform_device.h> | 24 | #include <linux/platform_device.h> |
25 | #include <linux/hw_random.h> | 25 | #include <linux/hw_random.h> |
26 | #include <linux/delay.h> | 26 | #include <linux/delay.h> |
27 | #include <asm/of_platform.h> | 27 | #include <linux/of_platform.h> |
28 | #include <asm/io.h> | 28 | #include <asm/io.h> |
29 | 29 | ||
30 | #define SDCRNG_CTL_REG 0x00 | 30 | #define SDCRNG_CTL_REG 0x00 |
diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c index 977f7d35e769..e5da98d8f9cd 100644 --- a/drivers/char/viotape.c +++ b/drivers/char/viotape.c | |||
@@ -678,6 +678,17 @@ free_op: | |||
678 | return ret; | 678 | return ret; |
679 | } | 679 | } |
680 | 680 | ||
681 | static long viotap_unlocked_ioctl(struct file *file, | ||
682 | unsigned int cmd, unsigned long arg) | ||
683 | { | ||
684 | long rc; | ||
685 | |||
686 | lock_kernel(); | ||
687 | rc = viotap_ioctl(file->f_path.dentry->d_inode, file, cmd, arg); | ||
688 | unlock_kernel(); | ||
689 | return rc; | ||
690 | } | ||
691 | |||
681 | static int viotap_open(struct inode *inode, struct file *file) | 692 | static int viotap_open(struct inode *inode, struct file *file) |
682 | { | 693 | { |
683 | HvLpEvent_Rc hvrc; | 694 | HvLpEvent_Rc hvrc; |
@@ -786,12 +797,12 @@ free_op: | |||
786 | } | 797 | } |
787 | 798 | ||
788 | const struct file_operations viotap_fops = { | 799 | const struct file_operations viotap_fops = { |
789 | .owner = THIS_MODULE, | 800 | .owner = THIS_MODULE, |
790 | .read = viotap_read, | 801 | .read = viotap_read, |
791 | .write = viotap_write, | 802 | .write = viotap_write, |
792 | .ioctl = viotap_ioctl, | 803 | .unlocked_ioctl = viotap_unlocked_ioctl, |
793 | .open = viotap_open, | 804 | .open = viotap_open, |
794 | .release = viotap_release, | 805 | .release = viotap_release, |
795 | }; | 806 | }; |
796 | 807 | ||
797 | /* Handle interrupt events for tape */ | 808 | /* Handle interrupt events for tape */ |
diff --git a/drivers/hwmon/ams/ams-core.c b/drivers/hwmon/ams/ams-core.c index a112a03e8f29..fbefa82a015c 100644 --- a/drivers/hwmon/ams/ams-core.c +++ b/drivers/hwmon/ams/ams-core.c | |||
@@ -23,8 +23,8 @@ | |||
23 | #include <linux/types.h> | 23 | #include <linux/types.h> |
24 | #include <linux/errno.h> | 24 | #include <linux/errno.h> |
25 | #include <linux/init.h> | 25 | #include <linux/init.h> |
26 | #include <linux/of_platform.h> | ||
26 | #include <asm/pmac_pfunc.h> | 27 | #include <asm/pmac_pfunc.h> |
27 | #include <asm/of_platform.h> | ||
28 | 28 | ||
29 | #include "ams.h" | 29 | #include "ams.h" |
30 | 30 | ||
diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index a076129de7e8..4fdfb62d6f38 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c | |||
@@ -17,7 +17,8 @@ | |||
17 | #include <linux/module.h> | 17 | #include <linux/module.h> |
18 | #include <linux/sched.h> | 18 | #include <linux/sched.h> |
19 | #include <linux/init.h> | 19 | #include <linux/init.h> |
20 | #include <linux/platform_device.h> | 20 | #include <linux/of_platform.h> |
21 | #include <linux/of_i2c.h> | ||
21 | 22 | ||
22 | #include <asm/io.h> | 23 | #include <asm/io.h> |
23 | #include <linux/fsl_devices.h> | 24 | #include <linux/fsl_devices.h> |
@@ -25,13 +26,13 @@ | |||
25 | #include <linux/interrupt.h> | 26 | #include <linux/interrupt.h> |
26 | #include <linux/delay.h> | 27 | #include <linux/delay.h> |
27 | 28 | ||
28 | #define MPC_I2C_ADDR 0x00 | 29 | #define DRV_NAME "mpc-i2c" |
30 | |||
29 | #define MPC_I2C_FDR 0x04 | 31 | #define MPC_I2C_FDR 0x04 |
30 | #define MPC_I2C_CR 0x08 | 32 | #define MPC_I2C_CR 0x08 |
31 | #define MPC_I2C_SR 0x0c | 33 | #define MPC_I2C_SR 0x0c |
32 | #define MPC_I2C_DR 0x10 | 34 | #define MPC_I2C_DR 0x10 |
33 | #define MPC_I2C_DFSRR 0x14 | 35 | #define MPC_I2C_DFSRR 0x14 |
34 | #define MPC_I2C_REGION 0x20 | ||
35 | 36 | ||
36 | #define CCR_MEN 0x80 | 37 | #define CCR_MEN 0x80 |
37 | #define CCR_MIEN 0x40 | 38 | #define CCR_MIEN 0x40 |
@@ -315,102 +316,117 @@ static struct i2c_adapter mpc_ops = { | |||
315 | .timeout = 1, | 316 | .timeout = 1, |
316 | }; | 317 | }; |
317 | 318 | ||
318 | static int fsl_i2c_probe(struct platform_device *pdev) | 319 | static int __devinit fsl_i2c_probe(struct of_device *op, const struct of_device_id *match) |
319 | { | 320 | { |
320 | int result = 0; | 321 | int result = 0; |
321 | struct mpc_i2c *i2c; | 322 | struct mpc_i2c *i2c; |
322 | struct fsl_i2c_platform_data *pdata; | ||
323 | struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
324 | |||
325 | pdata = (struct fsl_i2c_platform_data *) pdev->dev.platform_data; | ||
326 | 323 | ||
327 | i2c = kzalloc(sizeof(*i2c), GFP_KERNEL); | 324 | i2c = kzalloc(sizeof(*i2c), GFP_KERNEL); |
328 | if (!i2c) | 325 | if (!i2c) |
329 | return -ENOMEM; | 326 | return -ENOMEM; |
330 | 327 | ||
331 | i2c->irq = platform_get_irq(pdev, 0); | 328 | if (of_get_property(op->node, "dfsrr", NULL)) |
332 | if (i2c->irq < 0) | 329 | i2c->flags |= FSL_I2C_DEV_SEPARATE_DFSRR; |
333 | i2c->irq = NO_IRQ; /* Use polling */ | ||
334 | 330 | ||
335 | i2c->flags = pdata->device_flags; | 331 | if (of_device_is_compatible(op->node, "fsl,mpc5200-i2c") || |
336 | init_waitqueue_head(&i2c->queue); | 332 | of_device_is_compatible(op->node, "mpc5200-i2c")) |
333 | i2c->flags |= FSL_I2C_DEV_CLOCK_5200; | ||
337 | 334 | ||
338 | i2c->base = ioremap((phys_addr_t)r->start, MPC_I2C_REGION); | 335 | init_waitqueue_head(&i2c->queue); |
339 | 336 | ||
337 | i2c->base = of_iomap(op->node, 0); | ||
340 | if (!i2c->base) { | 338 | if (!i2c->base) { |
341 | printk(KERN_ERR "i2c-mpc - failed to map controller\n"); | 339 | printk(KERN_ERR "i2c-mpc - failed to map controller\n"); |
342 | result = -ENOMEM; | 340 | result = -ENOMEM; |
343 | goto fail_map; | 341 | goto fail_map; |
344 | } | 342 | } |
345 | 343 | ||
346 | if (i2c->irq != NO_IRQ) | 344 | i2c->irq = irq_of_parse_and_map(op->node, 0); |
347 | if ((result = request_irq(i2c->irq, mpc_i2c_isr, | 345 | if (i2c->irq != NO_IRQ) { /* i2c->irq = NO_IRQ implies polling */ |
348 | IRQF_SHARED, "i2c-mpc", i2c)) < 0) { | 346 | result = request_irq(i2c->irq, mpc_i2c_isr, |
349 | printk(KERN_ERR | 347 | IRQF_SHARED, "i2c-mpc", i2c); |
350 | "i2c-mpc - failed to attach interrupt\n"); | 348 | if (result < 0) { |
351 | goto fail_irq; | 349 | printk(KERN_ERR "i2c-mpc - failed to attach interrupt\n"); |
350 | goto fail_request; | ||
352 | } | 351 | } |
353 | 352 | } | |
353 | |||
354 | mpc_i2c_setclock(i2c); | 354 | mpc_i2c_setclock(i2c); |
355 | platform_set_drvdata(pdev, i2c); | 355 | |
356 | dev_set_drvdata(&op->dev, i2c); | ||
356 | 357 | ||
357 | i2c->adap = mpc_ops; | 358 | i2c->adap = mpc_ops; |
358 | i2c->adap.nr = pdev->id; | ||
359 | i2c_set_adapdata(&i2c->adap, i2c); | 359 | i2c_set_adapdata(&i2c->adap, i2c); |
360 | i2c->adap.dev.parent = &pdev->dev; | 360 | i2c->adap.dev.parent = &op->dev; |
361 | if ((result = i2c_add_numbered_adapter(&i2c->adap)) < 0) { | 361 | |
362 | result = i2c_add_adapter(&i2c->adap); | ||
363 | if (result < 0) { | ||
362 | printk(KERN_ERR "i2c-mpc - failed to add adapter\n"); | 364 | printk(KERN_ERR "i2c-mpc - failed to add adapter\n"); |
363 | goto fail_add; | 365 | goto fail_add; |
364 | } | 366 | } |
367 | of_register_i2c_devices(&i2c->adap, op->node); | ||
365 | 368 | ||
366 | return result; | 369 | return result; |
367 | 370 | ||
368 | fail_add: | 371 | fail_add: |
369 | if (i2c->irq != NO_IRQ) | 372 | dev_set_drvdata(&op->dev, NULL); |
370 | free_irq(i2c->irq, i2c); | 373 | free_irq(i2c->irq, i2c); |
371 | fail_irq: | 374 | fail_request: |
372 | iounmap(i2c->base); | 375 | irq_dispose_mapping(i2c->irq); |
373 | fail_map: | 376 | iounmap(i2c->base); |
377 | fail_map: | ||
374 | kfree(i2c); | 378 | kfree(i2c); |
375 | return result; | 379 | return result; |
376 | }; | 380 | }; |
377 | 381 | ||
378 | static int fsl_i2c_remove(struct platform_device *pdev) | 382 | static int __devexit fsl_i2c_remove(struct of_device *op) |
379 | { | 383 | { |
380 | struct mpc_i2c *i2c = platform_get_drvdata(pdev); | 384 | struct mpc_i2c *i2c = dev_get_drvdata(&op->dev); |
381 | 385 | ||
382 | i2c_del_adapter(&i2c->adap); | 386 | i2c_del_adapter(&i2c->adap); |
383 | platform_set_drvdata(pdev, NULL); | 387 | dev_set_drvdata(&op->dev, NULL); |
384 | 388 | ||
385 | if (i2c->irq != NO_IRQ) | 389 | if (i2c->irq != NO_IRQ) |
386 | free_irq(i2c->irq, i2c); | 390 | free_irq(i2c->irq, i2c); |
387 | 391 | ||
392 | irq_dispose_mapping(i2c->irq); | ||
388 | iounmap(i2c->base); | 393 | iounmap(i2c->base); |
389 | kfree(i2c); | 394 | kfree(i2c); |
390 | return 0; | 395 | return 0; |
391 | }; | 396 | }; |
392 | 397 | ||
393 | /* work with hotplug and coldplug */ | 398 | static const struct of_device_id mpc_i2c_of_match[] = { |
394 | MODULE_ALIAS("platform:fsl-i2c"); | 399 | {.compatible = "fsl-i2c",}, |
400 | {}, | ||
401 | }; | ||
402 | MODULE_DEVICE_TABLE(of, mpc_i2c_of_match); | ||
403 | |||
395 | 404 | ||
396 | /* Structure for a device driver */ | 405 | /* Structure for a device driver */ |
397 | static struct platform_driver fsl_i2c_driver = { | 406 | static struct of_platform_driver mpc_i2c_driver = { |
398 | .probe = fsl_i2c_probe, | 407 | .match_table = mpc_i2c_of_match, |
399 | .remove = fsl_i2c_remove, | 408 | .probe = fsl_i2c_probe, |
400 | .driver = { | 409 | .remove = __devexit_p(fsl_i2c_remove), |
401 | .owner = THIS_MODULE, | 410 | .driver = { |
402 | .name = "fsl-i2c", | 411 | .owner = THIS_MODULE, |
412 | .name = DRV_NAME, | ||
403 | }, | 413 | }, |
404 | }; | 414 | }; |
405 | 415 | ||
406 | static int __init fsl_i2c_init(void) | 416 | static int __init fsl_i2c_init(void) |
407 | { | 417 | { |
408 | return platform_driver_register(&fsl_i2c_driver); | 418 | int rv; |
419 | |||
420 | rv = of_register_platform_driver(&mpc_i2c_driver); | ||
421 | if (rv) | ||
422 | printk(KERN_ERR DRV_NAME | ||
423 | " of_register_platform_driver failed (%i)\n", rv); | ||
424 | return rv; | ||
409 | } | 425 | } |
410 | 426 | ||
411 | static void __exit fsl_i2c_exit(void) | 427 | static void __exit fsl_i2c_exit(void) |
412 | { | 428 | { |
413 | platform_driver_unregister(&fsl_i2c_driver); | 429 | of_unregister_platform_driver(&mpc_i2c_driver); |
414 | } | 430 | } |
415 | 431 | ||
416 | module_init(fsl_i2c_init); | 432 | module_init(fsl_i2c_init); |
diff --git a/drivers/macintosh/adb.c b/drivers/macintosh/adb.c index 40c70ba62bf0..e5d446804d32 100644 --- a/drivers/macintosh/adb.c +++ b/drivers/macintosh/adb.c | |||
@@ -46,7 +46,6 @@ | |||
46 | #endif | 46 | #endif |
47 | 47 | ||
48 | 48 | ||
49 | EXPORT_SYMBOL(adb_controller); | ||
50 | EXPORT_SYMBOL(adb_client_list); | 49 | EXPORT_SYMBOL(adb_client_list); |
51 | 50 | ||
52 | extern struct adb_driver via_macii_driver; | 51 | extern struct adb_driver via_macii_driver; |
@@ -80,7 +79,7 @@ static struct adb_driver *adb_driver_list[] = { | |||
80 | 79 | ||
81 | static struct class *adb_dev_class; | 80 | static struct class *adb_dev_class; |
82 | 81 | ||
83 | struct adb_driver *adb_controller; | 82 | static struct adb_driver *adb_controller; |
84 | BLOCKING_NOTIFIER_HEAD(adb_client_list); | 83 | BLOCKING_NOTIFIER_HEAD(adb_client_list); |
85 | static int adb_got_sleep; | 84 | static int adb_got_sleep; |
86 | static int adb_inited; | 85 | static int adb_inited; |
@@ -290,7 +289,7 @@ static int adb_resume(struct platform_device *dev) | |||
290 | } | 289 | } |
291 | #endif /* CONFIG_PM */ | 290 | #endif /* CONFIG_PM */ |
292 | 291 | ||
293 | int __init adb_init(void) | 292 | static int __init adb_init(void) |
294 | { | 293 | { |
295 | struct adb_driver *driver; | 294 | struct adb_driver *driver; |
296 | int i; | 295 | int i; |
diff --git a/drivers/macintosh/adbhid.c b/drivers/macintosh/adbhid.c index ef4c117ea35f..59ea520a5d7a 100644 --- a/drivers/macintosh/adbhid.c +++ b/drivers/macintosh/adbhid.c | |||
@@ -75,7 +75,7 @@ static struct notifier_block adbhid_adb_notifier = { | |||
75 | #define ADB_KEY_POWER_OLD 0x7e | 75 | #define ADB_KEY_POWER_OLD 0x7e |
76 | #define ADB_KEY_POWER 0x7f | 76 | #define ADB_KEY_POWER 0x7f |
77 | 77 | ||
78 | u16 adb_to_linux_keycodes[128] = { | 78 | static const u16 adb_to_linux_keycodes[128] = { |
79 | /* 0x00 */ KEY_A, /* 30 */ | 79 | /* 0x00 */ KEY_A, /* 30 */ |
80 | /* 0x01 */ KEY_S, /* 31 */ | 80 | /* 0x01 */ KEY_S, /* 31 */ |
81 | /* 0x02 */ KEY_D, /* 32 */ | 81 | /* 0x02 */ KEY_D, /* 32 */ |
diff --git a/drivers/macintosh/macio_sysfs.c b/drivers/macintosh/macio_sysfs.c index 112e5ef728f1..9e9453b58425 100644 --- a/drivers/macintosh/macio_sysfs.c +++ b/drivers/macintosh/macio_sysfs.c | |||
@@ -44,7 +44,7 @@ static ssize_t modalias_show (struct device *dev, struct device_attribute *attr, | |||
44 | struct of_device *ofdev = to_of_device(dev); | 44 | struct of_device *ofdev = to_of_device(dev); |
45 | int len; | 45 | int len; |
46 | 46 | ||
47 | len = of_device_get_modalias(ofdev, buf, PAGE_SIZE); | 47 | len = of_device_get_modalias(ofdev, buf, PAGE_SIZE - 2); |
48 | 48 | ||
49 | buf[len] = '\n'; | 49 | buf[len] = '\n'; |
50 | buf[len+1] = 0; | 50 | buf[len+1] = 0; |
@@ -52,6 +52,15 @@ static ssize_t modalias_show (struct device *dev, struct device_attribute *attr, | |||
52 | return len+1; | 52 | return len+1; |
53 | } | 53 | } |
54 | 54 | ||
55 | static ssize_t devspec_show(struct device *dev, | ||
56 | struct device_attribute *attr, char *buf) | ||
57 | { | ||
58 | struct of_device *ofdev; | ||
59 | |||
60 | ofdev = to_of_device(dev); | ||
61 | return sprintf(buf, "%s\n", ofdev->node->full_name); | ||
62 | } | ||
63 | |||
55 | macio_config_of_attr (name, "%s\n"); | 64 | macio_config_of_attr (name, "%s\n"); |
56 | macio_config_of_attr (type, "%s\n"); | 65 | macio_config_of_attr (type, "%s\n"); |
57 | 66 | ||
@@ -60,5 +69,6 @@ struct device_attribute macio_dev_attrs[] = { | |||
60 | __ATTR_RO(type), | 69 | __ATTR_RO(type), |
61 | __ATTR_RO(compatible), | 70 | __ATTR_RO(compatible), |
62 | __ATTR_RO(modalias), | 71 | __ATTR_RO(modalias), |
72 | __ATTR_RO(devspec), | ||
63 | __ATTR_NULL | 73 | __ATTR_NULL |
64 | }; | 74 | }; |
diff --git a/drivers/macintosh/mediabay.c b/drivers/macintosh/mediabay.c index 818aba368541..b1e5b4705250 100644 --- a/drivers/macintosh/mediabay.c +++ b/drivers/macintosh/mediabay.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/init.h> | 21 | #include <linux/init.h> |
22 | #include <linux/ide.h> | 22 | #include <linux/ide.h> |
23 | #include <linux/kthread.h> | 23 | #include <linux/kthread.h> |
24 | #include <linux/mutex.h> | ||
24 | #include <asm/prom.h> | 25 | #include <asm/prom.h> |
25 | #include <asm/pgtable.h> | 26 | #include <asm/pgtable.h> |
26 | #include <asm/io.h> | 27 | #include <asm/io.h> |
@@ -77,7 +78,7 @@ struct media_bay_info { | |||
77 | int index; | 78 | int index; |
78 | int cached_gpio; | 79 | int cached_gpio; |
79 | int sleeping; | 80 | int sleeping; |
80 | struct semaphore lock; | 81 | struct mutex lock; |
81 | #ifdef CONFIG_BLK_DEV_IDE_PMAC | 82 | #ifdef CONFIG_BLK_DEV_IDE_PMAC |
82 | ide_hwif_t *cd_port; | 83 | ide_hwif_t *cd_port; |
83 | void __iomem *cd_base; | 84 | void __iomem *cd_base; |
@@ -459,27 +460,27 @@ int media_bay_set_ide_infos(struct device_node* which_bay, unsigned long base, | |||
459 | if (bay->mdev && which_bay == bay->mdev->ofdev.node) { | 460 | if (bay->mdev && which_bay == bay->mdev->ofdev.node) { |
460 | int timeout = 5000, index = hwif->index; | 461 | int timeout = 5000, index = hwif->index; |
461 | 462 | ||
462 | down(&bay->lock); | 463 | mutex_lock(&bay->lock); |
463 | 464 | ||
464 | bay->cd_port = hwif; | 465 | bay->cd_port = hwif; |
465 | bay->cd_base = (void __iomem *) base; | 466 | bay->cd_base = (void __iomem *) base; |
466 | bay->cd_irq = irq; | 467 | bay->cd_irq = irq; |
467 | 468 | ||
468 | if ((MB_CD != bay->content_id) || bay->state != mb_up) { | 469 | if ((MB_CD != bay->content_id) || bay->state != mb_up) { |
469 | up(&bay->lock); | 470 | mutex_unlock(&bay->lock); |
470 | return 0; | 471 | return 0; |
471 | } | 472 | } |
472 | printk(KERN_DEBUG "Registered ide%d for media bay %d\n", index, i); | 473 | printk(KERN_DEBUG "Registered ide%d for media bay %d\n", index, i); |
473 | do { | 474 | do { |
474 | if (MB_IDE_READY(i)) { | 475 | if (MB_IDE_READY(i)) { |
475 | bay->cd_index = index; | 476 | bay->cd_index = index; |
476 | up(&bay->lock); | 477 | mutex_unlock(&bay->lock); |
477 | return 0; | 478 | return 0; |
478 | } | 479 | } |
479 | mdelay(1); | 480 | mdelay(1); |
480 | } while(--timeout); | 481 | } while(--timeout); |
481 | printk(KERN_DEBUG "Timeount waiting IDE in bay %d\n", i); | 482 | printk(KERN_DEBUG "Timeount waiting IDE in bay %d\n", i); |
482 | up(&bay->lock); | 483 | mutex_unlock(&bay->lock); |
483 | return -ENODEV; | 484 | return -ENODEV; |
484 | } | 485 | } |
485 | } | 486 | } |
@@ -617,10 +618,10 @@ static int media_bay_task(void *x) | |||
617 | 618 | ||
618 | while (!kthread_should_stop()) { | 619 | while (!kthread_should_stop()) { |
619 | for (i = 0; i < media_bay_count; ++i) { | 620 | for (i = 0; i < media_bay_count; ++i) { |
620 | down(&media_bays[i].lock); | 621 | mutex_lock(&media_bays[i].lock); |
621 | if (!media_bays[i].sleeping) | 622 | if (!media_bays[i].sleeping) |
622 | media_bay_step(i); | 623 | media_bay_step(i); |
623 | up(&media_bays[i].lock); | 624 | mutex_unlock(&media_bays[i].lock); |
624 | } | 625 | } |
625 | 626 | ||
626 | msleep_interruptible(MB_POLL_DELAY); | 627 | msleep_interruptible(MB_POLL_DELAY); |
@@ -660,7 +661,7 @@ static int __devinit media_bay_attach(struct macio_dev *mdev, const struct of_de | |||
660 | bay->index = i; | 661 | bay->index = i; |
661 | bay->ops = match->data; | 662 | bay->ops = match->data; |
662 | bay->sleeping = 0; | 663 | bay->sleeping = 0; |
663 | init_MUTEX(&bay->lock); | 664 | mutex_init(&bay->lock); |
664 | 665 | ||
665 | /* Init HW probing */ | 666 | /* Init HW probing */ |
666 | if (bay->ops->init) | 667 | if (bay->ops->init) |
@@ -698,10 +699,10 @@ static int media_bay_suspend(struct macio_dev *mdev, pm_message_t state) | |||
698 | 699 | ||
699 | if (state.event != mdev->ofdev.dev.power.power_state.event | 700 | if (state.event != mdev->ofdev.dev.power.power_state.event |
700 | && (state.event & PM_EVENT_SLEEP)) { | 701 | && (state.event & PM_EVENT_SLEEP)) { |
701 | down(&bay->lock); | 702 | mutex_lock(&bay->lock); |
702 | bay->sleeping = 1; | 703 | bay->sleeping = 1; |
703 | set_mb_power(bay, 0); | 704 | set_mb_power(bay, 0); |
704 | up(&bay->lock); | 705 | mutex_unlock(&bay->lock); |
705 | msleep(MB_POLL_DELAY); | 706 | msleep(MB_POLL_DELAY); |
706 | mdev->ofdev.dev.power.power_state = state; | 707 | mdev->ofdev.dev.power.power_state = state; |
707 | } | 708 | } |
@@ -720,12 +721,12 @@ static int media_bay_resume(struct macio_dev *mdev) | |||
720 | they seem to help the 3400 get it right. | 721 | they seem to help the 3400 get it right. |
721 | */ | 722 | */ |
722 | /* Force MB power to 0 */ | 723 | /* Force MB power to 0 */ |
723 | down(&bay->lock); | 724 | mutex_lock(&bay->lock); |
724 | set_mb_power(bay, 0); | 725 | set_mb_power(bay, 0); |
725 | msleep(MB_POWER_DELAY); | 726 | msleep(MB_POWER_DELAY); |
726 | if (bay->ops->content(bay) != bay->content_id) { | 727 | if (bay->ops->content(bay) != bay->content_id) { |
727 | printk("mediabay%d: content changed during sleep...\n", bay->index); | 728 | printk("mediabay%d: content changed during sleep...\n", bay->index); |
728 | up(&bay->lock); | 729 | mutex_unlock(&bay->lock); |
729 | return 0; | 730 | return 0; |
730 | } | 731 | } |
731 | set_mb_power(bay, 1); | 732 | set_mb_power(bay, 1); |
@@ -741,7 +742,7 @@ static int media_bay_resume(struct macio_dev *mdev) | |||
741 | } while((bay->state != mb_empty) && | 742 | } while((bay->state != mb_empty) && |
742 | (bay->state != mb_up)); | 743 | (bay->state != mb_up)); |
743 | bay->sleeping = 0; | 744 | bay->sleeping = 0; |
744 | up(&bay->lock); | 745 | mutex_unlock(&bay->lock); |
745 | } | 746 | } |
746 | return 0; | 747 | return 0; |
747 | } | 748 | } |
diff --git a/drivers/macintosh/smu.c b/drivers/macintosh/smu.c index 32cb0298f88e..96faa799b82a 100644 --- a/drivers/macintosh/smu.c +++ b/drivers/macintosh/smu.c | |||
@@ -36,6 +36,8 @@ | |||
36 | #include <linux/sysdev.h> | 36 | #include <linux/sysdev.h> |
37 | #include <linux/poll.h> | 37 | #include <linux/poll.h> |
38 | #include <linux/mutex.h> | 38 | #include <linux/mutex.h> |
39 | #include <linux/of_device.h> | ||
40 | #include <linux/of_platform.h> | ||
39 | 41 | ||
40 | #include <asm/byteorder.h> | 42 | #include <asm/byteorder.h> |
41 | #include <asm/io.h> | 43 | #include <asm/io.h> |
@@ -46,8 +48,6 @@ | |||
46 | #include <asm/sections.h> | 48 | #include <asm/sections.h> |
47 | #include <asm/abs_addr.h> | 49 | #include <asm/abs_addr.h> |
48 | #include <asm/uaccess.h> | 50 | #include <asm/uaccess.h> |
49 | #include <asm/of_device.h> | ||
50 | #include <asm/of_platform.h> | ||
51 | 51 | ||
52 | #define VERSION "0.7" | 52 | #define VERSION "0.7" |
53 | #define AUTHOR "(c) 2005 Benjamin Herrenschmidt, IBM Corp." | 53 | #define AUTHOR "(c) 2005 Benjamin Herrenschmidt, IBM Corp." |
@@ -475,6 +475,7 @@ int __init smu_init (void) | |||
475 | { | 475 | { |
476 | struct device_node *np; | 476 | struct device_node *np; |
477 | const u32 *data; | 477 | const u32 *data; |
478 | int ret = 0; | ||
478 | 479 | ||
479 | np = of_find_node_by_type(NULL, "smu"); | 480 | np = of_find_node_by_type(NULL, "smu"); |
480 | if (np == NULL) | 481 | if (np == NULL) |
@@ -484,16 +485,11 @@ int __init smu_init (void) | |||
484 | 485 | ||
485 | if (smu_cmdbuf_abs == 0) { | 486 | if (smu_cmdbuf_abs == 0) { |
486 | printk(KERN_ERR "SMU: Command buffer not allocated !\n"); | 487 | printk(KERN_ERR "SMU: Command buffer not allocated !\n"); |
487 | of_node_put(np); | 488 | ret = -EINVAL; |
488 | return -EINVAL; | 489 | goto fail_np; |
489 | } | 490 | } |
490 | 491 | ||
491 | smu = alloc_bootmem(sizeof(struct smu_device)); | 492 | smu = alloc_bootmem(sizeof(struct smu_device)); |
492 | if (smu == NULL) { | ||
493 | of_node_put(np); | ||
494 | return -ENOMEM; | ||
495 | } | ||
496 | memset(smu, 0, sizeof(*smu)); | ||
497 | 493 | ||
498 | spin_lock_init(&smu->lock); | 494 | spin_lock_init(&smu->lock); |
499 | INIT_LIST_HEAD(&smu->cmd_list); | 495 | INIT_LIST_HEAD(&smu->cmd_list); |
@@ -511,14 +507,14 @@ int __init smu_init (void) | |||
511 | smu->db_node = of_find_node_by_name(NULL, "smu-doorbell"); | 507 | smu->db_node = of_find_node_by_name(NULL, "smu-doorbell"); |
512 | if (smu->db_node == NULL) { | 508 | if (smu->db_node == NULL) { |
513 | printk(KERN_ERR "SMU: Can't find doorbell GPIO !\n"); | 509 | printk(KERN_ERR "SMU: Can't find doorbell GPIO !\n"); |
514 | goto fail; | 510 | ret = -ENXIO; |
511 | goto fail_bootmem; | ||
515 | } | 512 | } |
516 | data = of_get_property(smu->db_node, "reg", NULL); | 513 | data = of_get_property(smu->db_node, "reg", NULL); |
517 | if (data == NULL) { | 514 | if (data == NULL) { |
518 | of_node_put(smu->db_node); | ||
519 | smu->db_node = NULL; | ||
520 | printk(KERN_ERR "SMU: Can't find doorbell GPIO address !\n"); | 515 | printk(KERN_ERR "SMU: Can't find doorbell GPIO address !\n"); |
521 | goto fail; | 516 | ret = -ENXIO; |
517 | goto fail_db_node; | ||
522 | } | 518 | } |
523 | 519 | ||
524 | /* Current setup has one doorbell GPIO that does both doorbell | 520 | /* Current setup has one doorbell GPIO that does both doorbell |
@@ -552,7 +548,8 @@ int __init smu_init (void) | |||
552 | smu->db_buf = ioremap(0x8000860c, 0x1000); | 548 | smu->db_buf = ioremap(0x8000860c, 0x1000); |
553 | if (smu->db_buf == NULL) { | 549 | if (smu->db_buf == NULL) { |
554 | printk(KERN_ERR "SMU: Can't map doorbell buffer pointer !\n"); | 550 | printk(KERN_ERR "SMU: Can't map doorbell buffer pointer !\n"); |
555 | goto fail; | 551 | ret = -ENXIO; |
552 | goto fail_msg_node; | ||
556 | } | 553 | } |
557 | 554 | ||
558 | /* U3 has an issue with NAP mode when issuing SMU commands */ | 555 | /* U3 has an issue with NAP mode when issuing SMU commands */ |
@@ -563,10 +560,17 @@ int __init smu_init (void) | |||
563 | sys_ctrler = SYS_CTRLER_SMU; | 560 | sys_ctrler = SYS_CTRLER_SMU; |
564 | return 0; | 561 | return 0; |
565 | 562 | ||
566 | fail: | 563 | fail_msg_node: |
564 | if (smu->msg_node) | ||
565 | of_node_put(smu->msg_node); | ||
566 | fail_db_node: | ||
567 | of_node_put(smu->db_node); | ||
568 | fail_bootmem: | ||
569 | free_bootmem((unsigned long)smu, sizeof(struct smu_device)); | ||
567 | smu = NULL; | 570 | smu = NULL; |
568 | return -ENXIO; | 571 | fail_np: |
569 | 572 | of_node_put(np); | |
573 | return ret; | ||
570 | } | 574 | } |
571 | 575 | ||
572 | 576 | ||
diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c index 5366dc93fb38..22bf981d393b 100644 --- a/drivers/macintosh/therm_adt746x.c +++ b/drivers/macintosh/therm_adt746x.c | |||
@@ -24,13 +24,13 @@ | |||
24 | #include <linux/kthread.h> | 24 | #include <linux/kthread.h> |
25 | #include <linux/moduleparam.h> | 25 | #include <linux/moduleparam.h> |
26 | #include <linux/freezer.h> | 26 | #include <linux/freezer.h> |
27 | #include <linux/of_platform.h> | ||
27 | 28 | ||
28 | #include <asm/prom.h> | 29 | #include <asm/prom.h> |
29 | #include <asm/machdep.h> | 30 | #include <asm/machdep.h> |
30 | #include <asm/io.h> | 31 | #include <asm/io.h> |
31 | #include <asm/system.h> | 32 | #include <asm/system.h> |
32 | #include <asm/sections.h> | 33 | #include <asm/sections.h> |
33 | #include <asm/of_platform.h> | ||
34 | 34 | ||
35 | #undef DEBUG | 35 | #undef DEBUG |
36 | 36 | ||
diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c index ddfb426a9abd..817607e2af6a 100644 --- a/drivers/macintosh/therm_pm72.c +++ b/drivers/macintosh/therm_pm72.c | |||
@@ -123,14 +123,14 @@ | |||
123 | #include <linux/i2c.h> | 123 | #include <linux/i2c.h> |
124 | #include <linux/kthread.h> | 124 | #include <linux/kthread.h> |
125 | #include <linux/mutex.h> | 125 | #include <linux/mutex.h> |
126 | #include <linux/of_device.h> | ||
127 | #include <linux/of_platform.h> | ||
126 | #include <asm/prom.h> | 128 | #include <asm/prom.h> |
127 | #include <asm/machdep.h> | 129 | #include <asm/machdep.h> |
128 | #include <asm/io.h> | 130 | #include <asm/io.h> |
129 | #include <asm/system.h> | 131 | #include <asm/system.h> |
130 | #include <asm/sections.h> | 132 | #include <asm/sections.h> |
131 | #include <asm/of_device.h> | ||
132 | #include <asm/macio.h> | 133 | #include <asm/macio.h> |
133 | #include <asm/of_platform.h> | ||
134 | 134 | ||
135 | #include "therm_pm72.h" | 135 | #include "therm_pm72.h" |
136 | 136 | ||
diff --git a/drivers/macintosh/therm_windtunnel.c b/drivers/macintosh/therm_windtunnel.c index d11821af3b8d..3da0a02efd76 100644 --- a/drivers/macintosh/therm_windtunnel.c +++ b/drivers/macintosh/therm_windtunnel.c | |||
@@ -37,13 +37,13 @@ | |||
37 | #include <linux/slab.h> | 37 | #include <linux/slab.h> |
38 | #include <linux/init.h> | 38 | #include <linux/init.h> |
39 | #include <linux/kthread.h> | 39 | #include <linux/kthread.h> |
40 | #include <linux/of_platform.h> | ||
40 | 41 | ||
41 | #include <asm/prom.h> | 42 | #include <asm/prom.h> |
42 | #include <asm/machdep.h> | 43 | #include <asm/machdep.h> |
43 | #include <asm/io.h> | 44 | #include <asm/io.h> |
44 | #include <asm/system.h> | 45 | #include <asm/system.h> |
45 | #include <asm/sections.h> | 46 | #include <asm/sections.h> |
46 | #include <asm/of_platform.h> | ||
47 | #include <asm/macio.h> | 47 | #include <asm/macio.h> |
48 | 48 | ||
49 | #define LOG_TEMP 0 /* continously log temperature */ | 49 | #define LOG_TEMP 0 /* continously log temperature */ |
@@ -62,7 +62,7 @@ static struct { | |||
62 | volatile int running; | 62 | volatile int running; |
63 | struct task_struct *poll_task; | 63 | struct task_struct *poll_task; |
64 | 64 | ||
65 | struct semaphore lock; | 65 | struct mutex lock; |
66 | struct of_device *of_dev; | 66 | struct of_device *of_dev; |
67 | 67 | ||
68 | struct i2c_client *thermostat; | 68 | struct i2c_client *thermostat; |
@@ -286,23 +286,23 @@ restore_regs( void ) | |||
286 | 286 | ||
287 | static int control_loop(void *dummy) | 287 | static int control_loop(void *dummy) |
288 | { | 288 | { |
289 | down(&x.lock); | 289 | mutex_lock(&x.lock); |
290 | setup_hardware(); | 290 | setup_hardware(); |
291 | up(&x.lock); | 291 | mutex_unlock(&x.lock); |
292 | 292 | ||
293 | for (;;) { | 293 | for (;;) { |
294 | msleep_interruptible(8000); | 294 | msleep_interruptible(8000); |
295 | if (kthread_should_stop()) | 295 | if (kthread_should_stop()) |
296 | break; | 296 | break; |
297 | 297 | ||
298 | down(&x.lock); | 298 | mutex_lock(&x.lock); |
299 | poll_temp(); | 299 | poll_temp(); |
300 | up(&x.lock); | 300 | mutex_unlock(&x.lock); |
301 | } | 301 | } |
302 | 302 | ||
303 | down(&x.lock); | 303 | mutex_lock(&x.lock); |
304 | restore_regs(); | 304 | restore_regs(); |
305 | up(&x.lock); | 305 | mutex_unlock(&x.lock); |
306 | 306 | ||
307 | return 0; | 307 | return 0; |
308 | } | 308 | } |
@@ -489,7 +489,7 @@ g4fan_init( void ) | |||
489 | const struct apple_thermal_info *info; | 489 | const struct apple_thermal_info *info; |
490 | struct device_node *np; | 490 | struct device_node *np; |
491 | 491 | ||
492 | init_MUTEX( &x.lock ); | 492 | mutex_init(&x.lock); |
493 | 493 | ||
494 | if( !(np=of_find_node_by_name(NULL, "power-mgt")) ) | 494 | if( !(np=of_find_node_by_name(NULL, "power-mgt")) ) |
495 | return -ENODEV; | 495 | return -ENODEV; |
diff --git a/drivers/macintosh/via-pmu68k.c b/drivers/macintosh/via-pmu68k.c index e2f84da09e7c..b64741c95ac4 100644 --- a/drivers/macintosh/via-pmu68k.c +++ b/drivers/macintosh/via-pmu68k.c | |||
@@ -101,7 +101,6 @@ static int pmu_kind = PMU_UNKNOWN; | |||
101 | static int pmu_fully_inited; | 101 | static int pmu_fully_inited; |
102 | 102 | ||
103 | int asleep; | 103 | int asleep; |
104 | BLOCKING_NOTIFIER_HEAD(sleep_notifier_list); | ||
105 | 104 | ||
106 | static int pmu_probe(void); | 105 | static int pmu_probe(void); |
107 | static int pmu_init(void); | 106 | static int pmu_init(void); |
@@ -741,8 +740,8 @@ pmu_handle_data(unsigned char *data, int len) | |||
741 | } | 740 | } |
742 | } | 741 | } |
743 | 742 | ||
744 | int backlight_level = -1; | 743 | static int backlight_level = -1; |
745 | int backlight_enabled = 0; | 744 | static int backlight_enabled = 0; |
746 | 745 | ||
747 | #define LEVEL_TO_BRIGHT(lev) ((lev) < 1? 0x7f: 0x4a - ((lev) << 1)) | 746 | #define LEVEL_TO_BRIGHT(lev) ((lev) < 1? 0x7f: 0x4a - ((lev) << 1)) |
748 | 747 | ||
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 45a41b597da9..2683ee32fc11 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig | |||
@@ -1884,7 +1884,6 @@ config NE_H8300 | |||
1884 | Say Y here if you want to use the NE2000 compatible | 1884 | Say Y here if you want to use the NE2000 compatible |
1885 | controller on the Renesas H8/300 processor. | 1885 | controller on the Renesas H8/300 processor. |
1886 | 1886 | ||
1887 | source "drivers/net/fec_8xx/Kconfig" | ||
1888 | source "drivers/net/fs_enet/Kconfig" | 1887 | source "drivers/net/fs_enet/Kconfig" |
1889 | 1888 | ||
1890 | endif # NET_ETHERNET | 1889 | endif # NET_ETHERNET |
diff --git a/drivers/net/Makefile b/drivers/net/Makefile index dcbfe8421154..9010e58da0f2 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile | |||
@@ -217,7 +217,6 @@ obj-$(CONFIG_SMC91X) += smc91x.o | |||
217 | obj-$(CONFIG_SMC911X) += smc911x.o | 217 | obj-$(CONFIG_SMC911X) += smc911x.o |
218 | obj-$(CONFIG_BFIN_MAC) += bfin_mac.o | 218 | obj-$(CONFIG_BFIN_MAC) += bfin_mac.o |
219 | obj-$(CONFIG_DM9000) += dm9000.o | 219 | obj-$(CONFIG_DM9000) += dm9000.o |
220 | obj-$(CONFIG_FEC_8XX) += fec_8xx/ | ||
221 | obj-$(CONFIG_PASEMI_MAC) += pasemi_mac_driver.o | 220 | obj-$(CONFIG_PASEMI_MAC) += pasemi_mac_driver.o |
222 | pasemi_mac_driver-objs := pasemi_mac.o pasemi_mac_ethtool.o | 221 | pasemi_mac_driver-objs := pasemi_mac.o pasemi_mac_ethtool.o |
223 | obj-$(CONFIG_MLX4_CORE) += mlx4/ | 222 | obj-$(CONFIG_MLX4_CORE) += mlx4/ |
diff --git a/drivers/net/fec_8xx/Kconfig b/drivers/net/fec_8xx/Kconfig deleted file mode 100644 index afb34ded26ee..000000000000 --- a/drivers/net/fec_8xx/Kconfig +++ /dev/null | |||
@@ -1,20 +0,0 @@ | |||
1 | config FEC_8XX | ||
2 | tristate "Motorola 8xx FEC driver" | ||
3 | depends on 8XX | ||
4 | select MII | ||
5 | |||
6 | config FEC_8XX_GENERIC_PHY | ||
7 | bool "Support any generic PHY" | ||
8 | depends on FEC_8XX | ||
9 | default y | ||
10 | |||
11 | config FEC_8XX_DM9161_PHY | ||
12 | bool "Support DM9161 PHY" | ||
13 | depends on FEC_8XX | ||
14 | default n | ||
15 | |||
16 | config FEC_8XX_LXT971_PHY | ||
17 | bool "Support LXT971/LXT972 PHY" | ||
18 | depends on FEC_8XX | ||
19 | default n | ||
20 | |||
diff --git a/drivers/net/fec_8xx/Makefile b/drivers/net/fec_8xx/Makefile deleted file mode 100644 index 70c54f8c48e5..000000000000 --- a/drivers/net/fec_8xx/Makefile +++ /dev/null | |||
@@ -1,12 +0,0 @@ | |||
1 | # | ||
2 | # Makefile for the Motorola 8xx FEC ethernet controller | ||
3 | # | ||
4 | |||
5 | obj-$(CONFIG_FEC_8XX) += fec_8xx.o | ||
6 | |||
7 | fec_8xx-objs := fec_main.o fec_mii.o | ||
8 | |||
9 | # the platform instantatiation objects | ||
10 | ifeq ($(CONFIG_NETTA),y) | ||
11 | fec_8xx-objs += fec_8xx-netta.o | ||
12 | endif | ||
diff --git a/drivers/net/fec_8xx/fec_8xx-netta.c b/drivers/net/fec_8xx/fec_8xx-netta.c deleted file mode 100644 index 79deee222e28..000000000000 --- a/drivers/net/fec_8xx/fec_8xx-netta.c +++ /dev/null | |||
@@ -1,151 +0,0 @@ | |||
1 | /* | ||
2 | * FEC instantatiation file for NETTA | ||
3 | */ | ||
4 | |||
5 | #include <linux/kernel.h> | ||
6 | #include <linux/types.h> | ||
7 | #include <linux/string.h> | ||
8 | #include <linux/ptrace.h> | ||
9 | #include <linux/errno.h> | ||
10 | #include <linux/ioport.h> | ||
11 | #include <linux/slab.h> | ||
12 | #include <linux/interrupt.h> | ||
13 | #include <linux/pci.h> | ||
14 | #include <linux/init.h> | ||
15 | #include <linux/delay.h> | ||
16 | #include <linux/netdevice.h> | ||
17 | #include <linux/etherdevice.h> | ||
18 | #include <linux/skbuff.h> | ||
19 | #include <linux/spinlock.h> | ||
20 | #include <linux/mii.h> | ||
21 | #include <linux/ethtool.h> | ||
22 | #include <linux/bitops.h> | ||
23 | |||
24 | #include <asm/8xx_immap.h> | ||
25 | #include <asm/pgtable.h> | ||
26 | #include <asm/mpc8xx.h> | ||
27 | #include <asm/irq.h> | ||
28 | #include <asm/uaccess.h> | ||
29 | #include <asm/cpm1.h> | ||
30 | |||
31 | #include "fec_8xx.h" | ||
32 | |||
33 | /*************************************************/ | ||
34 | |||
35 | static struct fec_platform_info fec1_info = { | ||
36 | .fec_no = 0, | ||
37 | .use_mdio = 1, | ||
38 | .phy_addr = 8, | ||
39 | .fec_irq = SIU_LEVEL1, | ||
40 | .phy_irq = CPM_IRQ_OFFSET + CPMVEC_PIO_PC6, | ||
41 | .rx_ring = 128, | ||
42 | .tx_ring = 16, | ||
43 | .rx_copybreak = 240, | ||
44 | .use_napi = 1, | ||
45 | .napi_weight = 17, | ||
46 | }; | ||
47 | |||
48 | static struct fec_platform_info fec2_info = { | ||
49 | .fec_no = 1, | ||
50 | .use_mdio = 1, | ||
51 | .phy_addr = 2, | ||
52 | .fec_irq = SIU_LEVEL3, | ||
53 | .phy_irq = CPM_IRQ_OFFSET + CPMVEC_PIO_PC7, | ||
54 | .rx_ring = 128, | ||
55 | .tx_ring = 16, | ||
56 | .rx_copybreak = 240, | ||
57 | .use_napi = 1, | ||
58 | .napi_weight = 17, | ||
59 | }; | ||
60 | |||
61 | static struct net_device *fec1_dev; | ||
62 | static struct net_device *fec2_dev; | ||
63 | |||
64 | /* XXX custom u-boot & Linux startup needed */ | ||
65 | extern const char *__fw_getenv(const char *var); | ||
66 | |||
67 | /* access ports */ | ||
68 | #define setbits32(_addr, _v) __fec_out32(&(_addr), __fec_in32(&(_addr)) | (_v)) | ||
69 | #define clrbits32(_addr, _v) __fec_out32(&(_addr), __fec_in32(&(_addr)) & ~(_v)) | ||
70 | |||
71 | #define setbits16(_addr, _v) __fec_out16(&(_addr), __fec_in16(&(_addr)) | (_v)) | ||
72 | #define clrbits16(_addr, _v) __fec_out16(&(_addr), __fec_in16(&(_addr)) & ~(_v)) | ||
73 | |||
74 | int fec_8xx_platform_init(void) | ||
75 | { | ||
76 | immap_t *immap = (immap_t *)IMAP_ADDR; | ||
77 | bd_t *bd = (bd_t *) __res; | ||
78 | const char *s; | ||
79 | char *e; | ||
80 | int i; | ||
81 | |||
82 | /* use MDC for MII */ | ||
83 | setbits16(immap->im_ioport.iop_pdpar, 0x0080); | ||
84 | clrbits16(immap->im_ioport.iop_pddir, 0x0080); | ||
85 | |||
86 | /* configure FEC1 pins */ | ||
87 | setbits16(immap->im_ioport.iop_papar, 0xe810); | ||
88 | setbits16(immap->im_ioport.iop_padir, 0x0810); | ||
89 | clrbits16(immap->im_ioport.iop_padir, 0xe000); | ||
90 | |||
91 | setbits32(immap->im_cpm.cp_pbpar, 0x00000001); | ||
92 | clrbits32(immap->im_cpm.cp_pbdir, 0x00000001); | ||
93 | |||
94 | setbits32(immap->im_cpm.cp_cptr, 0x00000100); | ||
95 | clrbits32(immap->im_cpm.cp_cptr, 0x00000050); | ||
96 | |||
97 | clrbits16(immap->im_ioport.iop_pcpar, 0x0200); | ||
98 | clrbits16(immap->im_ioport.iop_pcdir, 0x0200); | ||
99 | clrbits16(immap->im_ioport.iop_pcso, 0x0200); | ||
100 | setbits16(immap->im_ioport.iop_pcint, 0x0200); | ||
101 | |||
102 | /* configure FEC2 pins */ | ||
103 | setbits32(immap->im_cpm.cp_pepar, 0x00039620); | ||
104 | setbits32(immap->im_cpm.cp_pedir, 0x00039620); | ||
105 | setbits32(immap->im_cpm.cp_peso, 0x00031000); | ||
106 | clrbits32(immap->im_cpm.cp_peso, 0x00008620); | ||
107 | |||
108 | setbits32(immap->im_cpm.cp_cptr, 0x00000080); | ||
109 | clrbits32(immap->im_cpm.cp_cptr, 0x00000028); | ||
110 | |||
111 | clrbits16(immap->im_ioport.iop_pcpar, 0x0200); | ||
112 | clrbits16(immap->im_ioport.iop_pcdir, 0x0200); | ||
113 | clrbits16(immap->im_ioport.iop_pcso, 0x0200); | ||
114 | setbits16(immap->im_ioport.iop_pcint, 0x0200); | ||
115 | |||
116 | /* fill up */ | ||
117 | fec1_info.sys_clk = bd->bi_intfreq; | ||
118 | fec2_info.sys_clk = bd->bi_intfreq; | ||
119 | |||
120 | s = __fw_getenv("ethaddr"); | ||
121 | if (s != NULL) { | ||
122 | for (i = 0; i < 6; i++) { | ||
123 | fec1_info.macaddr[i] = simple_strtoul(s, &e, 16); | ||
124 | if (*e) | ||
125 | s = e + 1; | ||
126 | } | ||
127 | } | ||
128 | |||
129 | s = __fw_getenv("eth1addr"); | ||
130 | if (s != NULL) { | ||
131 | for (i = 0; i < 6; i++) { | ||
132 | fec2_info.macaddr[i] = simple_strtoul(s, &e, 16); | ||
133 | if (*e) | ||
134 | s = e + 1; | ||
135 | } | ||
136 | } | ||
137 | |||
138 | fec_8xx_init_one(&fec1_info, &fec1_dev); | ||
139 | fec_8xx_init_one(&fec2_info, &fec2_dev); | ||
140 | |||
141 | return fec1_dev != NULL && fec2_dev != NULL ? 0 : -1; | ||
142 | } | ||
143 | |||
144 | void fec_8xx_platform_cleanup(void) | ||
145 | { | ||
146 | if (fec2_dev != NULL) | ||
147 | fec_8xx_cleanup_one(fec2_dev); | ||
148 | |||
149 | if (fec1_dev != NULL) | ||
150 | fec_8xx_cleanup_one(fec1_dev); | ||
151 | } | ||
diff --git a/drivers/net/fec_8xx/fec_8xx.h b/drivers/net/fec_8xx/fec_8xx.h deleted file mode 100644 index f3b1c6fbba8b..000000000000 --- a/drivers/net/fec_8xx/fec_8xx.h +++ /dev/null | |||
@@ -1,220 +0,0 @@ | |||
1 | #ifndef FEC_8XX_H | ||
2 | #define FEC_8XX_H | ||
3 | |||
4 | #include <linux/mii.h> | ||
5 | #include <linux/netdevice.h> | ||
6 | |||
7 | #include <linux/types.h> | ||
8 | |||
9 | /* HW info */ | ||
10 | |||
11 | /* CRC polynomium used by the FEC for the multicast group filtering */ | ||
12 | #define FEC_CRC_POLY 0x04C11DB7 | ||
13 | |||
14 | #define MII_ADVERTISE_HALF (ADVERTISE_100HALF | \ | ||
15 | ADVERTISE_10HALF | ADVERTISE_CSMA) | ||
16 | #define MII_ADVERTISE_ALL (ADVERTISE_100FULL | \ | ||
17 | ADVERTISE_10FULL | MII_ADVERTISE_HALF) | ||
18 | |||
19 | /* Interrupt events/masks. | ||
20 | */ | ||
21 | #define FEC_ENET_HBERR 0x80000000U /* Heartbeat error */ | ||
22 | #define FEC_ENET_BABR 0x40000000U /* Babbling receiver */ | ||
23 | #define FEC_ENET_BABT 0x20000000U /* Babbling transmitter */ | ||
24 | #define FEC_ENET_GRA 0x10000000U /* Graceful stop complete */ | ||
25 | #define FEC_ENET_TXF 0x08000000U /* Full frame transmitted */ | ||
26 | #define FEC_ENET_TXB 0x04000000U /* A buffer was transmitted */ | ||
27 | #define FEC_ENET_RXF 0x02000000U /* Full frame received */ | ||
28 | #define FEC_ENET_RXB 0x01000000U /* A buffer was received */ | ||
29 | #define FEC_ENET_MII 0x00800000U /* MII interrupt */ | ||
30 | #define FEC_ENET_EBERR 0x00400000U /* SDMA bus error */ | ||
31 | |||
32 | #define FEC_ECNTRL_PINMUX 0x00000004 | ||
33 | #define FEC_ECNTRL_ETHER_EN 0x00000002 | ||
34 | #define FEC_ECNTRL_RESET 0x00000001 | ||
35 | |||
36 | #define FEC_RCNTRL_BC_REJ 0x00000010 | ||
37 | #define FEC_RCNTRL_PROM 0x00000008 | ||
38 | #define FEC_RCNTRL_MII_MODE 0x00000004 | ||
39 | #define FEC_RCNTRL_DRT 0x00000002 | ||
40 | #define FEC_RCNTRL_LOOP 0x00000001 | ||
41 | |||
42 | #define FEC_TCNTRL_FDEN 0x00000004 | ||
43 | #define FEC_TCNTRL_HBC 0x00000002 | ||
44 | #define FEC_TCNTRL_GTS 0x00000001 | ||
45 | |||
46 | /* values for MII phy_status */ | ||
47 | |||
48 | #define PHY_CONF_ANE 0x0001 /* 1 auto-negotiation enabled */ | ||
49 | #define PHY_CONF_LOOP 0x0002 /* 1 loopback mode enabled */ | ||
50 | #define PHY_CONF_SPMASK 0x00f0 /* mask for speed */ | ||
51 | #define PHY_CONF_10HDX 0x0010 /* 10 Mbit half duplex supported */ | ||
52 | #define PHY_CONF_10FDX 0x0020 /* 10 Mbit full duplex supported */ | ||
53 | #define PHY_CONF_100HDX 0x0040 /* 100 Mbit half duplex supported */ | ||
54 | #define PHY_CONF_100FDX 0x0080 /* 100 Mbit full duplex supported */ | ||
55 | |||
56 | #define PHY_STAT_LINK 0x0100 /* 1 up - 0 down */ | ||
57 | #define PHY_STAT_FAULT 0x0200 /* 1 remote fault */ | ||
58 | #define PHY_STAT_ANC 0x0400 /* 1 auto-negotiation complete */ | ||
59 | #define PHY_STAT_SPMASK 0xf000 /* mask for speed */ | ||
60 | #define PHY_STAT_10HDX 0x1000 /* 10 Mbit half duplex selected */ | ||
61 | #define PHY_STAT_10FDX 0x2000 /* 10 Mbit full duplex selected */ | ||
62 | #define PHY_STAT_100HDX 0x4000 /* 100 Mbit half duplex selected */ | ||
63 | #define PHY_STAT_100FDX 0x8000 /* 100 Mbit full duplex selected */ | ||
64 | |||
65 | typedef struct phy_info { | ||
66 | unsigned int id; | ||
67 | const char *name; | ||
68 | void (*startup) (struct net_device * dev); | ||
69 | void (*shutdown) (struct net_device * dev); | ||
70 | void (*ack_int) (struct net_device * dev); | ||
71 | } phy_info_t; | ||
72 | |||
73 | /* The FEC stores dest/src/type, data, and checksum for receive packets. | ||
74 | */ | ||
75 | #define MAX_MTU 1508 /* Allow fullsized pppoe packets over VLAN */ | ||
76 | #define MIN_MTU 46 /* this is data size */ | ||
77 | #define CRC_LEN 4 | ||
78 | |||
79 | #define PKT_MAXBUF_SIZE (MAX_MTU+ETH_HLEN+CRC_LEN) | ||
80 | #define PKT_MINBUF_SIZE (MIN_MTU+ETH_HLEN+CRC_LEN) | ||
81 | |||
82 | /* Must be a multiple of 4 */ | ||
83 | #define PKT_MAXBLR_SIZE ((PKT_MAXBUF_SIZE+3) & ~3) | ||
84 | /* This is needed so that invalidate_xxx wont invalidate too much */ | ||
85 | #define ENET_RX_FRSIZE L1_CACHE_ALIGN(PKT_MAXBUF_SIZE) | ||
86 | |||
87 | /* platform interface */ | ||
88 | |||
89 | struct fec_platform_info { | ||
90 | int fec_no; /* FEC index */ | ||
91 | int use_mdio; /* use external MII */ | ||
92 | int phy_addr; /* the phy address */ | ||
93 | int fec_irq, phy_irq; /* the irq for the controller */ | ||
94 | int rx_ring, tx_ring; /* number of buffers on rx */ | ||
95 | int sys_clk; /* system clock */ | ||
96 | __u8 macaddr[6]; /* mac address */ | ||
97 | int rx_copybreak; /* limit we copy small frames */ | ||
98 | int use_napi; /* use NAPI */ | ||
99 | int napi_weight; /* NAPI weight */ | ||
100 | }; | ||
101 | |||
102 | /* forward declaration */ | ||
103 | struct fec; | ||
104 | |||
105 | struct fec_enet_private { | ||
106 | spinlock_t lock; /* during all ops except TX pckt processing */ | ||
107 | spinlock_t tx_lock; /* during fec_start_xmit and fec_tx */ | ||
108 | struct net_device *dev; | ||
109 | struct napi_struct napi; | ||
110 | int fecno; | ||
111 | struct fec *fecp; | ||
112 | const struct fec_platform_info *fpi; | ||
113 | int rx_ring, tx_ring; | ||
114 | dma_addr_t ring_mem_addr; | ||
115 | void *ring_base; | ||
116 | struct sk_buff **rx_skbuff; | ||
117 | struct sk_buff **tx_skbuff; | ||
118 | cbd_t *rx_bd_base; /* Address of Rx and Tx buffers. */ | ||
119 | cbd_t *tx_bd_base; | ||
120 | cbd_t *dirty_tx; /* ring entries to be free()ed. */ | ||
121 | cbd_t *cur_rx; | ||
122 | cbd_t *cur_tx; | ||
123 | int tx_free; | ||
124 | struct net_device_stats stats; | ||
125 | struct timer_list phy_timer_list; | ||
126 | const struct phy_info *phy; | ||
127 | unsigned int fec_phy_speed; | ||
128 | __u32 msg_enable; | ||
129 | struct mii_if_info mii_if; | ||
130 | }; | ||
131 | |||
132 | /***************************************************************************/ | ||
133 | |||
134 | void fec_restart(struct net_device *dev, int duplex, int speed); | ||
135 | void fec_stop(struct net_device *dev); | ||
136 | |||
137 | /***************************************************************************/ | ||
138 | |||
139 | int fec_mii_read(struct net_device *dev, int phy_id, int location); | ||
140 | void fec_mii_write(struct net_device *dev, int phy_id, int location, int value); | ||
141 | |||
142 | int fec_mii_phy_id_detect(struct net_device *dev); | ||
143 | void fec_mii_startup(struct net_device *dev); | ||
144 | void fec_mii_shutdown(struct net_device *dev); | ||
145 | void fec_mii_ack_int(struct net_device *dev); | ||
146 | |||
147 | void fec_mii_link_status_change_check(struct net_device *dev, int init_media); | ||
148 | |||
149 | /***************************************************************************/ | ||
150 | |||
151 | #define FEC1_NO 0x00 | ||
152 | #define FEC2_NO 0x01 | ||
153 | #define FEC3_NO 0x02 | ||
154 | |||
155 | int fec_8xx_init_one(const struct fec_platform_info *fpi, | ||
156 | struct net_device **devp); | ||
157 | int fec_8xx_cleanup_one(struct net_device *dev); | ||
158 | |||
159 | /***************************************************************************/ | ||
160 | |||
161 | #define DRV_MODULE_NAME "fec_8xx" | ||
162 | #define PFX DRV_MODULE_NAME ": " | ||
163 | #define DRV_MODULE_VERSION "0.1" | ||
164 | #define DRV_MODULE_RELDATE "May 6, 2004" | ||
165 | |||
166 | /***************************************************************************/ | ||
167 | |||
168 | int fec_8xx_platform_init(void); | ||
169 | void fec_8xx_platform_cleanup(void); | ||
170 | |||
171 | /***************************************************************************/ | ||
172 | |||
173 | /* FEC access macros */ | ||
174 | #if defined(CONFIG_8xx) | ||
175 | /* for a 8xx __raw_xxx's are sufficient */ | ||
176 | #define __fec_out32(addr, x) __raw_writel(x, addr) | ||
177 | #define __fec_out16(addr, x) __raw_writew(x, addr) | ||
178 | #define __fec_in32(addr) __raw_readl(addr) | ||
179 | #define __fec_in16(addr) __raw_readw(addr) | ||
180 | #else | ||
181 | /* for others play it safe */ | ||
182 | #define __fec_out32(addr, x) out_be32(addr, x) | ||
183 | #define __fec_out16(addr, x) out_be16(addr, x) | ||
184 | #define __fec_in32(addr) in_be32(addr) | ||
185 | #define __fec_in16(addr) in_be16(addr) | ||
186 | #endif | ||
187 | |||
188 | /* write */ | ||
189 | #define FW(_fecp, _reg, _v) __fec_out32(&(_fecp)->fec_ ## _reg, (_v)) | ||
190 | |||
191 | /* read */ | ||
192 | #define FR(_fecp, _reg) __fec_in32(&(_fecp)->fec_ ## _reg) | ||
193 | |||
194 | /* set bits */ | ||
195 | #define FS(_fecp, _reg, _v) FW(_fecp, _reg, FR(_fecp, _reg) | (_v)) | ||
196 | |||
197 | /* clear bits */ | ||
198 | #define FC(_fecp, _reg, _v) FW(_fecp, _reg, FR(_fecp, _reg) & ~(_v)) | ||
199 | |||
200 | /* buffer descriptor access macros */ | ||
201 | |||
202 | /* write */ | ||
203 | #define CBDW_SC(_cbd, _sc) __fec_out16(&(_cbd)->cbd_sc, (_sc)) | ||
204 | #define CBDW_DATLEN(_cbd, _datlen) __fec_out16(&(_cbd)->cbd_datlen, (_datlen)) | ||
205 | #define CBDW_BUFADDR(_cbd, _bufaddr) __fec_out32(&(_cbd)->cbd_bufaddr, (_bufaddr)) | ||
206 | |||
207 | /* read */ | ||
208 | #define CBDR_SC(_cbd) __fec_in16(&(_cbd)->cbd_sc) | ||
209 | #define CBDR_DATLEN(_cbd) __fec_in16(&(_cbd)->cbd_datlen) | ||
210 | #define CBDR_BUFADDR(_cbd) __fec_in32(&(_cbd)->cbd_bufaddr) | ||
211 | |||
212 | /* set bits */ | ||
213 | #define CBDS_SC(_cbd, _sc) CBDW_SC(_cbd, CBDR_SC(_cbd) | (_sc)) | ||
214 | |||
215 | /* clear bits */ | ||
216 | #define CBDC_SC(_cbd, _sc) CBDW_SC(_cbd, CBDR_SC(_cbd) & ~(_sc)) | ||
217 | |||
218 | /***************************************************************************/ | ||
219 | |||
220 | #endif | ||
diff --git a/drivers/net/fec_8xx/fec_main.c b/drivers/net/fec_8xx/fec_main.c deleted file mode 100644 index ca8d2e83ab03..000000000000 --- a/drivers/net/fec_8xx/fec_main.c +++ /dev/null | |||
@@ -1,1264 +0,0 @@ | |||
1 | /* | ||
2 | * Fast Ethernet Controller (FEC) driver for Motorola MPC8xx. | ||
3 | * | ||
4 | * Copyright (c) 2003 Intracom S.A. | ||
5 | * by Pantelis Antoniou <panto@intracom.gr> | ||
6 | * | ||
7 | * Heavily based on original FEC driver by Dan Malek <dan@embeddededge.com> | ||
8 | * and modifications by Joakim Tjernlund <joakim.tjernlund@lumentis.se> | ||
9 | * | ||
10 | * Released under the GPL | ||
11 | */ | ||
12 | |||
13 | #include <linux/module.h> | ||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/types.h> | ||
16 | #include <linux/string.h> | ||
17 | #include <linux/ptrace.h> | ||
18 | #include <linux/errno.h> | ||
19 | #include <linux/ioport.h> | ||
20 | #include <linux/slab.h> | ||
21 | #include <linux/interrupt.h> | ||
22 | #include <linux/init.h> | ||
23 | #include <linux/delay.h> | ||
24 | #include <linux/netdevice.h> | ||
25 | #include <linux/etherdevice.h> | ||
26 | #include <linux/skbuff.h> | ||
27 | #include <linux/spinlock.h> | ||
28 | #include <linux/mii.h> | ||
29 | #include <linux/ethtool.h> | ||
30 | #include <linux/bitops.h> | ||
31 | #include <linux/dma-mapping.h> | ||
32 | |||
33 | #include <asm/8xx_immap.h> | ||
34 | #include <asm/pgtable.h> | ||
35 | #include <asm/mpc8xx.h> | ||
36 | #include <asm/irq.h> | ||
37 | #include <asm/uaccess.h> | ||
38 | #include <asm/cpm1.h> | ||
39 | |||
40 | #include "fec_8xx.h" | ||
41 | |||
42 | /*************************************************/ | ||
43 | |||
44 | #define FEC_MAX_MULTICAST_ADDRS 64 | ||
45 | |||
46 | /*************************************************/ | ||
47 | |||
48 | static char version[] __devinitdata = | ||
49 | DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")" "\n"; | ||
50 | |||
51 | MODULE_AUTHOR("Pantelis Antoniou <panto@intracom.gr>"); | ||
52 | MODULE_DESCRIPTION("Motorola 8xx FEC ethernet driver"); | ||
53 | MODULE_LICENSE("GPL"); | ||
54 | |||
55 | int fec_8xx_debug = -1; /* -1 == use FEC_8XX_DEF_MSG_ENABLE as value */ | ||
56 | module_param(fec_8xx_debug, int, 0); | ||
57 | MODULE_PARM_DESC(fec_8xx_debug, | ||
58 | "FEC 8xx bitmapped debugging message enable value"); | ||
59 | |||
60 | |||
61 | /*************************************************/ | ||
62 | |||
63 | /* | ||
64 | * Delay to wait for FEC reset command to complete (in us) | ||
65 | */ | ||
66 | #define FEC_RESET_DELAY 50 | ||
67 | |||
68 | /*****************************************************************************************/ | ||
69 | |||
70 | static void fec_whack_reset(fec_t * fecp) | ||
71 | { | ||
72 | int i; | ||
73 | |||
74 | /* | ||
75 | * Whack a reset. We should wait for this. | ||
76 | */ | ||
77 | FW(fecp, ecntrl, FEC_ECNTRL_PINMUX | FEC_ECNTRL_RESET); | ||
78 | for (i = 0; | ||
79 | (FR(fecp, ecntrl) & FEC_ECNTRL_RESET) != 0 && i < FEC_RESET_DELAY; | ||
80 | i++) | ||
81 | udelay(1); | ||
82 | |||
83 | if (i == FEC_RESET_DELAY) | ||
84 | printk(KERN_WARNING "FEC Reset timeout!\n"); | ||
85 | |||
86 | } | ||
87 | |||
88 | /****************************************************************************/ | ||
89 | |||
90 | /* | ||
91 | * Transmitter timeout. | ||
92 | */ | ||
93 | #define TX_TIMEOUT (2*HZ) | ||
94 | |||
95 | /****************************************************************************/ | ||
96 | |||
97 | /* | ||
98 | * Returns the CRC needed when filling in the hash table for | ||
99 | * multicast group filtering | ||
100 | * pAddr must point to a MAC address (6 bytes) | ||
101 | */ | ||
102 | static __u32 fec_mulicast_calc_crc(char *pAddr) | ||
103 | { | ||
104 | u8 byte; | ||
105 | int byte_count; | ||
106 | int bit_count; | ||
107 | __u32 crc = 0xffffffff; | ||
108 | u8 msb; | ||
109 | |||
110 | for (byte_count = 0; byte_count < 6; byte_count++) { | ||
111 | byte = pAddr[byte_count]; | ||
112 | for (bit_count = 0; bit_count < 8; bit_count++) { | ||
113 | msb = crc >> 31; | ||
114 | crc <<= 1; | ||
115 | if (msb ^ (byte & 0x1)) { | ||
116 | crc ^= FEC_CRC_POLY; | ||
117 | } | ||
118 | byte >>= 1; | ||
119 | } | ||
120 | } | ||
121 | return (crc); | ||
122 | } | ||
123 | |||
124 | /* | ||
125 | * Set or clear the multicast filter for this adaptor. | ||
126 | * Skeleton taken from sunlance driver. | ||
127 | * The CPM Ethernet implementation allows Multicast as well as individual | ||
128 | * MAC address filtering. Some of the drivers check to make sure it is | ||
129 | * a group multicast address, and discard those that are not. I guess I | ||
130 | * will do the same for now, but just remove the test if you want | ||
131 | * individual filtering as well (do the upper net layers want or support | ||
132 | * this kind of feature?). | ||
133 | */ | ||
134 | static void fec_set_multicast_list(struct net_device *dev) | ||
135 | { | ||
136 | struct fec_enet_private *fep = netdev_priv(dev); | ||
137 | fec_t *fecp = fep->fecp; | ||
138 | struct dev_mc_list *pmc; | ||
139 | __u32 crc; | ||
140 | int temp; | ||
141 | __u32 csrVal; | ||
142 | int hash_index; | ||
143 | __u32 hthi, htlo; | ||
144 | unsigned long flags; | ||
145 | |||
146 | |||
147 | if ((dev->flags & IFF_PROMISC) != 0) { | ||
148 | |||
149 | spin_lock_irqsave(&fep->lock, flags); | ||
150 | FS(fecp, r_cntrl, FEC_RCNTRL_PROM); | ||
151 | spin_unlock_irqrestore(&fep->lock, flags); | ||
152 | |||
153 | /* | ||
154 | * Log any net taps. | ||
155 | */ | ||
156 | printk(KERN_WARNING DRV_MODULE_NAME | ||
157 | ": %s: Promiscuous mode enabled.\n", dev->name); | ||
158 | return; | ||
159 | |||
160 | } | ||
161 | |||
162 | if ((dev->flags & IFF_ALLMULTI) != 0 || | ||
163 | dev->mc_count > FEC_MAX_MULTICAST_ADDRS) { | ||
164 | /* | ||
165 | * Catch all multicast addresses, set the filter to all 1's. | ||
166 | */ | ||
167 | hthi = 0xffffffffU; | ||
168 | htlo = 0xffffffffU; | ||
169 | } else { | ||
170 | hthi = 0; | ||
171 | htlo = 0; | ||
172 | |||
173 | /* | ||
174 | * Now populate the hash table | ||
175 | */ | ||
176 | for (pmc = dev->mc_list; pmc != NULL; pmc = pmc->next) { | ||
177 | crc = fec_mulicast_calc_crc(pmc->dmi_addr); | ||
178 | temp = (crc & 0x3f) >> 1; | ||
179 | hash_index = ((temp & 0x01) << 4) | | ||
180 | ((temp & 0x02) << 2) | | ||
181 | ((temp & 0x04)) | | ||
182 | ((temp & 0x08) >> 2) | | ||
183 | ((temp & 0x10) >> 4); | ||
184 | csrVal = (1 << hash_index); | ||
185 | if (crc & 1) | ||
186 | hthi |= csrVal; | ||
187 | else | ||
188 | htlo |= csrVal; | ||
189 | } | ||
190 | } | ||
191 | |||
192 | spin_lock_irqsave(&fep->lock, flags); | ||
193 | FC(fecp, r_cntrl, FEC_RCNTRL_PROM); | ||
194 | FW(fecp, hash_table_high, hthi); | ||
195 | FW(fecp, hash_table_low, htlo); | ||
196 | spin_unlock_irqrestore(&fep->lock, flags); | ||
197 | } | ||
198 | |||
199 | static int fec_set_mac_address(struct net_device *dev, void *addr) | ||
200 | { | ||
201 | struct sockaddr *mac = addr; | ||
202 | struct fec_enet_private *fep = netdev_priv(dev); | ||
203 | struct fec *fecp = fep->fecp; | ||
204 | int i; | ||
205 | __u32 addrhi, addrlo; | ||
206 | unsigned long flags; | ||
207 | |||
208 | /* Get pointer to SCC area in parameter RAM. */ | ||
209 | for (i = 0; i < 6; i++) | ||
210 | dev->dev_addr[i] = mac->sa_data[i]; | ||
211 | |||
212 | /* | ||
213 | * Set station address. | ||
214 | */ | ||
215 | addrhi = ((__u32) dev->dev_addr[0] << 24) | | ||
216 | ((__u32) dev->dev_addr[1] << 16) | | ||
217 | ((__u32) dev->dev_addr[2] << 8) | | ||
218 | (__u32) dev->dev_addr[3]; | ||
219 | addrlo = ((__u32) dev->dev_addr[4] << 24) | | ||
220 | ((__u32) dev->dev_addr[5] << 16); | ||
221 | |||
222 | spin_lock_irqsave(&fep->lock, flags); | ||
223 | FW(fecp, addr_low, addrhi); | ||
224 | FW(fecp, addr_high, addrlo); | ||
225 | spin_unlock_irqrestore(&fep->lock, flags); | ||
226 | |||
227 | return 0; | ||
228 | } | ||
229 | |||
230 | /* | ||
231 | * This function is called to start or restart the FEC during a link | ||
232 | * change. This only happens when switching between half and full | ||
233 | * duplex. | ||
234 | */ | ||
235 | void fec_restart(struct net_device *dev, int duplex, int speed) | ||
236 | { | ||
237 | #ifdef CONFIG_DUET | ||
238 | immap_t *immap = (immap_t *) IMAP_ADDR; | ||
239 | __u32 cptr; | ||
240 | #endif | ||
241 | struct fec_enet_private *fep = netdev_priv(dev); | ||
242 | struct fec *fecp = fep->fecp; | ||
243 | const struct fec_platform_info *fpi = fep->fpi; | ||
244 | cbd_t *bdp; | ||
245 | struct sk_buff *skb; | ||
246 | int i; | ||
247 | __u32 addrhi, addrlo; | ||
248 | |||
249 | fec_whack_reset(fep->fecp); | ||
250 | |||
251 | /* | ||
252 | * Set station address. | ||
253 | */ | ||
254 | addrhi = ((__u32) dev->dev_addr[0] << 24) | | ||
255 | ((__u32) dev->dev_addr[1] << 16) | | ||
256 | ((__u32) dev->dev_addr[2] << 8) | | ||
257 | (__u32) dev->dev_addr[3]; | ||
258 | addrlo = ((__u32) dev->dev_addr[4] << 24) | | ||
259 | ((__u32) dev->dev_addr[5] << 16); | ||
260 | FW(fecp, addr_low, addrhi); | ||
261 | FW(fecp, addr_high, addrlo); | ||
262 | |||
263 | /* | ||
264 | * Reset all multicast. | ||
265 | */ | ||
266 | FW(fecp, hash_table_high, 0); | ||
267 | FW(fecp, hash_table_low, 0); | ||
268 | |||
269 | /* | ||
270 | * Set maximum receive buffer size. | ||
271 | */ | ||
272 | FW(fecp, r_buff_size, PKT_MAXBLR_SIZE); | ||
273 | FW(fecp, r_hash, PKT_MAXBUF_SIZE); | ||
274 | |||
275 | /* | ||
276 | * Set receive and transmit descriptor base. | ||
277 | */ | ||
278 | FW(fecp, r_des_start, iopa((__u32) (fep->rx_bd_base))); | ||
279 | FW(fecp, x_des_start, iopa((__u32) (fep->tx_bd_base))); | ||
280 | |||
281 | fep->dirty_tx = fep->cur_tx = fep->tx_bd_base; | ||
282 | fep->tx_free = fep->tx_ring; | ||
283 | fep->cur_rx = fep->rx_bd_base; | ||
284 | |||
285 | /* | ||
286 | * Reset SKB receive buffers | ||
287 | */ | ||
288 | for (i = 0; i < fep->rx_ring; i++) { | ||
289 | if ((skb = fep->rx_skbuff[i]) == NULL) | ||
290 | continue; | ||
291 | fep->rx_skbuff[i] = NULL; | ||
292 | dev_kfree_skb(skb); | ||
293 | } | ||
294 | |||
295 | /* | ||
296 | * Initialize the receive buffer descriptors. | ||
297 | */ | ||
298 | for (i = 0, bdp = fep->rx_bd_base; i < fep->rx_ring; i++, bdp++) { | ||
299 | skb = dev_alloc_skb(ENET_RX_FRSIZE); | ||
300 | if (skb == NULL) { | ||
301 | printk(KERN_WARNING DRV_MODULE_NAME | ||
302 | ": %s Memory squeeze, unable to allocate skb\n", | ||
303 | dev->name); | ||
304 | fep->stats.rx_dropped++; | ||
305 | break; | ||
306 | } | ||
307 | fep->rx_skbuff[i] = skb; | ||
308 | skb->dev = dev; | ||
309 | CBDW_BUFADDR(bdp, dma_map_single(NULL, skb->data, | ||
310 | L1_CACHE_ALIGN(PKT_MAXBUF_SIZE), | ||
311 | DMA_FROM_DEVICE)); | ||
312 | CBDW_DATLEN(bdp, 0); /* zero */ | ||
313 | CBDW_SC(bdp, BD_ENET_RX_EMPTY | | ||
314 | ((i < fep->rx_ring - 1) ? 0 : BD_SC_WRAP)); | ||
315 | } | ||
316 | /* | ||
317 | * if we failed, fillup remainder | ||
318 | */ | ||
319 | for (; i < fep->rx_ring; i++, bdp++) { | ||
320 | fep->rx_skbuff[i] = NULL; | ||
321 | CBDW_SC(bdp, (i < fep->rx_ring - 1) ? 0 : BD_SC_WRAP); | ||
322 | } | ||
323 | |||
324 | /* | ||
325 | * Reset SKB transmit buffers. | ||
326 | */ | ||
327 | for (i = 0; i < fep->tx_ring; i++) { | ||
328 | if ((skb = fep->tx_skbuff[i]) == NULL) | ||
329 | continue; | ||
330 | fep->tx_skbuff[i] = NULL; | ||
331 | dev_kfree_skb(skb); | ||
332 | } | ||
333 | |||
334 | /* | ||
335 | * ...and the same for transmit. | ||
336 | */ | ||
337 | for (i = 0, bdp = fep->tx_bd_base; i < fep->tx_ring; i++, bdp++) { | ||
338 | fep->tx_skbuff[i] = NULL; | ||
339 | CBDW_BUFADDR(bdp, virt_to_bus(NULL)); | ||
340 | CBDW_DATLEN(bdp, 0); | ||
341 | CBDW_SC(bdp, (i < fep->tx_ring - 1) ? 0 : BD_SC_WRAP); | ||
342 | } | ||
343 | |||
344 | /* | ||
345 | * Enable big endian and don't care about SDMA FC. | ||
346 | */ | ||
347 | FW(fecp, fun_code, 0x78000000); | ||
348 | |||
349 | /* | ||
350 | * Set MII speed. | ||
351 | */ | ||
352 | FW(fecp, mii_speed, fep->fec_phy_speed); | ||
353 | |||
354 | /* | ||
355 | * Clear any outstanding interrupt. | ||
356 | */ | ||
357 | FW(fecp, ievent, 0xffc0); | ||
358 | FW(fecp, ivec, (fpi->fec_irq / 2) << 29); | ||
359 | |||
360 | /* | ||
361 | * adjust to speed (only for DUET & RMII) | ||
362 | */ | ||
363 | #ifdef CONFIG_DUET | ||
364 | cptr = in_be32(&immap->im_cpm.cp_cptr); | ||
365 | switch (fpi->fec_no) { | ||
366 | case 0: | ||
367 | /* | ||
368 | * check if in RMII mode | ||
369 | */ | ||
370 | if ((cptr & 0x100) == 0) | ||
371 | break; | ||
372 | |||
373 | if (speed == 10) | ||
374 | cptr |= 0x0000010; | ||
375 | else if (speed == 100) | ||
376 | cptr &= ~0x0000010; | ||
377 | break; | ||
378 | case 1: | ||
379 | /* | ||
380 | * check if in RMII mode | ||
381 | */ | ||
382 | if ((cptr & 0x80) == 0) | ||
383 | break; | ||
384 | |||
385 | if (speed == 10) | ||
386 | cptr |= 0x0000008; | ||
387 | else if (speed == 100) | ||
388 | cptr &= ~0x0000008; | ||
389 | break; | ||
390 | default: | ||
391 | break; | ||
392 | } | ||
393 | out_be32(&immap->im_cpm.cp_cptr, cptr); | ||
394 | #endif | ||
395 | |||
396 | FW(fecp, r_cntrl, FEC_RCNTRL_MII_MODE); /* MII enable */ | ||
397 | /* | ||
398 | * adjust to duplex mode | ||
399 | */ | ||
400 | if (duplex) { | ||
401 | FC(fecp, r_cntrl, FEC_RCNTRL_DRT); | ||
402 | FS(fecp, x_cntrl, FEC_TCNTRL_FDEN); /* FD enable */ | ||
403 | } else { | ||
404 | FS(fecp, r_cntrl, FEC_RCNTRL_DRT); | ||
405 | FC(fecp, x_cntrl, FEC_TCNTRL_FDEN); /* FD disable */ | ||
406 | } | ||
407 | |||
408 | /* | ||
409 | * Enable interrupts we wish to service. | ||
410 | */ | ||
411 | FW(fecp, imask, FEC_ENET_TXF | FEC_ENET_TXB | | ||
412 | FEC_ENET_RXF | FEC_ENET_RXB); | ||
413 | |||
414 | /* | ||
415 | * And last, enable the transmit and receive processing. | ||
416 | */ | ||
417 | FW(fecp, ecntrl, FEC_ECNTRL_PINMUX | FEC_ECNTRL_ETHER_EN); | ||
418 | FW(fecp, r_des_active, 0x01000000); | ||
419 | } | ||
420 | |||
421 | void fec_stop(struct net_device *dev) | ||
422 | { | ||
423 | struct fec_enet_private *fep = netdev_priv(dev); | ||
424 | fec_t *fecp = fep->fecp; | ||
425 | struct sk_buff *skb; | ||
426 | int i; | ||
427 | |||
428 | if ((FR(fecp, ecntrl) & FEC_ECNTRL_ETHER_EN) == 0) | ||
429 | return; /* already down */ | ||
430 | |||
431 | FW(fecp, x_cntrl, 0x01); /* Graceful transmit stop */ | ||
432 | for (i = 0; ((FR(fecp, ievent) & 0x10000000) == 0) && | ||
433 | i < FEC_RESET_DELAY; i++) | ||
434 | udelay(1); | ||
435 | |||
436 | if (i == FEC_RESET_DELAY) | ||
437 | printk(KERN_WARNING DRV_MODULE_NAME | ||
438 | ": %s FEC timeout on graceful transmit stop\n", | ||
439 | dev->name); | ||
440 | /* | ||
441 | * Disable FEC. Let only MII interrupts. | ||
442 | */ | ||
443 | FW(fecp, imask, 0); | ||
444 | FW(fecp, ecntrl, ~FEC_ECNTRL_ETHER_EN); | ||
445 | |||
446 | /* | ||
447 | * Reset SKB transmit buffers. | ||
448 | */ | ||
449 | for (i = 0; i < fep->tx_ring; i++) { | ||
450 | if ((skb = fep->tx_skbuff[i]) == NULL) | ||
451 | continue; | ||
452 | fep->tx_skbuff[i] = NULL; | ||
453 | dev_kfree_skb(skb); | ||
454 | } | ||
455 | |||
456 | /* | ||
457 | * Reset SKB receive buffers | ||
458 | */ | ||
459 | for (i = 0; i < fep->rx_ring; i++) { | ||
460 | if ((skb = fep->rx_skbuff[i]) == NULL) | ||
461 | continue; | ||
462 | fep->rx_skbuff[i] = NULL; | ||
463 | dev_kfree_skb(skb); | ||
464 | } | ||
465 | } | ||
466 | |||
467 | /* common receive function */ | ||
468 | static int fec_enet_rx_common(struct fec_enet_private *ep, | ||
469 | struct net_device *dev, int budget) | ||
470 | { | ||
471 | fec_t *fecp = fep->fecp; | ||
472 | const struct fec_platform_info *fpi = fep->fpi; | ||
473 | cbd_t *bdp; | ||
474 | struct sk_buff *skb, *skbn, *skbt; | ||
475 | int received = 0; | ||
476 | __u16 pkt_len, sc; | ||
477 | int curidx; | ||
478 | |||
479 | /* | ||
480 | * First, grab all of the stats for the incoming packet. | ||
481 | * These get messed up if we get called due to a busy condition. | ||
482 | */ | ||
483 | bdp = fep->cur_rx; | ||
484 | |||
485 | /* clear RX status bits for napi*/ | ||
486 | if (fpi->use_napi) | ||
487 | FW(fecp, ievent, FEC_ENET_RXF | FEC_ENET_RXB); | ||
488 | |||
489 | while (((sc = CBDR_SC(bdp)) & BD_ENET_RX_EMPTY) == 0) { | ||
490 | |||
491 | curidx = bdp - fep->rx_bd_base; | ||
492 | |||
493 | /* | ||
494 | * Since we have allocated space to hold a complete frame, | ||
495 | * the last indicator should be set. | ||
496 | */ | ||
497 | if ((sc & BD_ENET_RX_LAST) == 0) | ||
498 | printk(KERN_WARNING DRV_MODULE_NAME | ||
499 | ": %s rcv is not +last\n", | ||
500 | dev->name); | ||
501 | |||
502 | /* | ||
503 | * Check for errors. | ||
504 | */ | ||
505 | if (sc & (BD_ENET_RX_LG | BD_ENET_RX_SH | BD_ENET_RX_CL | | ||
506 | BD_ENET_RX_NO | BD_ENET_RX_CR | BD_ENET_RX_OV)) { | ||
507 | fep->stats.rx_errors++; | ||
508 | /* Frame too long or too short. */ | ||
509 | if (sc & (BD_ENET_RX_LG | BD_ENET_RX_SH)) | ||
510 | fep->stats.rx_length_errors++; | ||
511 | /* Frame alignment */ | ||
512 | if (sc & (BD_ENET_RX_NO | BD_ENET_RX_CL)) | ||
513 | fep->stats.rx_frame_errors++; | ||
514 | /* CRC Error */ | ||
515 | if (sc & BD_ENET_RX_CR) | ||
516 | fep->stats.rx_crc_errors++; | ||
517 | /* FIFO overrun */ | ||
518 | if (sc & BD_ENET_RX_OV) | ||
519 | fep->stats.rx_crc_errors++; | ||
520 | |||
521 | skbn = fep->rx_skbuff[curidx]; | ||
522 | BUG_ON(skbn == NULL); | ||
523 | |||
524 | } else { | ||
525 | skb = fep->rx_skbuff[curidx]; | ||
526 | BUG_ON(skb == NULL); | ||
527 | |||
528 | /* | ||
529 | * Process the incoming frame. | ||
530 | */ | ||
531 | fep->stats.rx_packets++; | ||
532 | pkt_len = CBDR_DATLEN(bdp) - 4; /* remove CRC */ | ||
533 | fep->stats.rx_bytes += pkt_len + 4; | ||
534 | |||
535 | if (pkt_len <= fpi->rx_copybreak) { | ||
536 | /* +2 to make IP header L1 cache aligned */ | ||
537 | skbn = dev_alloc_skb(pkt_len + 2); | ||
538 | if (skbn != NULL) { | ||
539 | skb_reserve(skbn, 2); /* align IP header */ | ||
540 | skb_copy_from_linear_data(skb, | ||
541 | skbn->data, | ||
542 | pkt_len); | ||
543 | /* swap */ | ||
544 | skbt = skb; | ||
545 | skb = skbn; | ||
546 | skbn = skbt; | ||
547 | } | ||
548 | } else | ||
549 | skbn = dev_alloc_skb(ENET_RX_FRSIZE); | ||
550 | |||
551 | if (skbn != NULL) { | ||
552 | skb_put(skb, pkt_len); /* Make room */ | ||
553 | skb->protocol = eth_type_trans(skb, dev); | ||
554 | received++; | ||
555 | if (!fpi->use_napi) | ||
556 | netif_rx(skb); | ||
557 | else | ||
558 | netif_receive_skb(skb); | ||
559 | } else { | ||
560 | printk(KERN_WARNING DRV_MODULE_NAME | ||
561 | ": %s Memory squeeze, dropping packet.\n", | ||
562 | dev->name); | ||
563 | fep->stats.rx_dropped++; | ||
564 | skbn = skb; | ||
565 | } | ||
566 | } | ||
567 | |||
568 | fep->rx_skbuff[curidx] = skbn; | ||
569 | CBDW_BUFADDR(bdp, dma_map_single(NULL, skbn->data, | ||
570 | L1_CACHE_ALIGN(PKT_MAXBUF_SIZE), | ||
571 | DMA_FROM_DEVICE)); | ||
572 | CBDW_DATLEN(bdp, 0); | ||
573 | CBDW_SC(bdp, (sc & ~BD_ENET_RX_STATS) | BD_ENET_RX_EMPTY); | ||
574 | |||
575 | /* | ||
576 | * Update BD pointer to next entry. | ||
577 | */ | ||
578 | if ((sc & BD_ENET_RX_WRAP) == 0) | ||
579 | bdp++; | ||
580 | else | ||
581 | bdp = fep->rx_bd_base; | ||
582 | |||
583 | /* | ||
584 | * Doing this here will keep the FEC running while we process | ||
585 | * incoming frames. On a heavily loaded network, we should be | ||
586 | * able to keep up at the expense of system resources. | ||
587 | */ | ||
588 | FW(fecp, r_des_active, 0x01000000); | ||
589 | |||
590 | if (received >= budget) | ||
591 | break; | ||
592 | |||
593 | } | ||
594 | |||
595 | fep->cur_rx = bdp; | ||
596 | |||
597 | if (fpi->use_napi) { | ||
598 | if (received < budget) { | ||
599 | netif_rx_complete(dev, &fep->napi); | ||
600 | |||
601 | /* enable RX interrupt bits */ | ||
602 | FS(fecp, imask, FEC_ENET_RXF | FEC_ENET_RXB); | ||
603 | } | ||
604 | } | ||
605 | |||
606 | return received; | ||
607 | } | ||
608 | |||
609 | static void fec_enet_tx(struct net_device *dev) | ||
610 | { | ||
611 | struct fec_enet_private *fep = netdev_priv(dev); | ||
612 | cbd_t *bdp; | ||
613 | struct sk_buff *skb; | ||
614 | int dirtyidx, do_wake; | ||
615 | __u16 sc; | ||
616 | |||
617 | spin_lock(&fep->lock); | ||
618 | bdp = fep->dirty_tx; | ||
619 | |||
620 | do_wake = 0; | ||
621 | while (((sc = CBDR_SC(bdp)) & BD_ENET_TX_READY) == 0) { | ||
622 | |||
623 | dirtyidx = bdp - fep->tx_bd_base; | ||
624 | |||
625 | if (fep->tx_free == fep->tx_ring) | ||
626 | break; | ||
627 | |||
628 | skb = fep->tx_skbuff[dirtyidx]; | ||
629 | |||
630 | /* | ||
631 | * Check for errors. | ||
632 | */ | ||
633 | if (sc & (BD_ENET_TX_HB | BD_ENET_TX_LC | | ||
634 | BD_ENET_TX_RL | BD_ENET_TX_UN | BD_ENET_TX_CSL)) { | ||
635 | fep->stats.tx_errors++; | ||
636 | if (sc & BD_ENET_TX_HB) /* No heartbeat */ | ||
637 | fep->stats.tx_heartbeat_errors++; | ||
638 | if (sc & BD_ENET_TX_LC) /* Late collision */ | ||
639 | fep->stats.tx_window_errors++; | ||
640 | if (sc & BD_ENET_TX_RL) /* Retrans limit */ | ||
641 | fep->stats.tx_aborted_errors++; | ||
642 | if (sc & BD_ENET_TX_UN) /* Underrun */ | ||
643 | fep->stats.tx_fifo_errors++; | ||
644 | if (sc & BD_ENET_TX_CSL) /* Carrier lost */ | ||
645 | fep->stats.tx_carrier_errors++; | ||
646 | } else | ||
647 | fep->stats.tx_packets++; | ||
648 | |||
649 | if (sc & BD_ENET_TX_READY) | ||
650 | printk(KERN_WARNING DRV_MODULE_NAME | ||
651 | ": %s HEY! Enet xmit interrupt and TX_READY.\n", | ||
652 | dev->name); | ||
653 | |||
654 | /* | ||
655 | * Deferred means some collisions occurred during transmit, | ||
656 | * but we eventually sent the packet OK. | ||
657 | */ | ||
658 | if (sc & BD_ENET_TX_DEF) | ||
659 | fep->stats.collisions++; | ||
660 | |||
661 | /* | ||
662 | * Free the sk buffer associated with this last transmit. | ||
663 | */ | ||
664 | dev_kfree_skb_irq(skb); | ||
665 | fep->tx_skbuff[dirtyidx] = NULL; | ||
666 | |||
667 | /* | ||
668 | * Update pointer to next buffer descriptor to be transmitted. | ||
669 | */ | ||
670 | if ((sc & BD_ENET_TX_WRAP) == 0) | ||
671 | bdp++; | ||
672 | else | ||
673 | bdp = fep->tx_bd_base; | ||
674 | |||
675 | /* | ||
676 | * Since we have freed up a buffer, the ring is no longer | ||
677 | * full. | ||
678 | */ | ||
679 | if (!fep->tx_free++) | ||
680 | do_wake = 1; | ||
681 | } | ||
682 | |||
683 | fep->dirty_tx = bdp; | ||
684 | |||
685 | spin_unlock(&fep->lock); | ||
686 | |||
687 | if (do_wake && netif_queue_stopped(dev)) | ||
688 | netif_wake_queue(dev); | ||
689 | } | ||
690 | |||
691 | /* | ||
692 | * The interrupt handler. | ||
693 | * This is called from the MPC core interrupt. | ||
694 | */ | ||
695 | static irqreturn_t | ||
696 | fec_enet_interrupt(int irq, void *dev_id) | ||
697 | { | ||
698 | struct net_device *dev = dev_id; | ||
699 | struct fec_enet_private *fep; | ||
700 | const struct fec_platform_info *fpi; | ||
701 | fec_t *fecp; | ||
702 | __u32 int_events; | ||
703 | __u32 int_events_napi; | ||
704 | |||
705 | if (unlikely(dev == NULL)) | ||
706 | return IRQ_NONE; | ||
707 | |||
708 | fep = netdev_priv(dev); | ||
709 | fecp = fep->fecp; | ||
710 | fpi = fep->fpi; | ||
711 | |||
712 | /* | ||
713 | * Get the interrupt events that caused us to be here. | ||
714 | */ | ||
715 | while ((int_events = FR(fecp, ievent) & FR(fecp, imask)) != 0) { | ||
716 | |||
717 | if (!fpi->use_napi) | ||
718 | FW(fecp, ievent, int_events); | ||
719 | else { | ||
720 | int_events_napi = int_events & ~(FEC_ENET_RXF | FEC_ENET_RXB); | ||
721 | FW(fecp, ievent, int_events_napi); | ||
722 | } | ||
723 | |||
724 | if ((int_events & (FEC_ENET_HBERR | FEC_ENET_BABR | | ||
725 | FEC_ENET_BABT | FEC_ENET_EBERR)) != 0) | ||
726 | printk(KERN_WARNING DRV_MODULE_NAME | ||
727 | ": %s FEC ERROR(s) 0x%x\n", | ||
728 | dev->name, int_events); | ||
729 | |||
730 | if ((int_events & FEC_ENET_RXF) != 0) { | ||
731 | if (!fpi->use_napi) | ||
732 | fec_enet_rx_common(fep, dev, ~0); | ||
733 | else { | ||
734 | if (netif_rx_schedule_prep(dev, &fep->napi)) { | ||
735 | /* disable rx interrupts */ | ||
736 | FC(fecp, imask, FEC_ENET_RXF | FEC_ENET_RXB); | ||
737 | __netif_rx_schedule(dev, &fep->napi); | ||
738 | } else { | ||
739 | printk(KERN_ERR DRV_MODULE_NAME | ||
740 | ": %s driver bug! interrupt while in poll!\n", | ||
741 | dev->name); | ||
742 | FC(fecp, imask, FEC_ENET_RXF | FEC_ENET_RXB); | ||
743 | } | ||
744 | } | ||
745 | } | ||
746 | |||
747 | if ((int_events & FEC_ENET_TXF) != 0) | ||
748 | fec_enet_tx(dev); | ||
749 | } | ||
750 | |||
751 | return IRQ_HANDLED; | ||
752 | } | ||
753 | |||
754 | /* This interrupt occurs when the PHY detects a link change. */ | ||
755 | static irqreturn_t | ||
756 | fec_mii_link_interrupt(int irq, void *dev_id) | ||
757 | { | ||
758 | struct net_device *dev = dev_id; | ||
759 | struct fec_enet_private *fep; | ||
760 | const struct fec_platform_info *fpi; | ||
761 | |||
762 | if (unlikely(dev == NULL)) | ||
763 | return IRQ_NONE; | ||
764 | |||
765 | fep = netdev_priv(dev); | ||
766 | fpi = fep->fpi; | ||
767 | |||
768 | if (!fpi->use_mdio) | ||
769 | return IRQ_NONE; | ||
770 | |||
771 | /* | ||
772 | * Acknowledge the interrupt if possible. If we have not | ||
773 | * found the PHY yet we can't process or acknowledge the | ||
774 | * interrupt now. Instead we ignore this interrupt for now, | ||
775 | * which we can do since it is edge triggered. It will be | ||
776 | * acknowledged later by fec_enet_open(). | ||
777 | */ | ||
778 | if (!fep->phy) | ||
779 | return IRQ_NONE; | ||
780 | |||
781 | fec_mii_ack_int(dev); | ||
782 | fec_mii_link_status_change_check(dev, 0); | ||
783 | |||
784 | return IRQ_HANDLED; | ||
785 | } | ||
786 | |||
787 | |||
788 | /**********************************************************************************/ | ||
789 | |||
790 | static int fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) | ||
791 | { | ||
792 | struct fec_enet_private *fep = netdev_priv(dev); | ||
793 | fec_t *fecp = fep->fecp; | ||
794 | cbd_t *bdp; | ||
795 | int curidx; | ||
796 | unsigned long flags; | ||
797 | |||
798 | spin_lock_irqsave(&fep->tx_lock, flags); | ||
799 | |||
800 | /* | ||
801 | * Fill in a Tx ring entry | ||
802 | */ | ||
803 | bdp = fep->cur_tx; | ||
804 | |||
805 | if (!fep->tx_free || (CBDR_SC(bdp) & BD_ENET_TX_READY)) { | ||
806 | netif_stop_queue(dev); | ||
807 | spin_unlock_irqrestore(&fep->tx_lock, flags); | ||
808 | |||
809 | /* | ||
810 | * Ooops. All transmit buffers are full. Bail out. | ||
811 | * This should not happen, since the tx queue should be stopped. | ||
812 | */ | ||
813 | printk(KERN_WARNING DRV_MODULE_NAME | ||
814 | ": %s tx queue full!.\n", dev->name); | ||
815 | return 1; | ||
816 | } | ||
817 | |||
818 | curidx = bdp - fep->tx_bd_base; | ||
819 | /* | ||
820 | * Clear all of the status flags. | ||
821 | */ | ||
822 | CBDC_SC(bdp, BD_ENET_TX_STATS); | ||
823 | |||
824 | /* | ||
825 | * Save skb pointer. | ||
826 | */ | ||
827 | fep->tx_skbuff[curidx] = skb; | ||
828 | |||
829 | fep->stats.tx_bytes += skb->len; | ||
830 | |||
831 | /* | ||
832 | * Push the data cache so the CPM does not get stale memory data. | ||
833 | */ | ||
834 | CBDW_BUFADDR(bdp, dma_map_single(NULL, skb->data, | ||
835 | skb->len, DMA_TO_DEVICE)); | ||
836 | CBDW_DATLEN(bdp, skb->len); | ||
837 | |||
838 | dev->trans_start = jiffies; | ||
839 | |||
840 | /* | ||
841 | * If this was the last BD in the ring, start at the beginning again. | ||
842 | */ | ||
843 | if ((CBDR_SC(bdp) & BD_ENET_TX_WRAP) == 0) | ||
844 | fep->cur_tx++; | ||
845 | else | ||
846 | fep->cur_tx = fep->tx_bd_base; | ||
847 | |||
848 | if (!--fep->tx_free) | ||
849 | netif_stop_queue(dev); | ||
850 | |||
851 | /* | ||
852 | * Trigger transmission start | ||
853 | */ | ||
854 | CBDS_SC(bdp, BD_ENET_TX_READY | BD_ENET_TX_INTR | | ||
855 | BD_ENET_TX_LAST | BD_ENET_TX_TC); | ||
856 | FW(fecp, x_des_active, 0x01000000); | ||
857 | |||
858 | spin_unlock_irqrestore(&fep->tx_lock, flags); | ||
859 | |||
860 | return 0; | ||
861 | } | ||
862 | |||
863 | static void fec_timeout(struct net_device *dev) | ||
864 | { | ||
865 | struct fec_enet_private *fep = netdev_priv(dev); | ||
866 | |||
867 | fep->stats.tx_errors++; | ||
868 | |||
869 | if (fep->tx_free) | ||
870 | netif_wake_queue(dev); | ||
871 | |||
872 | /* check link status again */ | ||
873 | fec_mii_link_status_change_check(dev, 0); | ||
874 | } | ||
875 | |||
876 | static int fec_enet_open(struct net_device *dev) | ||
877 | { | ||
878 | struct fec_enet_private *fep = netdev_priv(dev); | ||
879 | const struct fec_platform_info *fpi = fep->fpi; | ||
880 | unsigned long flags; | ||
881 | |||
882 | napi_enable(&fep->napi); | ||
883 | |||
884 | /* Install our interrupt handler. */ | ||
885 | if (request_irq(fpi->fec_irq, fec_enet_interrupt, 0, "fec", dev) != 0) { | ||
886 | printk(KERN_ERR DRV_MODULE_NAME | ||
887 | ": %s Could not allocate FEC IRQ!", dev->name); | ||
888 | napi_disable(&fep->napi); | ||
889 | return -EINVAL; | ||
890 | } | ||
891 | |||
892 | /* Install our phy interrupt handler */ | ||
893 | if (fpi->phy_irq != -1 && | ||
894 | request_irq(fpi->phy_irq, fec_mii_link_interrupt, 0, "fec-phy", | ||
895 | dev) != 0) { | ||
896 | printk(KERN_ERR DRV_MODULE_NAME | ||
897 | ": %s Could not allocate PHY IRQ!", dev->name); | ||
898 | free_irq(fpi->fec_irq, dev); | ||
899 | napi_disable(&fep->napi); | ||
900 | return -EINVAL; | ||
901 | } | ||
902 | |||
903 | if (fpi->use_mdio) { | ||
904 | fec_mii_startup(dev); | ||
905 | netif_carrier_off(dev); | ||
906 | fec_mii_link_status_change_check(dev, 1); | ||
907 | } else { | ||
908 | spin_lock_irqsave(&fep->lock, flags); | ||
909 | fec_restart(dev, 1, 100); /* XXX this sucks */ | ||
910 | spin_unlock_irqrestore(&fep->lock, flags); | ||
911 | |||
912 | netif_carrier_on(dev); | ||
913 | netif_start_queue(dev); | ||
914 | } | ||
915 | return 0; | ||
916 | } | ||
917 | |||
918 | static int fec_enet_close(struct net_device *dev) | ||
919 | { | ||
920 | struct fec_enet_private *fep = netdev_priv(dev); | ||
921 | const struct fec_platform_info *fpi = fep->fpi; | ||
922 | unsigned long flags; | ||
923 | |||
924 | netif_stop_queue(dev); | ||
925 | napi_disable(&fep->napi); | ||
926 | netif_carrier_off(dev); | ||
927 | |||
928 | if (fpi->use_mdio) | ||
929 | fec_mii_shutdown(dev); | ||
930 | |||
931 | spin_lock_irqsave(&fep->lock, flags); | ||
932 | fec_stop(dev); | ||
933 | spin_unlock_irqrestore(&fep->lock, flags); | ||
934 | |||
935 | /* release any irqs */ | ||
936 | if (fpi->phy_irq != -1) | ||
937 | free_irq(fpi->phy_irq, dev); | ||
938 | free_irq(fpi->fec_irq, dev); | ||
939 | |||
940 | return 0; | ||
941 | } | ||
942 | |||
943 | static struct net_device_stats *fec_enet_get_stats(struct net_device *dev) | ||
944 | { | ||
945 | struct fec_enet_private *fep = netdev_priv(dev); | ||
946 | return &fep->stats; | ||
947 | } | ||
948 | |||
949 | static int fec_enet_poll(struct napi_struct *napi, int budget) | ||
950 | { | ||
951 | struct fec_enet_private *fep = container_of(napi, struct fec_enet_private, napi); | ||
952 | struct net_device *dev = fep->dev; | ||
953 | |||
954 | return fec_enet_rx_common(fep, dev, budget); | ||
955 | } | ||
956 | |||
957 | /*************************************************************************/ | ||
958 | |||
959 | static void fec_get_drvinfo(struct net_device *dev, | ||
960 | struct ethtool_drvinfo *info) | ||
961 | { | ||
962 | strcpy(info->driver, DRV_MODULE_NAME); | ||
963 | strcpy(info->version, DRV_MODULE_VERSION); | ||
964 | } | ||
965 | |||
966 | static int fec_get_regs_len(struct net_device *dev) | ||
967 | { | ||
968 | return sizeof(fec_t); | ||
969 | } | ||
970 | |||
971 | static void fec_get_regs(struct net_device *dev, struct ethtool_regs *regs, | ||
972 | void *p) | ||
973 | { | ||
974 | struct fec_enet_private *fep = netdev_priv(dev); | ||
975 | unsigned long flags; | ||
976 | |||
977 | if (regs->len < sizeof(fec_t)) | ||
978 | return; | ||
979 | |||
980 | regs->version = 0; | ||
981 | spin_lock_irqsave(&fep->lock, flags); | ||
982 | memcpy_fromio(p, fep->fecp, sizeof(fec_t)); | ||
983 | spin_unlock_irqrestore(&fep->lock, flags); | ||
984 | } | ||
985 | |||
986 | static int fec_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) | ||
987 | { | ||
988 | struct fec_enet_private *fep = netdev_priv(dev); | ||
989 | unsigned long flags; | ||
990 | int rc; | ||
991 | |||
992 | spin_lock_irqsave(&fep->lock, flags); | ||
993 | rc = mii_ethtool_gset(&fep->mii_if, cmd); | ||
994 | spin_unlock_irqrestore(&fep->lock, flags); | ||
995 | |||
996 | return rc; | ||
997 | } | ||
998 | |||
999 | static int fec_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) | ||
1000 | { | ||
1001 | struct fec_enet_private *fep = netdev_priv(dev); | ||
1002 | unsigned long flags; | ||
1003 | int rc; | ||
1004 | |||
1005 | spin_lock_irqsave(&fep->lock, flags); | ||
1006 | rc = mii_ethtool_sset(&fep->mii_if, cmd); | ||
1007 | spin_unlock_irqrestore(&fep->lock, flags); | ||
1008 | |||
1009 | return rc; | ||
1010 | } | ||
1011 | |||
1012 | static int fec_nway_reset(struct net_device *dev) | ||
1013 | { | ||
1014 | struct fec_enet_private *fep = netdev_priv(dev); | ||
1015 | return mii_nway_restart(&fep->mii_if); | ||
1016 | } | ||
1017 | |||
1018 | static __u32 fec_get_msglevel(struct net_device *dev) | ||
1019 | { | ||
1020 | struct fec_enet_private *fep = netdev_priv(dev); | ||
1021 | return fep->msg_enable; | ||
1022 | } | ||
1023 | |||
1024 | static void fec_set_msglevel(struct net_device *dev, __u32 value) | ||
1025 | { | ||
1026 | struct fec_enet_private *fep = netdev_priv(dev); | ||
1027 | fep->msg_enable = value; | ||
1028 | } | ||
1029 | |||
1030 | static const struct ethtool_ops fec_ethtool_ops = { | ||
1031 | .get_drvinfo = fec_get_drvinfo, | ||
1032 | .get_regs_len = fec_get_regs_len, | ||
1033 | .get_settings = fec_get_settings, | ||
1034 | .set_settings = fec_set_settings, | ||
1035 | .nway_reset = fec_nway_reset, | ||
1036 | .get_link = ethtool_op_get_link, | ||
1037 | .get_msglevel = fec_get_msglevel, | ||
1038 | .set_msglevel = fec_set_msglevel, | ||
1039 | .set_tx_csum = ethtool_op_set_tx_csum, /* local! */ | ||
1040 | .set_sg = ethtool_op_set_sg, | ||
1041 | .get_regs = fec_get_regs, | ||
1042 | }; | ||
1043 | |||
1044 | static int fec_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) | ||
1045 | { | ||
1046 | struct fec_enet_private *fep = netdev_priv(dev); | ||
1047 | struct mii_ioctl_data *mii = (struct mii_ioctl_data *)&rq->ifr_data; | ||
1048 | unsigned long flags; | ||
1049 | int rc; | ||
1050 | |||
1051 | if (!netif_running(dev)) | ||
1052 | return -EINVAL; | ||
1053 | |||
1054 | spin_lock_irqsave(&fep->lock, flags); | ||
1055 | rc = generic_mii_ioctl(&fep->mii_if, mii, cmd, NULL); | ||
1056 | spin_unlock_irqrestore(&fep->lock, flags); | ||
1057 | return rc; | ||
1058 | } | ||
1059 | |||
1060 | int fec_8xx_init_one(const struct fec_platform_info *fpi, | ||
1061 | struct net_device **devp) | ||
1062 | { | ||
1063 | immap_t *immap = (immap_t *) IMAP_ADDR; | ||
1064 | static int fec_8xx_version_printed = 0; | ||
1065 | struct net_device *dev = NULL; | ||
1066 | struct fec_enet_private *fep = NULL; | ||
1067 | fec_t *fecp = NULL; | ||
1068 | int i; | ||
1069 | int err = 0; | ||
1070 | int registered = 0; | ||
1071 | __u32 siel; | ||
1072 | |||
1073 | *devp = NULL; | ||
1074 | |||
1075 | switch (fpi->fec_no) { | ||
1076 | case 0: | ||
1077 | fecp = &((immap_t *) IMAP_ADDR)->im_cpm.cp_fec; | ||
1078 | break; | ||
1079 | #ifdef CONFIG_DUET | ||
1080 | case 1: | ||
1081 | fecp = &((immap_t *) IMAP_ADDR)->im_cpm.cp_fec2; | ||
1082 | break; | ||
1083 | #endif | ||
1084 | default: | ||
1085 | return -EINVAL; | ||
1086 | } | ||
1087 | |||
1088 | if (fec_8xx_version_printed++ == 0) | ||
1089 | printk(KERN_INFO "%s", version); | ||
1090 | |||
1091 | i = sizeof(*fep) + (sizeof(struct sk_buff **) * | ||
1092 | (fpi->rx_ring + fpi->tx_ring)); | ||
1093 | |||
1094 | dev = alloc_etherdev(i); | ||
1095 | if (!dev) { | ||
1096 | err = -ENOMEM; | ||
1097 | goto err; | ||
1098 | } | ||
1099 | |||
1100 | fep = netdev_priv(dev); | ||
1101 | fep->dev = dev; | ||
1102 | |||
1103 | /* partial reset of FEC */ | ||
1104 | fec_whack_reset(fecp); | ||
1105 | |||
1106 | /* point rx_skbuff, tx_skbuff */ | ||
1107 | fep->rx_skbuff = (struct sk_buff **)&fep[1]; | ||
1108 | fep->tx_skbuff = fep->rx_skbuff + fpi->rx_ring; | ||
1109 | |||
1110 | fep->fecp = fecp; | ||
1111 | fep->fpi = fpi; | ||
1112 | |||
1113 | /* init locks */ | ||
1114 | spin_lock_init(&fep->lock); | ||
1115 | spin_lock_init(&fep->tx_lock); | ||
1116 | |||
1117 | /* | ||
1118 | * Set the Ethernet address. | ||
1119 | */ | ||
1120 | for (i = 0; i < 6; i++) | ||
1121 | dev->dev_addr[i] = fpi->macaddr[i]; | ||
1122 | |||
1123 | fep->ring_base = dma_alloc_coherent(NULL, | ||
1124 | (fpi->tx_ring + fpi->rx_ring) * | ||
1125 | sizeof(cbd_t), &fep->ring_mem_addr, | ||
1126 | GFP_KERNEL); | ||
1127 | if (fep->ring_base == NULL) { | ||
1128 | printk(KERN_ERR DRV_MODULE_NAME | ||
1129 | ": %s dma alloc failed.\n", dev->name); | ||
1130 | err = -ENOMEM; | ||
1131 | goto err; | ||
1132 | } | ||
1133 | |||
1134 | /* | ||
1135 | * Set receive and transmit descriptor base. | ||
1136 | */ | ||
1137 | fep->rx_bd_base = fep->ring_base; | ||
1138 | fep->tx_bd_base = fep->rx_bd_base + fpi->rx_ring; | ||
1139 | |||
1140 | /* initialize ring size variables */ | ||
1141 | fep->tx_ring = fpi->tx_ring; | ||
1142 | fep->rx_ring = fpi->rx_ring; | ||
1143 | |||
1144 | /* SIU interrupt */ | ||
1145 | if (fpi->phy_irq != -1 && | ||
1146 | (fpi->phy_irq >= SIU_IRQ0 && fpi->phy_irq < SIU_LEVEL7)) { | ||
1147 | |||
1148 | siel = in_be32(&immap->im_siu_conf.sc_siel); | ||
1149 | if ((fpi->phy_irq & 1) == 0) | ||
1150 | siel |= (0x80000000 >> fpi->phy_irq); | ||
1151 | else | ||
1152 | siel &= ~(0x80000000 >> (fpi->phy_irq & ~1)); | ||
1153 | out_be32(&immap->im_siu_conf.sc_siel, siel); | ||
1154 | } | ||
1155 | |||
1156 | /* | ||
1157 | * The FEC Ethernet specific entries in the device structure. | ||
1158 | */ | ||
1159 | dev->open = fec_enet_open; | ||
1160 | dev->hard_start_xmit = fec_enet_start_xmit; | ||
1161 | dev->tx_timeout = fec_timeout; | ||
1162 | dev->watchdog_timeo = TX_TIMEOUT; | ||
1163 | dev->stop = fec_enet_close; | ||
1164 | dev->get_stats = fec_enet_get_stats; | ||
1165 | dev->set_multicast_list = fec_set_multicast_list; | ||
1166 | dev->set_mac_address = fec_set_mac_address; | ||
1167 | netif_napi_add(dev, &fec->napi, | ||
1168 | fec_enet_poll, fpi->napi_weight); | ||
1169 | |||
1170 | dev->ethtool_ops = &fec_ethtool_ops; | ||
1171 | dev->do_ioctl = fec_ioctl; | ||
1172 | |||
1173 | fep->fec_phy_speed = | ||
1174 | ((((fpi->sys_clk + 4999999) / 2500000) / 2) & 0x3F) << 1; | ||
1175 | |||
1176 | init_timer(&fep->phy_timer_list); | ||
1177 | |||
1178 | /* partial reset of FEC so that only MII works */ | ||
1179 | FW(fecp, mii_speed, fep->fec_phy_speed); | ||
1180 | FW(fecp, ievent, 0xffc0); | ||
1181 | FW(fecp, ivec, (fpi->fec_irq / 2) << 29); | ||
1182 | FW(fecp, imask, 0); | ||
1183 | FW(fecp, r_cntrl, FEC_RCNTRL_MII_MODE); /* MII enable */ | ||
1184 | FW(fecp, ecntrl, FEC_ECNTRL_PINMUX | FEC_ECNTRL_ETHER_EN); | ||
1185 | |||
1186 | netif_carrier_off(dev); | ||
1187 | |||
1188 | err = register_netdev(dev); | ||
1189 | if (err != 0) | ||
1190 | goto err; | ||
1191 | registered = 1; | ||
1192 | |||
1193 | if (fpi->use_mdio) { | ||
1194 | fep->mii_if.dev = dev; | ||
1195 | fep->mii_if.mdio_read = fec_mii_read; | ||
1196 | fep->mii_if.mdio_write = fec_mii_write; | ||
1197 | fep->mii_if.phy_id_mask = 0x1f; | ||
1198 | fep->mii_if.reg_num_mask = 0x1f; | ||
1199 | fep->mii_if.phy_id = fec_mii_phy_id_detect(dev); | ||
1200 | } | ||
1201 | |||
1202 | *devp = dev; | ||
1203 | |||
1204 | return 0; | ||
1205 | |||
1206 | err: | ||
1207 | if (dev != NULL) { | ||
1208 | if (fecp != NULL) | ||
1209 | fec_whack_reset(fecp); | ||
1210 | |||
1211 | if (registered) | ||
1212 | unregister_netdev(dev); | ||
1213 | |||
1214 | if (fep != NULL) { | ||
1215 | if (fep->ring_base) | ||
1216 | dma_free_coherent(NULL, | ||
1217 | (fpi->tx_ring + | ||
1218 | fpi->rx_ring) * | ||
1219 | sizeof(cbd_t), fep->ring_base, | ||
1220 | fep->ring_mem_addr); | ||
1221 | } | ||
1222 | free_netdev(dev); | ||
1223 | } | ||
1224 | return err; | ||
1225 | } | ||
1226 | |||
1227 | int fec_8xx_cleanup_one(struct net_device *dev) | ||
1228 | { | ||
1229 | struct fec_enet_private *fep = netdev_priv(dev); | ||
1230 | fec_t *fecp = fep->fecp; | ||
1231 | const struct fec_platform_info *fpi = fep->fpi; | ||
1232 | |||
1233 | fec_whack_reset(fecp); | ||
1234 | |||
1235 | unregister_netdev(dev); | ||
1236 | |||
1237 | dma_free_coherent(NULL, (fpi->tx_ring + fpi->rx_ring) * sizeof(cbd_t), | ||
1238 | fep->ring_base, fep->ring_mem_addr); | ||
1239 | |||
1240 | free_netdev(dev); | ||
1241 | |||
1242 | return 0; | ||
1243 | } | ||
1244 | |||
1245 | /**************************************************************************************/ | ||
1246 | /**************************************************************************************/ | ||
1247 | /**************************************************************************************/ | ||
1248 | |||
1249 | static int __init fec_8xx_init(void) | ||
1250 | { | ||
1251 | return fec_8xx_platform_init(); | ||
1252 | } | ||
1253 | |||
1254 | static void __exit fec_8xx_cleanup(void) | ||
1255 | { | ||
1256 | fec_8xx_platform_cleanup(); | ||
1257 | } | ||
1258 | |||
1259 | /**************************************************************************************/ | ||
1260 | /**************************************************************************************/ | ||
1261 | /**************************************************************************************/ | ||
1262 | |||
1263 | module_init(fec_8xx_init); | ||
1264 | module_exit(fec_8xx_cleanup); | ||
diff --git a/drivers/net/fec_8xx/fec_mii.c b/drivers/net/fec_8xx/fec_mii.c deleted file mode 100644 index 3b6ca29d31f2..000000000000 --- a/drivers/net/fec_8xx/fec_mii.c +++ /dev/null | |||
@@ -1,418 +0,0 @@ | |||
1 | /* | ||
2 | * Fast Ethernet Controller (FEC) driver for Motorola MPC8xx. | ||
3 | * | ||
4 | * Copyright (c) 2003 Intracom S.A. | ||
5 | * by Pantelis Antoniou <panto@intracom.gr> | ||
6 | * | ||
7 | * Heavily based on original FEC driver by Dan Malek <dan@embeddededge.com> | ||
8 | * and modifications by Joakim Tjernlund <joakim.tjernlund@lumentis.se> | ||
9 | * | ||
10 | * Released under the GPL | ||
11 | */ | ||
12 | |||
13 | #include <linux/module.h> | ||
14 | #include <linux/types.h> | ||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/string.h> | ||
17 | #include <linux/ptrace.h> | ||
18 | #include <linux/errno.h> | ||
19 | #include <linux/ioport.h> | ||
20 | #include <linux/slab.h> | ||
21 | #include <linux/interrupt.h> | ||
22 | #include <linux/init.h> | ||
23 | #include <linux/delay.h> | ||
24 | #include <linux/netdevice.h> | ||
25 | #include <linux/etherdevice.h> | ||
26 | #include <linux/skbuff.h> | ||
27 | #include <linux/spinlock.h> | ||
28 | #include <linux/mii.h> | ||
29 | #include <linux/ethtool.h> | ||
30 | #include <linux/bitops.h> | ||
31 | |||
32 | #include <asm/8xx_immap.h> | ||
33 | #include <asm/pgtable.h> | ||
34 | #include <asm/mpc8xx.h> | ||
35 | #include <asm/irq.h> | ||
36 | #include <asm/uaccess.h> | ||
37 | #include <asm/cpm1.h> | ||
38 | |||
39 | /*************************************************/ | ||
40 | |||
41 | #include "fec_8xx.h" | ||
42 | |||
43 | /*************************************************/ | ||
44 | |||
45 | /* Make MII read/write commands for the FEC. | ||
46 | */ | ||
47 | #define mk_mii_read(REG) (0x60020000 | ((REG & 0x1f) << 18)) | ||
48 | #define mk_mii_write(REG, VAL) (0x50020000 | ((REG & 0x1f) << 18) | (VAL & 0xffff)) | ||
49 | #define mk_mii_end 0 | ||
50 | |||
51 | /*************************************************/ | ||
52 | |||
53 | /* XXX both FECs use the MII interface of FEC1 */ | ||
54 | static DEFINE_SPINLOCK(fec_mii_lock); | ||
55 | |||
56 | #define FEC_MII_LOOPS 10000 | ||
57 | |||
58 | int fec_mii_read(struct net_device *dev, int phy_id, int location) | ||
59 | { | ||
60 | struct fec_enet_private *fep = netdev_priv(dev); | ||
61 | fec_t *fecp; | ||
62 | int i, ret = -1; | ||
63 | unsigned long flags; | ||
64 | |||
65 | /* XXX MII interface is only connected to FEC1 */ | ||
66 | fecp = &((immap_t *) IMAP_ADDR)->im_cpm.cp_fec; | ||
67 | |||
68 | spin_lock_irqsave(&fec_mii_lock, flags); | ||
69 | |||
70 | if ((FR(fecp, r_cntrl) & FEC_RCNTRL_MII_MODE) == 0) { | ||
71 | FS(fecp, r_cntrl, FEC_RCNTRL_MII_MODE); /* MII enable */ | ||
72 | FS(fecp, ecntrl, FEC_ECNTRL_PINMUX | FEC_ECNTRL_ETHER_EN); | ||
73 | FW(fecp, ievent, FEC_ENET_MII); | ||
74 | } | ||
75 | |||
76 | /* Add PHY address to register command. */ | ||
77 | FW(fecp, mii_speed, fep->fec_phy_speed); | ||
78 | FW(fecp, mii_data, (phy_id << 23) | mk_mii_read(location)); | ||
79 | |||
80 | for (i = 0; i < FEC_MII_LOOPS; i++) | ||
81 | if ((FR(fecp, ievent) & FEC_ENET_MII) != 0) | ||
82 | break; | ||
83 | |||
84 | if (i < FEC_MII_LOOPS) { | ||
85 | FW(fecp, ievent, FEC_ENET_MII); | ||
86 | ret = FR(fecp, mii_data) & 0xffff; | ||
87 | } | ||
88 | |||
89 | spin_unlock_irqrestore(&fec_mii_lock, flags); | ||
90 | |||
91 | return ret; | ||
92 | } | ||
93 | |||
94 | void fec_mii_write(struct net_device *dev, int phy_id, int location, int value) | ||
95 | { | ||
96 | struct fec_enet_private *fep = netdev_priv(dev); | ||
97 | fec_t *fecp; | ||
98 | unsigned long flags; | ||
99 | int i; | ||
100 | |||
101 | /* XXX MII interface is only connected to FEC1 */ | ||
102 | fecp = &((immap_t *) IMAP_ADDR)->im_cpm.cp_fec; | ||
103 | |||
104 | spin_lock_irqsave(&fec_mii_lock, flags); | ||
105 | |||
106 | if ((FR(fecp, r_cntrl) & FEC_RCNTRL_MII_MODE) == 0) { | ||
107 | FS(fecp, r_cntrl, FEC_RCNTRL_MII_MODE); /* MII enable */ | ||
108 | FS(fecp, ecntrl, FEC_ECNTRL_PINMUX | FEC_ECNTRL_ETHER_EN); | ||
109 | FW(fecp, ievent, FEC_ENET_MII); | ||
110 | } | ||
111 | |||
112 | /* Add PHY address to register command. */ | ||
113 | FW(fecp, mii_speed, fep->fec_phy_speed); /* always adapt mii speed */ | ||
114 | FW(fecp, mii_data, (phy_id << 23) | mk_mii_write(location, value)); | ||
115 | |||
116 | for (i = 0; i < FEC_MII_LOOPS; i++) | ||
117 | if ((FR(fecp, ievent) & FEC_ENET_MII) != 0) | ||
118 | break; | ||
119 | |||
120 | if (i < FEC_MII_LOOPS) | ||
121 | FW(fecp, ievent, FEC_ENET_MII); | ||
122 | |||
123 | spin_unlock_irqrestore(&fec_mii_lock, flags); | ||
124 | } | ||
125 | |||
126 | /*************************************************/ | ||
127 | |||
128 | #ifdef CONFIG_FEC_8XX_GENERIC_PHY | ||
129 | |||
130 | /* | ||
131 | * Generic PHY support. | ||
132 | * Should work for all PHYs, but link change is detected by polling | ||
133 | */ | ||
134 | |||
135 | static void generic_timer_callback(unsigned long data) | ||
136 | { | ||
137 | struct net_device *dev = (struct net_device *)data; | ||
138 | struct fec_enet_private *fep = netdev_priv(dev); | ||
139 | |||
140 | fep->phy_timer_list.expires = jiffies + HZ / 2; | ||
141 | |||
142 | add_timer(&fep->phy_timer_list); | ||
143 | |||
144 | fec_mii_link_status_change_check(dev, 0); | ||
145 | } | ||
146 | |||
147 | static void generic_startup(struct net_device *dev) | ||
148 | { | ||
149 | struct fec_enet_private *fep = netdev_priv(dev); | ||
150 | |||
151 | fep->phy_timer_list.expires = jiffies + HZ / 2; /* every 500ms */ | ||
152 | fep->phy_timer_list.data = (unsigned long)dev; | ||
153 | fep->phy_timer_list.function = generic_timer_callback; | ||
154 | add_timer(&fep->phy_timer_list); | ||
155 | } | ||
156 | |||
157 | static void generic_shutdown(struct net_device *dev) | ||
158 | { | ||
159 | struct fec_enet_private *fep = netdev_priv(dev); | ||
160 | |||
161 | del_timer_sync(&fep->phy_timer_list); | ||
162 | } | ||
163 | |||
164 | #endif | ||
165 | |||
166 | #ifdef CONFIG_FEC_8XX_DM9161_PHY | ||
167 | |||
168 | /* ------------------------------------------------------------------------- */ | ||
169 | /* The Davicom DM9161 is used on the NETTA board */ | ||
170 | |||
171 | /* register definitions */ | ||
172 | |||
173 | #define MII_DM9161_ACR 16 /* Aux. Config Register */ | ||
174 | #define MII_DM9161_ACSR 17 /* Aux. Config/Status Register */ | ||
175 | #define MII_DM9161_10TCSR 18 /* 10BaseT Config/Status Reg. */ | ||
176 | #define MII_DM9161_INTR 21 /* Interrupt Register */ | ||
177 | #define MII_DM9161_RECR 22 /* Receive Error Counter Reg. */ | ||
178 | #define MII_DM9161_DISCR 23 /* Disconnect Counter Register */ | ||
179 | |||
180 | static void dm9161_startup(struct net_device *dev) | ||
181 | { | ||
182 | struct fec_enet_private *fep = netdev_priv(dev); | ||
183 | |||
184 | fec_mii_write(dev, fep->mii_if.phy_id, MII_DM9161_INTR, 0x0000); | ||
185 | } | ||
186 | |||
187 | static void dm9161_ack_int(struct net_device *dev) | ||
188 | { | ||
189 | struct fec_enet_private *fep = netdev_priv(dev); | ||
190 | |||
191 | fec_mii_read(dev, fep->mii_if.phy_id, MII_DM9161_INTR); | ||
192 | } | ||
193 | |||
194 | static void dm9161_shutdown(struct net_device *dev) | ||
195 | { | ||
196 | struct fec_enet_private *fep = netdev_priv(dev); | ||
197 | |||
198 | fec_mii_write(dev, fep->mii_if.phy_id, MII_DM9161_INTR, 0x0f00); | ||
199 | } | ||
200 | |||
201 | #endif | ||
202 | |||
203 | #ifdef CONFIG_FEC_8XX_LXT971_PHY | ||
204 | |||
205 | /* Support for LXT971/972 PHY */ | ||
206 | |||
207 | #define MII_LXT971_PCR 16 /* Port Control Register */ | ||
208 | #define MII_LXT971_SR2 17 /* Status Register 2 */ | ||
209 | #define MII_LXT971_IER 18 /* Interrupt Enable Register */ | ||
210 | #define MII_LXT971_ISR 19 /* Interrupt Status Register */ | ||
211 | #define MII_LXT971_LCR 20 /* LED Control Register */ | ||
212 | #define MII_LXT971_TCR 30 /* Transmit Control Register */ | ||
213 | |||
214 | static void lxt971_startup(struct net_device *dev) | ||
215 | { | ||
216 | struct fec_enet_private *fep = netdev_priv(dev); | ||
217 | |||
218 | fec_mii_write(dev, fep->mii_if.phy_id, MII_LXT971_IER, 0x00F2); | ||
219 | } | ||
220 | |||
221 | static void lxt971_ack_int(struct net_device *dev) | ||
222 | { | ||
223 | struct fec_enet_private *fep = netdev_priv(dev); | ||
224 | |||
225 | fec_mii_read(dev, fep->mii_if.phy_id, MII_LXT971_ISR); | ||
226 | } | ||
227 | |||
228 | static void lxt971_shutdown(struct net_device *dev) | ||
229 | { | ||
230 | struct fec_enet_private *fep = netdev_priv(dev); | ||
231 | |||
232 | fec_mii_write(dev, fep->mii_if.phy_id, MII_LXT971_IER, 0x0000); | ||
233 | } | ||
234 | #endif | ||
235 | |||
236 | /**********************************************************************************/ | ||
237 | |||
238 | static const struct phy_info phy_info[] = { | ||
239 | #ifdef CONFIG_FEC_8XX_DM9161_PHY | ||
240 | { | ||
241 | .id = 0x00181b88, | ||
242 | .name = "DM9161", | ||
243 | .startup = dm9161_startup, | ||
244 | .ack_int = dm9161_ack_int, | ||
245 | .shutdown = dm9161_shutdown, | ||
246 | }, | ||
247 | #endif | ||
248 | #ifdef CONFIG_FEC_8XX_LXT971_PHY | ||
249 | { | ||
250 | .id = 0x0001378e, | ||
251 | .name = "LXT971/972", | ||
252 | .startup = lxt971_startup, | ||
253 | .ack_int = lxt971_ack_int, | ||
254 | .shutdown = lxt971_shutdown, | ||
255 | }, | ||
256 | #endif | ||
257 | #ifdef CONFIG_FEC_8XX_GENERIC_PHY | ||
258 | { | ||
259 | .id = 0, | ||
260 | .name = "GENERIC", | ||
261 | .startup = generic_startup, | ||
262 | .shutdown = generic_shutdown, | ||
263 | }, | ||
264 | #endif | ||
265 | }; | ||
266 | |||
267 | /**********************************************************************************/ | ||
268 | |||
269 | int fec_mii_phy_id_detect(struct net_device *dev) | ||
270 | { | ||
271 | struct fec_enet_private *fep = netdev_priv(dev); | ||
272 | const struct fec_platform_info *fpi = fep->fpi; | ||
273 | int i, r, start, end, phytype, physubtype; | ||
274 | const struct phy_info *phy; | ||
275 | int phy_hwid, phy_id; | ||
276 | |||
277 | /* if no MDIO */ | ||
278 | if (fpi->use_mdio == 0) | ||
279 | return -1; | ||
280 | |||
281 | phy_hwid = -1; | ||
282 | fep->phy = NULL; | ||
283 | |||
284 | /* auto-detect? */ | ||
285 | if (fpi->phy_addr == -1) { | ||
286 | start = 0; | ||
287 | end = 32; | ||
288 | } else { /* direct */ | ||
289 | start = fpi->phy_addr; | ||
290 | end = start + 1; | ||
291 | } | ||
292 | |||
293 | for (phy_id = start; phy_id < end; phy_id++) { | ||
294 | r = fec_mii_read(dev, phy_id, MII_PHYSID1); | ||
295 | if (r == -1 || (phytype = (r & 0xffff)) == 0xffff) | ||
296 | continue; | ||
297 | r = fec_mii_read(dev, phy_id, MII_PHYSID2); | ||
298 | if (r == -1 || (physubtype = (r & 0xffff)) == 0xffff) | ||
299 | continue; | ||
300 | phy_hwid = (phytype << 16) | physubtype; | ||
301 | if (phy_hwid != -1) | ||
302 | break; | ||
303 | } | ||
304 | |||
305 | if (phy_hwid == -1) { | ||
306 | printk(KERN_ERR DRV_MODULE_NAME | ||
307 | ": %s No PHY detected!\n", dev->name); | ||
308 | return -1; | ||
309 | } | ||
310 | |||
311 | for (i = 0, phy = phy_info; i < ARRAY_SIZE(phy_info); i++, phy++) | ||
312 | if (phy->id == (phy_hwid >> 4) || phy->id == 0) | ||
313 | break; | ||
314 | |||
315 | if (i >= ARRAY_SIZE(phy_info)) { | ||
316 | printk(KERN_ERR DRV_MODULE_NAME | ||
317 | ": %s PHY id 0x%08x is not supported!\n", | ||
318 | dev->name, phy_hwid); | ||
319 | return -1; | ||
320 | } | ||
321 | |||
322 | fep->phy = phy; | ||
323 | |||
324 | printk(KERN_INFO DRV_MODULE_NAME | ||
325 | ": %s Phy @ 0x%x, type %s (0x%08x)\n", | ||
326 | dev->name, phy_id, fep->phy->name, phy_hwid); | ||
327 | |||
328 | return phy_id; | ||
329 | } | ||
330 | |||
331 | void fec_mii_startup(struct net_device *dev) | ||
332 | { | ||
333 | struct fec_enet_private *fep = netdev_priv(dev); | ||
334 | const struct fec_platform_info *fpi = fep->fpi; | ||
335 | |||
336 | if (!fpi->use_mdio || fep->phy == NULL) | ||
337 | return; | ||
338 | |||
339 | if (fep->phy->startup == NULL) | ||
340 | return; | ||
341 | |||
342 | (*fep->phy->startup) (dev); | ||
343 | } | ||
344 | |||
345 | void fec_mii_shutdown(struct net_device *dev) | ||
346 | { | ||
347 | struct fec_enet_private *fep = netdev_priv(dev); | ||
348 | const struct fec_platform_info *fpi = fep->fpi; | ||
349 | |||
350 | if (!fpi->use_mdio || fep->phy == NULL) | ||
351 | return; | ||
352 | |||
353 | if (fep->phy->shutdown == NULL) | ||
354 | return; | ||
355 | |||
356 | (*fep->phy->shutdown) (dev); | ||
357 | } | ||
358 | |||
359 | void fec_mii_ack_int(struct net_device *dev) | ||
360 | { | ||
361 | struct fec_enet_private *fep = netdev_priv(dev); | ||
362 | const struct fec_platform_info *fpi = fep->fpi; | ||
363 | |||
364 | if (!fpi->use_mdio || fep->phy == NULL) | ||
365 | return; | ||
366 | |||
367 | if (fep->phy->ack_int == NULL) | ||
368 | return; | ||
369 | |||
370 | (*fep->phy->ack_int) (dev); | ||
371 | } | ||
372 | |||
373 | /* helper function */ | ||
374 | static int mii_negotiated(struct mii_if_info *mii) | ||
375 | { | ||
376 | int advert, lpa, val; | ||
377 | |||
378 | if (!mii_link_ok(mii)) | ||
379 | return 0; | ||
380 | |||
381 | val = (*mii->mdio_read) (mii->dev, mii->phy_id, MII_BMSR); | ||
382 | if ((val & BMSR_ANEGCOMPLETE) == 0) | ||
383 | return 0; | ||
384 | |||
385 | advert = (*mii->mdio_read) (mii->dev, mii->phy_id, MII_ADVERTISE); | ||
386 | lpa = (*mii->mdio_read) (mii->dev, mii->phy_id, MII_LPA); | ||
387 | |||
388 | return mii_nway_result(advert & lpa); | ||
389 | } | ||
390 | |||
391 | void fec_mii_link_status_change_check(struct net_device *dev, int init_media) | ||
392 | { | ||
393 | struct fec_enet_private *fep = netdev_priv(dev); | ||
394 | unsigned int media; | ||
395 | unsigned long flags; | ||
396 | |||
397 | if (mii_check_media(&fep->mii_if, netif_msg_link(fep), init_media) == 0) | ||
398 | return; | ||
399 | |||
400 | media = mii_negotiated(&fep->mii_if); | ||
401 | |||
402 | if (netif_carrier_ok(dev)) { | ||
403 | spin_lock_irqsave(&fep->lock, flags); | ||
404 | fec_restart(dev, !!(media & ADVERTISE_FULL), | ||
405 | (media & (ADVERTISE_100FULL | ADVERTISE_100HALF)) ? | ||
406 | 100 : 10); | ||
407 | spin_unlock_irqrestore(&fep->lock, flags); | ||
408 | |||
409 | netif_start_queue(dev); | ||
410 | } else { | ||
411 | netif_stop_queue(dev); | ||
412 | |||
413 | spin_lock_irqsave(&fep->lock, flags); | ||
414 | fec_stop(dev); | ||
415 | spin_unlock_irqrestore(&fep->lock, flags); | ||
416 | |||
417 | } | ||
418 | } | ||
diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c index a5baaf59ff66..352574a3f056 100644 --- a/drivers/net/fs_enet/fs_enet-main.c +++ b/drivers/net/fs_enet/fs_enet-main.c | |||
@@ -43,7 +43,7 @@ | |||
43 | #include <asm/uaccess.h> | 43 | #include <asm/uaccess.h> |
44 | 44 | ||
45 | #ifdef CONFIG_PPC_CPM_NEW_BINDING | 45 | #ifdef CONFIG_PPC_CPM_NEW_BINDING |
46 | #include <asm/of_platform.h> | 46 | #include <linux/of_platform.h> |
47 | #endif | 47 | #endif |
48 | 48 | ||
49 | #include "fs_enet.h" | 49 | #include "fs_enet.h" |
diff --git a/drivers/net/fs_enet/mac-scc.c b/drivers/net/fs_enet/mac-scc.c index d7ca31945c82..e3557eca7b6d 100644 --- a/drivers/net/fs_enet/mac-scc.c +++ b/drivers/net/fs_enet/mac-scc.c | |||
@@ -44,7 +44,7 @@ | |||
44 | #endif | 44 | #endif |
45 | 45 | ||
46 | #ifdef CONFIG_PPC_CPM_NEW_BINDING | 46 | #ifdef CONFIG_PPC_CPM_NEW_BINDING |
47 | #include <asm/of_platform.h> | 47 | #include <linux/of_platform.h> |
48 | #endif | 48 | #endif |
49 | 49 | ||
50 | #include "fs_enet.h" | 50 | #include "fs_enet.h" |
diff --git a/drivers/net/fs_enet/mii-fec.c b/drivers/net/fs_enet/mii-fec.c index f0014cfbb275..8f6a43b0e0ff 100644 --- a/drivers/net/fs_enet/mii-fec.c +++ b/drivers/net/fs_enet/mii-fec.c | |||
@@ -37,7 +37,7 @@ | |||
37 | #include <asm/uaccess.h> | 37 | #include <asm/uaccess.h> |
38 | 38 | ||
39 | #ifdef CONFIG_PPC_CPM_NEW_BINDING | 39 | #ifdef CONFIG_PPC_CPM_NEW_BINDING |
40 | #include <asm/of_platform.h> | 40 | #include <linux/of_platform.h> |
41 | #endif | 41 | #endif |
42 | 42 | ||
43 | #include "fs_enet.h" | 43 | #include "fs_enet.h" |
diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c index babc79ad490b..61af02b4c9d8 100644 --- a/drivers/net/ibm_newemac/core.c +++ b/drivers/net/ibm_newemac/core.c | |||
@@ -363,25 +363,31 @@ static int emac_reset(struct emac_instance *dev) | |||
363 | 363 | ||
364 | static void emac_hash_mc(struct emac_instance *dev) | 364 | static void emac_hash_mc(struct emac_instance *dev) |
365 | { | 365 | { |
366 | struct emac_regs __iomem *p = dev->emacp; | 366 | const int regs = EMAC_XAHT_REGS(dev); |
367 | u16 gaht[4] = { 0 }; | 367 | u32 *gaht_base = emac_gaht_base(dev); |
368 | u32 gaht_temp[regs]; | ||
368 | struct dev_mc_list *dmi; | 369 | struct dev_mc_list *dmi; |
370 | int i; | ||
369 | 371 | ||
370 | DBG(dev, "hash_mc %d" NL, dev->ndev->mc_count); | 372 | DBG(dev, "hash_mc %d" NL, dev->ndev->mc_count); |
371 | 373 | ||
374 | memset(gaht_temp, 0, sizeof (gaht_temp)); | ||
375 | |||
372 | for (dmi = dev->ndev->mc_list; dmi; dmi = dmi->next) { | 376 | for (dmi = dev->ndev->mc_list; dmi; dmi = dmi->next) { |
373 | int bit; | 377 | int slot, reg, mask; |
374 | DBG2(dev, "mc %02x:%02x:%02x:%02x:%02x:%02x" NL, | 378 | DBG2(dev, "mc %02x:%02x:%02x:%02x:%02x:%02x" NL, |
375 | dmi->dmi_addr[0], dmi->dmi_addr[1], dmi->dmi_addr[2], | 379 | dmi->dmi_addr[0], dmi->dmi_addr[1], dmi->dmi_addr[2], |
376 | dmi->dmi_addr[3], dmi->dmi_addr[4], dmi->dmi_addr[5]); | 380 | dmi->dmi_addr[3], dmi->dmi_addr[4], dmi->dmi_addr[5]); |
377 | 381 | ||
378 | bit = 63 - (ether_crc(ETH_ALEN, dmi->dmi_addr) >> 26); | 382 | slot = EMAC_XAHT_CRC_TO_SLOT(dev, ether_crc(ETH_ALEN, dmi->dmi_addr)); |
379 | gaht[bit >> 4] |= 0x8000 >> (bit & 0x0f); | 383 | reg = EMAC_XAHT_SLOT_TO_REG(dev, slot); |
384 | mask = EMAC_XAHT_SLOT_TO_MASK(dev, slot); | ||
385 | |||
386 | gaht_temp[reg] |= mask; | ||
380 | } | 387 | } |
381 | out_be32(&p->gaht1, gaht[0]); | 388 | |
382 | out_be32(&p->gaht2, gaht[1]); | 389 | for (i = 0; i < regs; i++) |
383 | out_be32(&p->gaht3, gaht[2]); | 390 | out_be32(gaht_base + i, gaht_temp[i]); |
384 | out_be32(&p->gaht4, gaht[3]); | ||
385 | } | 391 | } |
386 | 392 | ||
387 | static inline u32 emac_iff2rmr(struct net_device *ndev) | 393 | static inline u32 emac_iff2rmr(struct net_device *ndev) |
@@ -398,7 +404,8 @@ static inline u32 emac_iff2rmr(struct net_device *ndev) | |||
398 | 404 | ||
399 | if (ndev->flags & IFF_PROMISC) | 405 | if (ndev->flags & IFF_PROMISC) |
400 | r |= EMAC_RMR_PME; | 406 | r |= EMAC_RMR_PME; |
401 | else if (ndev->flags & IFF_ALLMULTI || ndev->mc_count > 32) | 407 | else if (ndev->flags & IFF_ALLMULTI || |
408 | (ndev->mc_count > EMAC_XAHT_SLOTS(dev))) | ||
402 | r |= EMAC_RMR_PMME; | 409 | r |= EMAC_RMR_PMME; |
403 | else if (ndev->mc_count > 0) | 410 | else if (ndev->mc_count > 0) |
404 | r |= EMAC_RMR_MAE; | 411 | r |= EMAC_RMR_MAE; |
@@ -542,7 +549,7 @@ static int emac_configure(struct emac_instance *dev) | |||
542 | /* Put some arbitrary OUI, Manuf & Rev IDs so we can | 549 | /* Put some arbitrary OUI, Manuf & Rev IDs so we can |
543 | * identify this GPCS PHY later. | 550 | * identify this GPCS PHY later. |
544 | */ | 551 | */ |
545 | out_be32(&p->ipcr, 0xdeadbeef); | 552 | out_be32(&p->u1.emac4.ipcr, 0xdeadbeef); |
546 | } else | 553 | } else |
547 | mr1 |= EMAC_MR1_MF_1000; | 554 | mr1 |= EMAC_MR1_MF_1000; |
548 | 555 | ||
@@ -2021,10 +2028,10 @@ static int emac_get_regs_len(struct emac_instance *dev) | |||
2021 | { | 2028 | { |
2022 | if (emac_has_feature(dev, EMAC_FTR_EMAC4)) | 2029 | if (emac_has_feature(dev, EMAC_FTR_EMAC4)) |
2023 | return sizeof(struct emac_ethtool_regs_subhdr) + | 2030 | return sizeof(struct emac_ethtool_regs_subhdr) + |
2024 | EMAC4_ETHTOOL_REGS_SIZE; | 2031 | EMAC4_ETHTOOL_REGS_SIZE(dev); |
2025 | else | 2032 | else |
2026 | return sizeof(struct emac_ethtool_regs_subhdr) + | 2033 | return sizeof(struct emac_ethtool_regs_subhdr) + |
2027 | EMAC_ETHTOOL_REGS_SIZE; | 2034 | EMAC_ETHTOOL_REGS_SIZE(dev); |
2028 | } | 2035 | } |
2029 | 2036 | ||
2030 | static int emac_ethtool_get_regs_len(struct net_device *ndev) | 2037 | static int emac_ethtool_get_regs_len(struct net_device *ndev) |
@@ -2051,12 +2058,12 @@ static void *emac_dump_regs(struct emac_instance *dev, void *buf) | |||
2051 | hdr->index = dev->cell_index; | 2058 | hdr->index = dev->cell_index; |
2052 | if (emac_has_feature(dev, EMAC_FTR_EMAC4)) { | 2059 | if (emac_has_feature(dev, EMAC_FTR_EMAC4)) { |
2053 | hdr->version = EMAC4_ETHTOOL_REGS_VER; | 2060 | hdr->version = EMAC4_ETHTOOL_REGS_VER; |
2054 | memcpy_fromio(hdr + 1, dev->emacp, EMAC4_ETHTOOL_REGS_SIZE); | 2061 | memcpy_fromio(hdr + 1, dev->emacp, EMAC4_ETHTOOL_REGS_SIZE(dev)); |
2055 | return ((void *)(hdr + 1) + EMAC4_ETHTOOL_REGS_SIZE); | 2062 | return ((void *)(hdr + 1) + EMAC4_ETHTOOL_REGS_SIZE(dev)); |
2056 | } else { | 2063 | } else { |
2057 | hdr->version = EMAC_ETHTOOL_REGS_VER; | 2064 | hdr->version = EMAC_ETHTOOL_REGS_VER; |
2058 | memcpy_fromio(hdr + 1, dev->emacp, EMAC_ETHTOOL_REGS_SIZE); | 2065 | memcpy_fromio(hdr + 1, dev->emacp, EMAC_ETHTOOL_REGS_SIZE(dev)); |
2059 | return ((void *)(hdr + 1) + EMAC_ETHTOOL_REGS_SIZE); | 2066 | return ((void *)(hdr + 1) + EMAC_ETHTOOL_REGS_SIZE(dev)); |
2060 | } | 2067 | } |
2061 | } | 2068 | } |
2062 | 2069 | ||
@@ -2546,7 +2553,9 @@ static int __devinit emac_init_config(struct emac_instance *dev) | |||
2546 | } | 2553 | } |
2547 | 2554 | ||
2548 | /* Check EMAC version */ | 2555 | /* Check EMAC version */ |
2549 | if (of_device_is_compatible(np, "ibm,emac4")) { | 2556 | if (of_device_is_compatible(np, "ibm,emac4sync")) { |
2557 | dev->features |= (EMAC_FTR_EMAC4 | EMAC_FTR_EMAC4SYNC); | ||
2558 | } else if (of_device_is_compatible(np, "ibm,emac4")) { | ||
2550 | dev->features |= EMAC_FTR_EMAC4; | 2559 | dev->features |= EMAC_FTR_EMAC4; |
2551 | if (of_device_is_compatible(np, "ibm,emac-440gx")) | 2560 | if (of_device_is_compatible(np, "ibm,emac-440gx")) |
2552 | dev->features |= EMAC_FTR_440GX_PHY_CLK_FIX; | 2561 | dev->features |= EMAC_FTR_440GX_PHY_CLK_FIX; |
@@ -2607,6 +2616,15 @@ static int __devinit emac_init_config(struct emac_instance *dev) | |||
2607 | } | 2616 | } |
2608 | memcpy(dev->ndev->dev_addr, p, 6); | 2617 | memcpy(dev->ndev->dev_addr, p, 6); |
2609 | 2618 | ||
2619 | /* IAHT and GAHT filter parameterization */ | ||
2620 | if (emac_has_feature(dev, EMAC_FTR_EMAC4SYNC)) { | ||
2621 | dev->xaht_slots_shift = EMAC4SYNC_XAHT_SLOTS_SHIFT; | ||
2622 | dev->xaht_width_shift = EMAC4SYNC_XAHT_WIDTH_SHIFT; | ||
2623 | } else { | ||
2624 | dev->xaht_slots_shift = EMAC4_XAHT_SLOTS_SHIFT; | ||
2625 | dev->xaht_width_shift = EMAC4_XAHT_WIDTH_SHIFT; | ||
2626 | } | ||
2627 | |||
2610 | DBG(dev, "features : 0x%08x / 0x%08x\n", dev->features, EMAC_FTRS_POSSIBLE); | 2628 | DBG(dev, "features : 0x%08x / 0x%08x\n", dev->features, EMAC_FTRS_POSSIBLE); |
2611 | DBG(dev, "tx_fifo_size : %d (%d gige)\n", dev->tx_fifo_size, dev->tx_fifo_size_gige); | 2629 | DBG(dev, "tx_fifo_size : %d (%d gige)\n", dev->tx_fifo_size, dev->tx_fifo_size_gige); |
2612 | DBG(dev, "rx_fifo_size : %d (%d gige)\n", dev->rx_fifo_size, dev->rx_fifo_size_gige); | 2630 | DBG(dev, "rx_fifo_size : %d (%d gige)\n", dev->rx_fifo_size, dev->rx_fifo_size_gige); |
@@ -2678,7 +2696,8 @@ static int __devinit emac_probe(struct of_device *ofdev, | |||
2678 | goto err_irq_unmap; | 2696 | goto err_irq_unmap; |
2679 | } | 2697 | } |
2680 | // TODO : request_mem_region | 2698 | // TODO : request_mem_region |
2681 | dev->emacp = ioremap(dev->rsrc_regs.start, sizeof(struct emac_regs)); | 2699 | dev->emacp = ioremap(dev->rsrc_regs.start, |
2700 | dev->rsrc_regs.end - dev->rsrc_regs.start + 1); | ||
2682 | if (dev->emacp == NULL) { | 2701 | if (dev->emacp == NULL) { |
2683 | printk(KERN_ERR "%s: Can't map device registers!\n", | 2702 | printk(KERN_ERR "%s: Can't map device registers!\n", |
2684 | np->full_name); | 2703 | np->full_name); |
@@ -2892,6 +2911,10 @@ static struct of_device_id emac_match[] = | |||
2892 | .type = "network", | 2911 | .type = "network", |
2893 | .compatible = "ibm,emac4", | 2912 | .compatible = "ibm,emac4", |
2894 | }, | 2913 | }, |
2914 | { | ||
2915 | .type = "network", | ||
2916 | .compatible = "ibm,emac4sync", | ||
2917 | }, | ||
2895 | {}, | 2918 | {}, |
2896 | }; | 2919 | }; |
2897 | 2920 | ||
diff --git a/drivers/net/ibm_newemac/core.h b/drivers/net/ibm_newemac/core.h index 1683db9870a4..6545e69d12c3 100644 --- a/drivers/net/ibm_newemac/core.h +++ b/drivers/net/ibm_newemac/core.h | |||
@@ -33,8 +33,8 @@ | |||
33 | #include <linux/netdevice.h> | 33 | #include <linux/netdevice.h> |
34 | #include <linux/dma-mapping.h> | 34 | #include <linux/dma-mapping.h> |
35 | #include <linux/spinlock.h> | 35 | #include <linux/spinlock.h> |
36 | #include <linux/of_platform.h> | ||
36 | 37 | ||
37 | #include <asm/of_platform.h> | ||
38 | #include <asm/io.h> | 38 | #include <asm/io.h> |
39 | #include <asm/dcr.h> | 39 | #include <asm/dcr.h> |
40 | 40 | ||
@@ -235,6 +235,10 @@ struct emac_instance { | |||
235 | u32 fifo_entry_size; | 235 | u32 fifo_entry_size; |
236 | u32 mal_burst_size; /* move to MAL ? */ | 236 | u32 mal_burst_size; /* move to MAL ? */ |
237 | 237 | ||
238 | /* IAHT and GAHT filter parameterization */ | ||
239 | u32 xaht_slots_shift; | ||
240 | u32 xaht_width_shift; | ||
241 | |||
238 | /* Descriptor management | 242 | /* Descriptor management |
239 | */ | 243 | */ |
240 | struct mal_descriptor *tx_desc; | 244 | struct mal_descriptor *tx_desc; |
@@ -309,6 +313,10 @@ struct emac_instance { | |||
309 | * Set if we need phy clock workaround for 440ep or 440gr | 313 | * Set if we need phy clock workaround for 440ep or 440gr |
310 | */ | 314 | */ |
311 | #define EMAC_FTR_440EP_PHY_CLK_FIX 0x00000100 | 315 | #define EMAC_FTR_440EP_PHY_CLK_FIX 0x00000100 |
316 | /* | ||
317 | * The 405EX and 460EX contain the EMAC4SYNC core | ||
318 | */ | ||
319 | #define EMAC_FTR_EMAC4SYNC 0x00000200 | ||
312 | 320 | ||
313 | 321 | ||
314 | /* Right now, we don't quite handle the always/possible masks on the | 322 | /* Right now, we don't quite handle the always/possible masks on the |
@@ -320,7 +328,8 @@ enum { | |||
320 | 328 | ||
321 | EMAC_FTRS_POSSIBLE = | 329 | EMAC_FTRS_POSSIBLE = |
322 | #ifdef CONFIG_IBM_NEW_EMAC_EMAC4 | 330 | #ifdef CONFIG_IBM_NEW_EMAC_EMAC4 |
323 | EMAC_FTR_EMAC4 | EMAC_FTR_HAS_NEW_STACR | | 331 | EMAC_FTR_EMAC4 | EMAC_FTR_EMAC4SYNC | |
332 | EMAC_FTR_HAS_NEW_STACR | | ||
324 | EMAC_FTR_STACR_OC_INVERT | EMAC_FTR_440GX_PHY_CLK_FIX | | 333 | EMAC_FTR_STACR_OC_INVERT | EMAC_FTR_440GX_PHY_CLK_FIX | |
325 | #endif | 334 | #endif |
326 | #ifdef CONFIG_IBM_NEW_EMAC_TAH | 335 | #ifdef CONFIG_IBM_NEW_EMAC_TAH |
@@ -342,6 +351,71 @@ static inline int emac_has_feature(struct emac_instance *dev, | |||
342 | (EMAC_FTRS_POSSIBLE & dev->features & feature); | 351 | (EMAC_FTRS_POSSIBLE & dev->features & feature); |
343 | } | 352 | } |
344 | 353 | ||
354 | /* | ||
355 | * Various instances of the EMAC core have varying 1) number of | ||
356 | * address match slots, 2) width of the registers for handling address | ||
357 | * match slots, 3) number of registers for handling address match | ||
358 | * slots and 4) base offset for those registers. | ||
359 | * | ||
360 | * These macros and inlines handle these differences based on | ||
361 | * parameters supplied by the device structure which are, in turn, | ||
362 | * initialized based on the "compatible" entry in the device tree. | ||
363 | */ | ||
364 | |||
365 | #define EMAC4_XAHT_SLOTS_SHIFT 6 | ||
366 | #define EMAC4_XAHT_WIDTH_SHIFT 4 | ||
367 | |||
368 | #define EMAC4SYNC_XAHT_SLOTS_SHIFT 8 | ||
369 | #define EMAC4SYNC_XAHT_WIDTH_SHIFT 5 | ||
370 | |||
371 | #define EMAC_XAHT_SLOTS(dev) (1 << (dev)->xaht_slots_shift) | ||
372 | #define EMAC_XAHT_WIDTH(dev) (1 << (dev)->xaht_width_shift) | ||
373 | #define EMAC_XAHT_REGS(dev) (1 << ((dev)->xaht_slots_shift - \ | ||
374 | (dev)->xaht_width_shift)) | ||
375 | |||
376 | #define EMAC_XAHT_CRC_TO_SLOT(dev, crc) \ | ||
377 | ((EMAC_XAHT_SLOTS(dev) - 1) - \ | ||
378 | ((crc) >> ((sizeof (u32) * BITS_PER_BYTE) - \ | ||
379 | (dev)->xaht_slots_shift))) | ||
380 | |||
381 | #define EMAC_XAHT_SLOT_TO_REG(dev, slot) \ | ||
382 | ((slot) >> (dev)->xaht_width_shift) | ||
383 | |||
384 | #define EMAC_XAHT_SLOT_TO_MASK(dev, slot) \ | ||
385 | ((u32)(1 << (EMAC_XAHT_WIDTH(dev) - 1)) >> \ | ||
386 | ((slot) & (u32)(EMAC_XAHT_WIDTH(dev) - 1))) | ||
387 | |||
388 | static inline u32 *emac_xaht_base(struct emac_instance *dev) | ||
389 | { | ||
390 | struct emac_regs __iomem *p = dev->emacp; | ||
391 | int offset; | ||
392 | |||
393 | /* The first IAHT entry always is the base of the block of | ||
394 | * IAHT and GAHT registers. | ||
395 | */ | ||
396 | if (emac_has_feature(dev, EMAC_FTR_EMAC4SYNC)) | ||
397 | offset = offsetof(struct emac_regs, u1.emac4sync.iaht1); | ||
398 | else | ||
399 | offset = offsetof(struct emac_regs, u0.emac4.iaht1); | ||
400 | |||
401 | return ((u32 *)((ptrdiff_t)p + offset)); | ||
402 | } | ||
403 | |||
404 | static inline u32 *emac_gaht_base(struct emac_instance *dev) | ||
405 | { | ||
406 | /* GAHT registers always come after an identical number of | ||
407 | * IAHT registers. | ||
408 | */ | ||
409 | return (emac_xaht_base(dev) + EMAC_XAHT_REGS(dev)); | ||
410 | } | ||
411 | |||
412 | static inline u32 *emac_iaht_base(struct emac_instance *dev) | ||
413 | { | ||
414 | /* IAHT registers always come before an identical number of | ||
415 | * GAHT registers. | ||
416 | */ | ||
417 | return (emac_xaht_base(dev)); | ||
418 | } | ||
345 | 419 | ||
346 | /* Ethtool get_regs complex data. | 420 | /* Ethtool get_regs complex data. |
347 | * We want to get not just EMAC registers, but also MAL, ZMII, RGMII, TAH | 421 | * We want to get not just EMAC registers, but also MAL, ZMII, RGMII, TAH |
@@ -366,4 +440,11 @@ struct emac_ethtool_regs_subhdr { | |||
366 | u32 index; | 440 | u32 index; |
367 | }; | 441 | }; |
368 | 442 | ||
443 | #define EMAC_ETHTOOL_REGS_VER 0 | ||
444 | #define EMAC_ETHTOOL_REGS_SIZE(dev) ((dev)->rsrc_regs.end - \ | ||
445 | (dev)->rsrc_regs.start + 1) | ||
446 | #define EMAC4_ETHTOOL_REGS_VER 1 | ||
447 | #define EMAC4_ETHTOOL_REGS_SIZE(dev) ((dev)->rsrc_regs.end - \ | ||
448 | (dev)->rsrc_regs.start + 1) | ||
449 | |||
369 | #endif /* __IBM_NEWEMAC_CORE_H */ | 450 | #endif /* __IBM_NEWEMAC_CORE_H */ |
diff --git a/drivers/net/ibm_newemac/debug.c b/drivers/net/ibm_newemac/debug.c index 86b756a30784..775c850a425a 100644 --- a/drivers/net/ibm_newemac/debug.c +++ b/drivers/net/ibm_newemac/debug.c | |||
@@ -67,29 +67,55 @@ static void emac_desc_dump(struct emac_instance *p) | |||
67 | static void emac_mac_dump(struct emac_instance *dev) | 67 | static void emac_mac_dump(struct emac_instance *dev) |
68 | { | 68 | { |
69 | struct emac_regs __iomem *p = dev->emacp; | 69 | struct emac_regs __iomem *p = dev->emacp; |
70 | const int xaht_regs = EMAC_XAHT_REGS(dev); | ||
71 | u32 *gaht_base = emac_gaht_base(dev); | ||
72 | u32 *iaht_base = emac_iaht_base(dev); | ||
73 | int emac4sync = emac_has_feature(dev, EMAC_FTR_EMAC4SYNC); | ||
74 | int n; | ||
70 | 75 | ||
71 | printk("** EMAC %s registers **\n" | 76 | printk("** EMAC %s registers **\n" |
72 | "MR0 = 0x%08x MR1 = 0x%08x TMR0 = 0x%08x TMR1 = 0x%08x\n" | 77 | "MR0 = 0x%08x MR1 = 0x%08x TMR0 = 0x%08x TMR1 = 0x%08x\n" |
73 | "RMR = 0x%08x ISR = 0x%08x ISER = 0x%08x\n" | 78 | "RMR = 0x%08x ISR = 0x%08x ISER = 0x%08x\n" |
74 | "IAR = %04x%08x VTPID = 0x%04x VTCI = 0x%04x\n" | 79 | "IAR = %04x%08x VTPID = 0x%04x VTCI = 0x%04x\n", |
75 | "IAHT: 0x%04x 0x%04x 0x%04x 0x%04x " | ||
76 | "GAHT: 0x%04x 0x%04x 0x%04x 0x%04x\n" | ||
77 | "LSA = %04x%08x IPGVR = 0x%04x\n" | ||
78 | "STACR = 0x%08x TRTR = 0x%08x RWMR = 0x%08x\n" | ||
79 | "OCTX = 0x%08x OCRX = 0x%08x IPCR = 0x%08x\n", | ||
80 | dev->ofdev->node->full_name, in_be32(&p->mr0), in_be32(&p->mr1), | 80 | dev->ofdev->node->full_name, in_be32(&p->mr0), in_be32(&p->mr1), |
81 | in_be32(&p->tmr0), in_be32(&p->tmr1), | 81 | in_be32(&p->tmr0), in_be32(&p->tmr1), |
82 | in_be32(&p->rmr), in_be32(&p->isr), in_be32(&p->iser), | 82 | in_be32(&p->rmr), in_be32(&p->isr), in_be32(&p->iser), |
83 | in_be32(&p->iahr), in_be32(&p->ialr), in_be32(&p->vtpid), | 83 | in_be32(&p->iahr), in_be32(&p->ialr), in_be32(&p->vtpid), |
84 | in_be32(&p->vtci), | 84 | in_be32(&p->vtci) |
85 | in_be32(&p->iaht1), in_be32(&p->iaht2), in_be32(&p->iaht3), | 85 | ); |
86 | in_be32(&p->iaht4), | 86 | |
87 | in_be32(&p->gaht1), in_be32(&p->gaht2), in_be32(&p->gaht3), | 87 | if (emac4sync) |
88 | in_be32(&p->gaht4), | 88 | printk("MAR = %04x%08x MMAR = %04x%08x\n", |
89 | in_be32(&p->u0.emac4sync.mahr), | ||
90 | in_be32(&p->u0.emac4sync.malr), | ||
91 | in_be32(&p->u0.emac4sync.mmahr), | ||
92 | in_be32(&p->u0.emac4sync.mmalr) | ||
93 | ); | ||
94 | |||
95 | for (n = 0; n < xaht_regs; n++) | ||
96 | printk("IAHT%02d = 0x%08x\n", n + 1, in_be32(iaht_base + n)); | ||
97 | |||
98 | for (n = 0; n < xaht_regs; n++) | ||
99 | printk("GAHT%02d = 0x%08x\n", n + 1, in_be32(gaht_base + n)); | ||
100 | |||
101 | printk("LSA = %04x%08x IPGVR = 0x%04x\n" | ||
102 | "STACR = 0x%08x TRTR = 0x%08x RWMR = 0x%08x\n" | ||
103 | "OCTX = 0x%08x OCRX = 0x%08x\n", | ||
89 | in_be32(&p->lsah), in_be32(&p->lsal), in_be32(&p->ipgvr), | 104 | in_be32(&p->lsah), in_be32(&p->lsal), in_be32(&p->ipgvr), |
90 | in_be32(&p->stacr), in_be32(&p->trtr), in_be32(&p->rwmr), | 105 | in_be32(&p->stacr), in_be32(&p->trtr), in_be32(&p->rwmr), |
91 | in_be32(&p->octx), in_be32(&p->ocrx), in_be32(&p->ipcr) | 106 | in_be32(&p->octx), in_be32(&p->ocrx) |
92 | ); | 107 | ); |
108 | |||
109 | if (!emac4sync) { | ||
110 | printk("IPCR = 0x%08x\n", | ||
111 | in_be32(&p->u1.emac4.ipcr) | ||
112 | ); | ||
113 | } else { | ||
114 | printk("REVID = 0x%08x TPC = 0x%08x\n", | ||
115 | in_be32(&p->u1.emac4sync.revid), | ||
116 | in_be32(&p->u1.emac4sync.tpc) | ||
117 | ); | ||
118 | } | ||
93 | 119 | ||
94 | emac_desc_dump(dev); | 120 | emac_desc_dump(dev); |
95 | } | 121 | } |
diff --git a/drivers/net/ibm_newemac/emac.h b/drivers/net/ibm_newemac/emac.h index 91cb096ab405..0afc2cf5c52b 100644 --- a/drivers/net/ibm_newemac/emac.h +++ b/drivers/net/ibm_newemac/emac.h | |||
@@ -27,37 +27,80 @@ | |||
27 | 27 | ||
28 | #include <linux/types.h> | 28 | #include <linux/types.h> |
29 | 29 | ||
30 | /* EMAC registers Write Access rules */ | 30 | /* EMAC registers Write Access rules */ |
31 | struct emac_regs { | 31 | struct emac_regs { |
32 | u32 mr0; /* special */ | 32 | /* Common registers across all EMAC implementations. */ |
33 | u32 mr1; /* Reset */ | 33 | u32 mr0; /* Special */ |
34 | u32 tmr0; /* special */ | 34 | u32 mr1; /* Reset */ |
35 | u32 tmr1; /* special */ | 35 | u32 tmr0; /* Special */ |
36 | u32 rmr; /* Reset */ | 36 | u32 tmr1; /* Special */ |
37 | u32 isr; /* Always */ | 37 | u32 rmr; /* Reset */ |
38 | u32 iser; /* Reset */ | 38 | u32 isr; /* Always */ |
39 | u32 iahr; /* Reset, R, T */ | 39 | u32 iser; /* Reset */ |
40 | u32 ialr; /* Reset, R, T */ | 40 | u32 iahr; /* Reset, R, T */ |
41 | u32 vtpid; /* Reset, R, T */ | 41 | u32 ialr; /* Reset, R, T */ |
42 | u32 vtci; /* Reset, R, T */ | 42 | u32 vtpid; /* Reset, R, T */ |
43 | u32 ptr; /* Reset, T */ | 43 | u32 vtci; /* Reset, R, T */ |
44 | u32 iaht1; /* Reset, R */ | 44 | u32 ptr; /* Reset, T */ |
45 | u32 iaht2; /* Reset, R */ | 45 | union { |
46 | u32 iaht3; /* Reset, R */ | 46 | /* Registers unique to EMAC4 implementations */ |
47 | u32 iaht4; /* Reset, R */ | 47 | struct { |
48 | u32 gaht1; /* Reset, R */ | 48 | u32 iaht1; /* Reset, R */ |
49 | u32 gaht2; /* Reset, R */ | 49 | u32 iaht2; /* Reset, R */ |
50 | u32 gaht3; /* Reset, R */ | 50 | u32 iaht3; /* Reset, R */ |
51 | u32 gaht4; /* Reset, R */ | 51 | u32 iaht4; /* Reset, R */ |
52 | u32 gaht1; /* Reset, R */ | ||
53 | u32 gaht2; /* Reset, R */ | ||
54 | u32 gaht3; /* Reset, R */ | ||
55 | u32 gaht4; /* Reset, R */ | ||
56 | } emac4; | ||
57 | /* Registers unique to EMAC4SYNC implementations */ | ||
58 | struct { | ||
59 | u32 mahr; /* Reset, R, T */ | ||
60 | u32 malr; /* Reset, R, T */ | ||
61 | u32 mmahr; /* Reset, R, T */ | ||
62 | u32 mmalr; /* Reset, R, T */ | ||
63 | u32 rsvd0[4]; | ||
64 | } emac4sync; | ||
65 | } u0; | ||
66 | /* Common registers across all EMAC implementations. */ | ||
52 | u32 lsah; | 67 | u32 lsah; |
53 | u32 lsal; | 68 | u32 lsal; |
54 | u32 ipgvr; /* Reset, T */ | 69 | u32 ipgvr; /* Reset, T */ |
55 | u32 stacr; /* special */ | 70 | u32 stacr; /* Special */ |
56 | u32 trtr; /* special */ | 71 | u32 trtr; /* Special */ |
57 | u32 rwmr; /* Reset */ | 72 | u32 rwmr; /* Reset */ |
58 | u32 octx; | 73 | u32 octx; |
59 | u32 ocrx; | 74 | u32 ocrx; |
60 | u32 ipcr; | 75 | union { |
76 | /* Registers unique to EMAC4 implementations */ | ||
77 | struct { | ||
78 | u32 ipcr; | ||
79 | } emac4; | ||
80 | /* Registers unique to EMAC4SYNC implementations */ | ||
81 | struct { | ||
82 | u32 rsvd1; | ||
83 | u32 revid; | ||
84 | u32 rsvd2[2]; | ||
85 | u32 iaht1; /* Reset, R */ | ||
86 | u32 iaht2; /* Reset, R */ | ||
87 | u32 iaht3; /* Reset, R */ | ||
88 | u32 iaht4; /* Reset, R */ | ||
89 | u32 iaht5; /* Reset, R */ | ||
90 | u32 iaht6; /* Reset, R */ | ||
91 | u32 iaht7; /* Reset, R */ | ||
92 | u32 iaht8; /* Reset, R */ | ||
93 | u32 gaht1; /* Reset, R */ | ||
94 | u32 gaht2; /* Reset, R */ | ||
95 | u32 gaht3; /* Reset, R */ | ||
96 | u32 gaht4; /* Reset, R */ | ||
97 | u32 gaht5; /* Reset, R */ | ||
98 | u32 gaht6; /* Reset, R */ | ||
99 | u32 gaht7; /* Reset, R */ | ||
100 | u32 gaht8; /* Reset, R */ | ||
101 | u32 tpc; /* Reset, T */ | ||
102 | } emac4sync; | ||
103 | } u1; | ||
61 | }; | 104 | }; |
62 | 105 | ||
63 | /* | 106 | /* |
@@ -73,12 +116,6 @@ struct emac_regs { | |||
73 | #define PHY_MODE_RTBI 7 | 116 | #define PHY_MODE_RTBI 7 |
74 | #define PHY_MODE_SGMII 8 | 117 | #define PHY_MODE_SGMII 8 |
75 | 118 | ||
76 | |||
77 | #define EMAC_ETHTOOL_REGS_VER 0 | ||
78 | #define EMAC_ETHTOOL_REGS_SIZE (sizeof(struct emac_regs) - sizeof(u32)) | ||
79 | #define EMAC4_ETHTOOL_REGS_VER 1 | ||
80 | #define EMAC4_ETHTOOL_REGS_SIZE sizeof(struct emac_regs) | ||
81 | |||
82 | /* EMACx_MR0 */ | 119 | /* EMACx_MR0 */ |
83 | #define EMAC_MR0_RXI 0x80000000 | 120 | #define EMAC_MR0_RXI 0x80000000 |
84 | #define EMAC_MR0_TXI 0x40000000 | 121 | #define EMAC_MR0_TXI 0x40000000 |
diff --git a/drivers/net/ibm_newemac/rgmii.c b/drivers/net/ibm_newemac/rgmii.c index e32da3de2695..1d5379de6900 100644 --- a/drivers/net/ibm_newemac/rgmii.c +++ b/drivers/net/ibm_newemac/rgmii.c | |||
@@ -39,6 +39,7 @@ | |||
39 | #define RGMII_FER_RGMII(idx) (0x5 << ((idx) * 4)) | 39 | #define RGMII_FER_RGMII(idx) (0x5 << ((idx) * 4)) |
40 | #define RGMII_FER_TBI(idx) (0x6 << ((idx) * 4)) | 40 | #define RGMII_FER_TBI(idx) (0x6 << ((idx) * 4)) |
41 | #define RGMII_FER_GMII(idx) (0x7 << ((idx) * 4)) | 41 | #define RGMII_FER_GMII(idx) (0x7 << ((idx) * 4)) |
42 | #define RGMII_FER_MII(idx) RGMII_FER_GMII(idx) | ||
42 | 43 | ||
43 | /* RGMIIx_SSR */ | 44 | /* RGMIIx_SSR */ |
44 | #define RGMII_SSR_MASK(idx) (0x7 << ((idx) * 8)) | 45 | #define RGMII_SSR_MASK(idx) (0x7 << ((idx) * 8)) |
@@ -49,6 +50,7 @@ | |||
49 | static inline int rgmii_valid_mode(int phy_mode) | 50 | static inline int rgmii_valid_mode(int phy_mode) |
50 | { | 51 | { |
51 | return phy_mode == PHY_MODE_GMII || | 52 | return phy_mode == PHY_MODE_GMII || |
53 | phy_mode == PHY_MODE_MII || | ||
52 | phy_mode == PHY_MODE_RGMII || | 54 | phy_mode == PHY_MODE_RGMII || |
53 | phy_mode == PHY_MODE_TBI || | 55 | phy_mode == PHY_MODE_TBI || |
54 | phy_mode == PHY_MODE_RTBI; | 56 | phy_mode == PHY_MODE_RTBI; |
@@ -63,6 +65,8 @@ static inline const char *rgmii_mode_name(int mode) | |||
63 | return "TBI"; | 65 | return "TBI"; |
64 | case PHY_MODE_GMII: | 66 | case PHY_MODE_GMII: |
65 | return "GMII"; | 67 | return "GMII"; |
68 | case PHY_MODE_MII: | ||
69 | return "MII"; | ||
66 | case PHY_MODE_RTBI: | 70 | case PHY_MODE_RTBI: |
67 | return "RTBI"; | 71 | return "RTBI"; |
68 | default: | 72 | default: |
@@ -79,6 +83,8 @@ static inline u32 rgmii_mode_mask(int mode, int input) | |||
79 | return RGMII_FER_TBI(input); | 83 | return RGMII_FER_TBI(input); |
80 | case PHY_MODE_GMII: | 84 | case PHY_MODE_GMII: |
81 | return RGMII_FER_GMII(input); | 85 | return RGMII_FER_GMII(input); |
86 | case PHY_MODE_MII: | ||
87 | return RGMII_FER_MII(input); | ||
82 | case PHY_MODE_RTBI: | 88 | case PHY_MODE_RTBI: |
83 | return RGMII_FER_RTBI(input); | 89 | return RGMII_FER_RTBI(input); |
84 | default: | 90 | default: |
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index fb0b918e5ccb..402e81020fb8 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c | |||
@@ -28,8 +28,8 @@ | |||
28 | #include <linux/mii.h> | 28 | #include <linux/mii.h> |
29 | #include <linux/phy.h> | 29 | #include <linux/phy.h> |
30 | #include <linux/workqueue.h> | 30 | #include <linux/workqueue.h> |
31 | #include <linux/of_platform.h> | ||
31 | 32 | ||
32 | #include <asm/of_platform.h> | ||
33 | #include <asm/uaccess.h> | 33 | #include <asm/uaccess.h> |
34 | #include <asm/irq.h> | 34 | #include <asm/irq.h> |
35 | #include <asm/io.h> | 35 | #include <asm/io.h> |
diff --git a/drivers/net/ucc_geth_mii.c b/drivers/net/ucc_geth_mii.c index 940474736922..6d9e7ad9fda9 100644 --- a/drivers/net/ucc_geth_mii.c +++ b/drivers/net/ucc_geth_mii.c | |||
@@ -36,8 +36,8 @@ | |||
36 | #include <linux/mii.h> | 36 | #include <linux/mii.h> |
37 | #include <linux/phy.h> | 37 | #include <linux/phy.h> |
38 | #include <linux/fsl_devices.h> | 38 | #include <linux/fsl_devices.h> |
39 | #include <linux/of_platform.h> | ||
39 | 40 | ||
40 | #include <asm/of_platform.h> | ||
41 | #include <asm/io.h> | 41 | #include <asm/io.h> |
42 | #include <asm/irq.h> | 42 | #include <asm/irq.h> |
43 | #include <asm/uaccess.h> | 43 | #include <asm/uaccess.h> |
diff --git a/drivers/of/device.c b/drivers/of/device.c index 29681c4b700b..8a1d93a2bb81 100644 --- a/drivers/of/device.c +++ b/drivers/of/device.c | |||
@@ -48,16 +48,32 @@ void of_dev_put(struct of_device *dev) | |||
48 | } | 48 | } |
49 | EXPORT_SYMBOL(of_dev_put); | 49 | EXPORT_SYMBOL(of_dev_put); |
50 | 50 | ||
51 | static ssize_t dev_show_devspec(struct device *dev, | 51 | static ssize_t devspec_show(struct device *dev, |
52 | struct device_attribute *attr, char *buf) | 52 | struct device_attribute *attr, char *buf) |
53 | { | 53 | { |
54 | struct of_device *ofdev; | 54 | struct of_device *ofdev; |
55 | 55 | ||
56 | ofdev = to_of_device(dev); | 56 | ofdev = to_of_device(dev); |
57 | return sprintf(buf, "%s", ofdev->node->full_name); | 57 | return sprintf(buf, "%s\n", ofdev->node->full_name); |
58 | } | 58 | } |
59 | 59 | ||
60 | static DEVICE_ATTR(devspec, S_IRUGO, dev_show_devspec, NULL); | 60 | static ssize_t modalias_show(struct device *dev, |
61 | struct device_attribute *attr, char *buf) | ||
62 | { | ||
63 | struct of_device *ofdev = to_of_device(dev); | ||
64 | ssize_t len = 0; | ||
65 | |||
66 | len = of_device_get_modalias(ofdev, buf, PAGE_SIZE - 2); | ||
67 | buf[len] = '\n'; | ||
68 | buf[len+1] = 0; | ||
69 | return len+1; | ||
70 | } | ||
71 | |||
72 | struct device_attribute of_platform_device_attrs[] = { | ||
73 | __ATTR_RO(devspec), | ||
74 | __ATTR_RO(modalias), | ||
75 | __ATTR_NULL | ||
76 | }; | ||
61 | 77 | ||
62 | /** | 78 | /** |
63 | * of_release_dev - free an of device structure when all users of it are finished. | 79 | * of_release_dev - free an of device structure when all users of it are finished. |
@@ -78,25 +94,61 @@ EXPORT_SYMBOL(of_release_dev); | |||
78 | 94 | ||
79 | int of_device_register(struct of_device *ofdev) | 95 | int of_device_register(struct of_device *ofdev) |
80 | { | 96 | { |
81 | int rc; | ||
82 | |||
83 | BUG_ON(ofdev->node == NULL); | 97 | BUG_ON(ofdev->node == NULL); |
84 | 98 | return device_register(&ofdev->dev); | |
85 | rc = device_register(&ofdev->dev); | ||
86 | if (rc) | ||
87 | return rc; | ||
88 | |||
89 | rc = device_create_file(&ofdev->dev, &dev_attr_devspec); | ||
90 | if (rc) | ||
91 | device_unregister(&ofdev->dev); | ||
92 | |||
93 | return rc; | ||
94 | } | 99 | } |
95 | EXPORT_SYMBOL(of_device_register); | 100 | EXPORT_SYMBOL(of_device_register); |
96 | 101 | ||
97 | void of_device_unregister(struct of_device *ofdev) | 102 | void of_device_unregister(struct of_device *ofdev) |
98 | { | 103 | { |
99 | device_remove_file(&ofdev->dev, &dev_attr_devspec); | ||
100 | device_unregister(&ofdev->dev); | 104 | device_unregister(&ofdev->dev); |
101 | } | 105 | } |
102 | EXPORT_SYMBOL(of_device_unregister); | 106 | EXPORT_SYMBOL(of_device_unregister); |
107 | |||
108 | ssize_t of_device_get_modalias(struct of_device *ofdev, | ||
109 | char *str, ssize_t len) | ||
110 | { | ||
111 | const char *compat; | ||
112 | int cplen, i; | ||
113 | ssize_t tsize, csize, repend; | ||
114 | |||
115 | /* Name & Type */ | ||
116 | csize = snprintf(str, len, "of:N%sT%s", | ||
117 | ofdev->node->name, ofdev->node->type); | ||
118 | |||
119 | /* Get compatible property if any */ | ||
120 | compat = of_get_property(ofdev->node, "compatible", &cplen); | ||
121 | if (!compat) | ||
122 | return csize; | ||
123 | |||
124 | /* Find true end (we tolerate multiple \0 at the end */ | ||
125 | for (i = (cplen - 1); i >= 0 && !compat[i]; i--) | ||
126 | cplen--; | ||
127 | if (!cplen) | ||
128 | return csize; | ||
129 | cplen++; | ||
130 | |||
131 | /* Check space (need cplen+1 chars including final \0) */ | ||
132 | tsize = csize + cplen; | ||
133 | repend = tsize; | ||
134 | |||
135 | if (csize >= len) /* @ the limit, all is already filled */ | ||
136 | return tsize; | ||
137 | |||
138 | if (tsize >= len) { /* limit compat list */ | ||
139 | cplen = len - csize - 1; | ||
140 | repend = len; | ||
141 | } | ||
142 | |||
143 | /* Copy and do char replacement */ | ||
144 | memcpy(&str[csize + 1], compat, cplen); | ||
145 | for (i = csize; i < repend; i++) { | ||
146 | char c = str[i]; | ||
147 | if (c == '\0') | ||
148 | str[i] = 'C'; | ||
149 | else if (c == ' ') | ||
150 | str[i] = '_'; | ||
151 | } | ||
152 | |||
153 | return tsize; | ||
154 | } | ||
diff --git a/drivers/of/gpio.c b/drivers/of/gpio.c index 000681e98f2c..1c9cab844f10 100644 --- a/drivers/of/gpio.c +++ b/drivers/of/gpio.c | |||
@@ -137,38 +137,6 @@ int of_gpio_simple_xlate(struct of_gpio_chip *of_gc, struct device_node *np, | |||
137 | } | 137 | } |
138 | EXPORT_SYMBOL(of_gpio_simple_xlate); | 138 | EXPORT_SYMBOL(of_gpio_simple_xlate); |
139 | 139 | ||
140 | /* Should be sufficient for now, later we'll use dynamic bases. */ | ||
141 | #if defined(CONFIG_PPC32) || defined(CONFIG_SPARC32) | ||
142 | #define GPIOS_PER_CHIP 32 | ||
143 | #else | ||
144 | #define GPIOS_PER_CHIP 64 | ||
145 | #endif | ||
146 | |||
147 | static int of_get_gpiochip_base(struct device_node *np) | ||
148 | { | ||
149 | struct device_node *gc = NULL; | ||
150 | int gpiochip_base = 0; | ||
151 | |||
152 | while ((gc = of_find_all_nodes(gc))) { | ||
153 | if (!of_get_property(gc, "gpio-controller", NULL)) | ||
154 | continue; | ||
155 | |||
156 | if (gc != np) { | ||
157 | gpiochip_base += GPIOS_PER_CHIP; | ||
158 | continue; | ||
159 | } | ||
160 | |||
161 | of_node_put(gc); | ||
162 | |||
163 | if (gpiochip_base >= ARCH_NR_GPIOS) | ||
164 | return -ENOSPC; | ||
165 | |||
166 | return gpiochip_base; | ||
167 | } | ||
168 | |||
169 | return -ENOENT; | ||
170 | } | ||
171 | |||
172 | /** | 140 | /** |
173 | * of_mm_gpiochip_add - Add memory mapped GPIO chip (bank) | 141 | * of_mm_gpiochip_add - Add memory mapped GPIO chip (bank) |
174 | * @np: device node of the GPIO chip | 142 | * @np: device node of the GPIO chip |
@@ -205,11 +173,7 @@ int of_mm_gpiochip_add(struct device_node *np, | |||
205 | if (!mm_gc->regs) | 173 | if (!mm_gc->regs) |
206 | goto err1; | 174 | goto err1; |
207 | 175 | ||
208 | gc->base = of_get_gpiochip_base(np); | 176 | gc->base = -1; |
209 | if (gc->base < 0) { | ||
210 | ret = gc->base; | ||
211 | goto err1; | ||
212 | } | ||
213 | 177 | ||
214 | if (!of_gc->xlate) | 178 | if (!of_gc->xlate) |
215 | of_gc->xlate = of_gpio_simple_xlate; | 179 | of_gc->xlate = of_gpio_simple_xlate; |
diff --git a/drivers/of/of_i2c.c b/drivers/of/of_i2c.c index b2ccdcbeb896..5c015d310d4a 100644 --- a/drivers/of/of_i2c.c +++ b/drivers/of/of_i2c.c | |||
@@ -13,6 +13,7 @@ | |||
13 | 13 | ||
14 | #include <linux/i2c.h> | 14 | #include <linux/i2c.h> |
15 | #include <linux/of.h> | 15 | #include <linux/of.h> |
16 | #include <linux/of_i2c.h> | ||
16 | #include <linux/module.h> | 17 | #include <linux/module.h> |
17 | 18 | ||
18 | struct i2c_driver_device { | 19 | struct i2c_driver_device { |
diff --git a/drivers/of/platform.c b/drivers/of/platform.c index ca09a63a64db..298de0f95d70 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c | |||
@@ -17,6 +17,8 @@ | |||
17 | #include <linux/of_device.h> | 17 | #include <linux/of_device.h> |
18 | #include <linux/of_platform.h> | 18 | #include <linux/of_platform.h> |
19 | 19 | ||
20 | extern struct device_attribute of_platform_device_attrs[]; | ||
21 | |||
20 | static int of_platform_bus_match(struct device *dev, struct device_driver *drv) | 22 | static int of_platform_bus_match(struct device *dev, struct device_driver *drv) |
21 | { | 23 | { |
22 | struct of_device *of_dev = to_of_device(dev); | 24 | struct of_device *of_dev = to_of_device(dev); |
@@ -103,6 +105,7 @@ int of_bus_type_init(struct bus_type *bus, const char *name) | |||
103 | bus->suspend = of_platform_device_suspend; | 105 | bus->suspend = of_platform_device_suspend; |
104 | bus->resume = of_platform_device_resume; | 106 | bus->resume = of_platform_device_resume; |
105 | bus->shutdown = of_platform_device_shutdown; | 107 | bus->shutdown = of_platform_device_shutdown; |
108 | bus->dev_attrs = of_platform_device_attrs; | ||
106 | return bus_register(bus); | 109 | return bus_register(bus); |
107 | } | 110 | } |
108 | 111 | ||
diff --git a/drivers/pcmcia/electra_cf.c b/drivers/pcmcia/electra_cf.c index 52d0aa8c2e7a..c21f9a9c3e3f 100644 --- a/drivers/pcmcia/electra_cf.c +++ b/drivers/pcmcia/electra_cf.c | |||
@@ -29,9 +29,9 @@ | |||
29 | #include <linux/delay.h> | 29 | #include <linux/delay.h> |
30 | #include <linux/interrupt.h> | 30 | #include <linux/interrupt.h> |
31 | #include <linux/vmalloc.h> | 31 | #include <linux/vmalloc.h> |
32 | #include <linux/of_platform.h> | ||
32 | 33 | ||
33 | #include <pcmcia/ss.h> | 34 | #include <pcmcia/ss.h> |
34 | #include <asm/of_platform.h> | ||
35 | 35 | ||
36 | static const char driver_name[] = "electra-cf"; | 36 | static const char driver_name[] = "electra-cf"; |
37 | 37 | ||
diff --git a/drivers/pcmcia/m8xx_pcmcia.c b/drivers/pcmcia/m8xx_pcmcia.c index 13a5fbd50a07..ff66604e90d4 100644 --- a/drivers/pcmcia/m8xx_pcmcia.c +++ b/drivers/pcmcia/m8xx_pcmcia.c | |||
@@ -49,6 +49,8 @@ | |||
49 | #include <linux/interrupt.h> | 49 | #include <linux/interrupt.h> |
50 | #include <linux/fsl_devices.h> | 50 | #include <linux/fsl_devices.h> |
51 | #include <linux/bitops.h> | 51 | #include <linux/bitops.h> |
52 | #include <linux/of_device.h> | ||
53 | #include <linux/of_platform.h> | ||
52 | 54 | ||
53 | #include <asm/io.h> | 55 | #include <asm/io.h> |
54 | #include <asm/system.h> | 56 | #include <asm/system.h> |
@@ -57,8 +59,6 @@ | |||
57 | #include <asm/8xx_immap.h> | 59 | #include <asm/8xx_immap.h> |
58 | #include <asm/irq.h> | 60 | #include <asm/irq.h> |
59 | #include <asm/fs_pd.h> | 61 | #include <asm/fs_pd.h> |
60 | #include <asm/of_device.h> | ||
61 | #include <asm/of_platform.h> | ||
62 | 62 | ||
63 | #include <pcmcia/cs_types.h> | 63 | #include <pcmcia/cs_types.h> |
64 | #include <pcmcia/cs.h> | 64 | #include <pcmcia/cs.h> |
diff --git a/drivers/serial/cpm_uart/cpm_uart.h b/drivers/serial/cpm_uart/cpm_uart.h index 0cc39f82d7c5..5c76e0ae0582 100644 --- a/drivers/serial/cpm_uart/cpm_uart.h +++ b/drivers/serial/cpm_uart/cpm_uart.h | |||
@@ -6,7 +6,7 @@ | |||
6 | * Copyright (C) 2004 Freescale Semiconductor, Inc. | 6 | * Copyright (C) 2004 Freescale Semiconductor, Inc. |
7 | * | 7 | * |
8 | * 2006 (c) MontaVista Software, Inc. | 8 | * 2006 (c) MontaVista Software, Inc. |
9 | * Vitaly Bordug <vbordug@ru.mvista.com> | 9 | * Vitaly Bordug <vbordug@ru.mvista.com> |
10 | * | 10 | * |
11 | * This file is licensed under the terms of the GNU General Public License | 11 | * This file is licensed under the terms of the GNU General Public License |
12 | * version 2. This program is licensed "as is" without any warranty of any | 12 | * version 2. This program is licensed "as is" without any warranty of any |
@@ -28,7 +28,7 @@ | |||
28 | #define SERIAL_CPM_MAJOR 204 | 28 | #define SERIAL_CPM_MAJOR 204 |
29 | #define SERIAL_CPM_MINOR 46 | 29 | #define SERIAL_CPM_MINOR 46 |
30 | 30 | ||
31 | #define IS_SMC(pinfo) (pinfo->flags & FLAG_SMC) | 31 | #define IS_SMC(pinfo) (pinfo->flags & FLAG_SMC) |
32 | #define IS_DISCARDING(pinfo) (pinfo->flags & FLAG_DISCARDING) | 32 | #define IS_DISCARDING(pinfo) (pinfo->flags & FLAG_DISCARDING) |
33 | #define FLAG_DISCARDING 0x00000004 /* when set, don't discard */ | 33 | #define FLAG_DISCARDING 0x00000004 /* when set, don't discard */ |
34 | #define FLAG_SMC 0x00000002 | 34 | #define FLAG_SMC 0x00000002 |
@@ -70,7 +70,7 @@ struct uart_cpm_port { | |||
70 | void (*set_lineif)(struct uart_cpm_port *); | 70 | void (*set_lineif)(struct uart_cpm_port *); |
71 | u8 brg; | 71 | u8 brg; |
72 | uint dp_addr; | 72 | uint dp_addr; |
73 | void *mem_addr; | 73 | void *mem_addr; |
74 | dma_addr_t dma_addr; | 74 | dma_addr_t dma_addr; |
75 | u32 mem_size; | 75 | u32 mem_size; |
76 | /* helpers */ | 76 | /* helpers */ |
@@ -79,14 +79,11 @@ struct uart_cpm_port { | |||
79 | /* Keep track of 'odd' SMC2 wirings */ | 79 | /* Keep track of 'odd' SMC2 wirings */ |
80 | int is_portb; | 80 | int is_portb; |
81 | /* wait on close if needed */ | 81 | /* wait on close if needed */ |
82 | int wait_closing; | 82 | int wait_closing; |
83 | /* value to combine with opcode to form cpm command */ | 83 | /* value to combine with opcode to form cpm command */ |
84 | u32 command; | 84 | u32 command; |
85 | }; | 85 | }; |
86 | 86 | ||
87 | #ifndef CONFIG_PPC_CPM_NEW_BINDING | ||
88 | extern int cpm_uart_port_map[UART_NR]; | ||
89 | #endif | ||
90 | extern int cpm_uart_nr; | 87 | extern int cpm_uart_nr; |
91 | extern struct uart_cpm_port cpm_uart_ports[UART_NR]; | 88 | extern struct uart_cpm_port cpm_uart_ports[UART_NR]; |
92 | 89 | ||
diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c index a19dc7ef8861..abe129cc927a 100644 --- a/drivers/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/serial/cpm_uart/cpm_uart_core.c | |||
@@ -13,7 +13,7 @@ | |||
13 | * Copyright (C) 2004, 2007 Freescale Semiconductor, Inc. | 13 | * Copyright (C) 2004, 2007 Freescale Semiconductor, Inc. |
14 | * (C) 2004 Intracom, S.A. | 14 | * (C) 2004 Intracom, S.A. |
15 | * (C) 2005-2006 MontaVista Software, Inc. | 15 | * (C) 2005-2006 MontaVista Software, Inc. |
16 | * Vitaly Bordug <vbordug@ru.mvista.com> | 16 | * Vitaly Bordug <vbordug@ru.mvista.com> |
17 | * | 17 | * |
18 | * This program is free software; you can redistribute it and/or modify | 18 | * This program is free software; you can redistribute it and/or modify |
19 | * it under the terms of the GNU General Public License as published by | 19 | * it under the terms of the GNU General Public License as published by |
@@ -42,6 +42,7 @@ | |||
42 | #include <linux/bootmem.h> | 42 | #include <linux/bootmem.h> |
43 | #include <linux/dma-mapping.h> | 43 | #include <linux/dma-mapping.h> |
44 | #include <linux/fs_uart_pd.h> | 44 | #include <linux/fs_uart_pd.h> |
45 | #include <linux/of_platform.h> | ||
45 | 46 | ||
46 | #include <asm/io.h> | 47 | #include <asm/io.h> |
47 | #include <asm/irq.h> | 48 | #include <asm/irq.h> |
@@ -49,10 +50,6 @@ | |||
49 | #include <asm/fs_pd.h> | 50 | #include <asm/fs_pd.h> |
50 | #include <asm/udbg.h> | 51 | #include <asm/udbg.h> |
51 | 52 | ||
52 | #ifdef CONFIG_PPC_CPM_NEW_BINDING | ||
53 | #include <linux/of_platform.h> | ||
54 | #endif | ||
55 | |||
56 | #if defined(CONFIG_SERIAL_CPM_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) | 53 | #if defined(CONFIG_SERIAL_CPM_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) |
57 | #define SUPPORT_SYSRQ | 54 | #define SUPPORT_SYSRQ |
58 | #endif | 55 | #endif |
@@ -72,59 +69,6 @@ static void cpm_uart_initbd(struct uart_cpm_port *pinfo); | |||
72 | 69 | ||
73 | /**************************************************************/ | 70 | /**************************************************************/ |
74 | 71 | ||
75 | #ifndef CONFIG_PPC_CPM_NEW_BINDING | ||
76 | /* Track which ports are configured as uarts */ | ||
77 | int cpm_uart_port_map[UART_NR]; | ||
78 | /* How many ports did we config as uarts */ | ||
79 | int cpm_uart_nr; | ||
80 | |||
81 | /* Place-holder for board-specific stuff */ | ||
82 | struct platform_device* __attribute__ ((weak)) __init | ||
83 | early_uart_get_pdev(int index) | ||
84 | { | ||
85 | return NULL; | ||
86 | } | ||
87 | |||
88 | |||
89 | static void cpm_uart_count(void) | ||
90 | { | ||
91 | cpm_uart_nr = 0; | ||
92 | #ifdef CONFIG_SERIAL_CPM_SMC1 | ||
93 | cpm_uart_port_map[cpm_uart_nr++] = UART_SMC1; | ||
94 | #endif | ||
95 | #ifdef CONFIG_SERIAL_CPM_SMC2 | ||
96 | cpm_uart_port_map[cpm_uart_nr++] = UART_SMC2; | ||
97 | #endif | ||
98 | #ifdef CONFIG_SERIAL_CPM_SCC1 | ||
99 | cpm_uart_port_map[cpm_uart_nr++] = UART_SCC1; | ||
100 | #endif | ||
101 | #ifdef CONFIG_SERIAL_CPM_SCC2 | ||
102 | cpm_uart_port_map[cpm_uart_nr++] = UART_SCC2; | ||
103 | #endif | ||
104 | #ifdef CONFIG_SERIAL_CPM_SCC3 | ||
105 | cpm_uart_port_map[cpm_uart_nr++] = UART_SCC3; | ||
106 | #endif | ||
107 | #ifdef CONFIG_SERIAL_CPM_SCC4 | ||
108 | cpm_uart_port_map[cpm_uart_nr++] = UART_SCC4; | ||
109 | #endif | ||
110 | } | ||
111 | |||
112 | /* Get UART number by its id */ | ||
113 | static int cpm_uart_id2nr(int id) | ||
114 | { | ||
115 | int i; | ||
116 | if (id < UART_NR) { | ||
117 | for (i=0; i<UART_NR; i++) { | ||
118 | if (cpm_uart_port_map[i] == id) | ||
119 | return i; | ||
120 | } | ||
121 | } | ||
122 | |||
123 | /* not found or invalid argument */ | ||
124 | return -1; | ||
125 | } | ||
126 | #endif | ||
127 | |||
128 | /* | 72 | /* |
129 | * Check, if transmit buffers are processed | 73 | * Check, if transmit buffers are processed |
130 | */ | 74 | */ |
@@ -547,6 +491,11 @@ static void cpm_uart_set_termios(struct uart_port *port, | |||
547 | } | 491 | } |
548 | 492 | ||
549 | /* | 493 | /* |
494 | * Update the timeout | ||
495 | */ | ||
496 | uart_update_timeout(port, termios->c_cflag, baud); | ||
497 | |||
498 | /* | ||
550 | * Set up parity check flag | 499 | * Set up parity check flag |
551 | */ | 500 | */ |
552 | #define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) | 501 | #define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) |
@@ -935,7 +884,6 @@ static struct uart_ops cpm_uart_pops = { | |||
935 | .verify_port = cpm_uart_verify_port, | 884 | .verify_port = cpm_uart_verify_port, |
936 | }; | 885 | }; |
937 | 886 | ||
938 | #ifdef CONFIG_PPC_CPM_NEW_BINDING | ||
939 | struct uart_cpm_port cpm_uart_ports[UART_NR]; | 887 | struct uart_cpm_port cpm_uart_ports[UART_NR]; |
940 | 888 | ||
941 | static int cpm_uart_init_port(struct device_node *np, | 889 | static int cpm_uart_init_port(struct device_node *np, |
@@ -995,6 +943,7 @@ static int cpm_uart_init_port(struct device_node *np, | |||
995 | pinfo->port.type = PORT_CPM; | 943 | pinfo->port.type = PORT_CPM; |
996 | pinfo->port.ops = &cpm_uart_pops, | 944 | pinfo->port.ops = &cpm_uart_pops, |
997 | pinfo->port.iotype = UPIO_MEM; | 945 | pinfo->port.iotype = UPIO_MEM; |
946 | pinfo->port.fifosize = pinfo->tx_nrfifos * pinfo->tx_fifosize; | ||
998 | spin_lock_init(&pinfo->port.lock); | 947 | spin_lock_init(&pinfo->port.lock); |
999 | 948 | ||
1000 | pinfo->port.irq = of_irq_to_resource(np, 0, NULL); | 949 | pinfo->port.irq = of_irq_to_resource(np, 0, NULL); |
@@ -1012,153 +961,6 @@ out_mem: | |||
1012 | return ret; | 961 | return ret; |
1013 | } | 962 | } |
1014 | 963 | ||
1015 | #else | ||
1016 | |||
1017 | struct uart_cpm_port cpm_uart_ports[UART_NR] = { | ||
1018 | [UART_SMC1] = { | ||
1019 | .port = { | ||
1020 | .irq = SMC1_IRQ, | ||
1021 | .ops = &cpm_uart_pops, | ||
1022 | .iotype = UPIO_MEM, | ||
1023 | .lock = __SPIN_LOCK_UNLOCKED(cpm_uart_ports[UART_SMC1].port.lock), | ||
1024 | }, | ||
1025 | .flags = FLAG_SMC, | ||
1026 | .tx_nrfifos = TX_NUM_FIFO, | ||
1027 | .tx_fifosize = TX_BUF_SIZE, | ||
1028 | .rx_nrfifos = RX_NUM_FIFO, | ||
1029 | .rx_fifosize = RX_BUF_SIZE, | ||
1030 | .set_lineif = smc1_lineif, | ||
1031 | }, | ||
1032 | [UART_SMC2] = { | ||
1033 | .port = { | ||
1034 | .irq = SMC2_IRQ, | ||
1035 | .ops = &cpm_uart_pops, | ||
1036 | .iotype = UPIO_MEM, | ||
1037 | .lock = __SPIN_LOCK_UNLOCKED(cpm_uart_ports[UART_SMC2].port.lock), | ||
1038 | }, | ||
1039 | .flags = FLAG_SMC, | ||
1040 | .tx_nrfifos = TX_NUM_FIFO, | ||
1041 | .tx_fifosize = TX_BUF_SIZE, | ||
1042 | .rx_nrfifos = RX_NUM_FIFO, | ||
1043 | .rx_fifosize = RX_BUF_SIZE, | ||
1044 | .set_lineif = smc2_lineif, | ||
1045 | #ifdef CONFIG_SERIAL_CPM_ALT_SMC2 | ||
1046 | .is_portb = 1, | ||
1047 | #endif | ||
1048 | }, | ||
1049 | [UART_SCC1] = { | ||
1050 | .port = { | ||
1051 | .irq = SCC1_IRQ, | ||
1052 | .ops = &cpm_uart_pops, | ||
1053 | .iotype = UPIO_MEM, | ||
1054 | .lock = __SPIN_LOCK_UNLOCKED(cpm_uart_ports[UART_SCC1].port.lock), | ||
1055 | }, | ||
1056 | .tx_nrfifos = TX_NUM_FIFO, | ||
1057 | .tx_fifosize = TX_BUF_SIZE, | ||
1058 | .rx_nrfifos = RX_NUM_FIFO, | ||
1059 | .rx_fifosize = RX_BUF_SIZE, | ||
1060 | .set_lineif = scc1_lineif, | ||
1061 | .wait_closing = SCC_WAIT_CLOSING, | ||
1062 | }, | ||
1063 | [UART_SCC2] = { | ||
1064 | .port = { | ||
1065 | .irq = SCC2_IRQ, | ||
1066 | .ops = &cpm_uart_pops, | ||
1067 | .iotype = UPIO_MEM, | ||
1068 | .lock = __SPIN_LOCK_UNLOCKED(cpm_uart_ports[UART_SCC2].port.lock), | ||
1069 | }, | ||
1070 | .tx_nrfifos = TX_NUM_FIFO, | ||
1071 | .tx_fifosize = TX_BUF_SIZE, | ||
1072 | .rx_nrfifos = RX_NUM_FIFO, | ||
1073 | .rx_fifosize = RX_BUF_SIZE, | ||
1074 | .set_lineif = scc2_lineif, | ||
1075 | .wait_closing = SCC_WAIT_CLOSING, | ||
1076 | }, | ||
1077 | [UART_SCC3] = { | ||
1078 | .port = { | ||
1079 | .irq = SCC3_IRQ, | ||
1080 | .ops = &cpm_uart_pops, | ||
1081 | .iotype = UPIO_MEM, | ||
1082 | .lock = __SPIN_LOCK_UNLOCKED(cpm_uart_ports[UART_SCC3].port.lock), | ||
1083 | }, | ||
1084 | .tx_nrfifos = TX_NUM_FIFO, | ||
1085 | .tx_fifosize = TX_BUF_SIZE, | ||
1086 | .rx_nrfifos = RX_NUM_FIFO, | ||
1087 | .rx_fifosize = RX_BUF_SIZE, | ||
1088 | .set_lineif = scc3_lineif, | ||
1089 | .wait_closing = SCC_WAIT_CLOSING, | ||
1090 | }, | ||
1091 | [UART_SCC4] = { | ||
1092 | .port = { | ||
1093 | .irq = SCC4_IRQ, | ||
1094 | .ops = &cpm_uart_pops, | ||
1095 | .iotype = UPIO_MEM, | ||
1096 | .lock = __SPIN_LOCK_UNLOCKED(cpm_uart_ports[UART_SCC4].port.lock), | ||
1097 | }, | ||
1098 | .tx_nrfifos = TX_NUM_FIFO, | ||
1099 | .tx_fifosize = TX_BUF_SIZE, | ||
1100 | .rx_nrfifos = RX_NUM_FIFO, | ||
1101 | .rx_fifosize = RX_BUF_SIZE, | ||
1102 | .set_lineif = scc4_lineif, | ||
1103 | .wait_closing = SCC_WAIT_CLOSING, | ||
1104 | }, | ||
1105 | }; | ||
1106 | |||
1107 | int cpm_uart_drv_get_platform_data(struct platform_device *pdev, int is_con) | ||
1108 | { | ||
1109 | struct resource *r; | ||
1110 | struct fs_uart_platform_info *pdata = pdev->dev.platform_data; | ||
1111 | int idx; /* It is UART_SMCx or UART_SCCx index */ | ||
1112 | struct uart_cpm_port *pinfo; | ||
1113 | int line; | ||
1114 | u32 mem, pram; | ||
1115 | |||
1116 | idx = pdata->fs_no = fs_uart_get_id(pdata); | ||
1117 | |||
1118 | line = cpm_uart_id2nr(idx); | ||
1119 | if(line < 0) { | ||
1120 | printk(KERN_ERR"%s(): port %d is not registered", __func__, idx); | ||
1121 | return -EINVAL; | ||
1122 | } | ||
1123 | |||
1124 | pinfo = (struct uart_cpm_port *) &cpm_uart_ports[idx]; | ||
1125 | |||
1126 | pinfo->brg = pdata->brg; | ||
1127 | |||
1128 | if (!is_con) { | ||
1129 | pinfo->port.line = line; | ||
1130 | pinfo->port.flags = UPF_BOOT_AUTOCONF; | ||
1131 | } | ||
1132 | |||
1133 | if (!(r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs"))) | ||
1134 | return -EINVAL; | ||
1135 | mem = (u32)ioremap(r->start, r->end - r->start + 1); | ||
1136 | |||
1137 | if (!(r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pram"))) | ||
1138 | return -EINVAL; | ||
1139 | pram = (u32)ioremap(r->start, r->end - r->start + 1); | ||
1140 | |||
1141 | if(idx > fsid_smc2_uart) { | ||
1142 | pinfo->sccp = (scc_t *)mem; | ||
1143 | pinfo->sccup = (scc_uart_t *)pram; | ||
1144 | } else { | ||
1145 | pinfo->smcp = (smc_t *)mem; | ||
1146 | pinfo->smcup = (smc_uart_t *)pram; | ||
1147 | } | ||
1148 | pinfo->tx_nrfifos = pdata->tx_num_fifo; | ||
1149 | pinfo->tx_fifosize = pdata->tx_buf_size; | ||
1150 | |||
1151 | pinfo->rx_nrfifos = pdata->rx_num_fifo; | ||
1152 | pinfo->rx_fifosize = pdata->rx_buf_size; | ||
1153 | |||
1154 | pinfo->port.uartclk = pdata->uart_clk; | ||
1155 | pinfo->port.mapbase = (unsigned long)mem; | ||
1156 | pinfo->port.irq = platform_get_irq(pdev, 0); | ||
1157 | |||
1158 | return 0; | ||
1159 | } | ||
1160 | #endif | ||
1161 | |||
1162 | #ifdef CONFIG_SERIAL_CPM_CONSOLE | 964 | #ifdef CONFIG_SERIAL_CPM_CONSOLE |
1163 | /* | 965 | /* |
1164 | * Print a string to the serial port trying not to disturb | 966 | * Print a string to the serial port trying not to disturb |
@@ -1169,15 +971,18 @@ int cpm_uart_drv_get_platform_data(struct platform_device *pdev, int is_con) | |||
1169 | static void cpm_uart_console_write(struct console *co, const char *s, | 971 | static void cpm_uart_console_write(struct console *co, const char *s, |
1170 | u_int count) | 972 | u_int count) |
1171 | { | 973 | { |
1172 | #ifdef CONFIG_PPC_CPM_NEW_BINDING | ||
1173 | struct uart_cpm_port *pinfo = &cpm_uart_ports[co->index]; | 974 | struct uart_cpm_port *pinfo = &cpm_uart_ports[co->index]; |
1174 | #else | ||
1175 | struct uart_cpm_port *pinfo = | ||
1176 | &cpm_uart_ports[cpm_uart_port_map[co->index]]; | ||
1177 | #endif | ||
1178 | unsigned int i; | 975 | unsigned int i; |
1179 | cbd_t __iomem *bdp, *bdbase; | 976 | cbd_t __iomem *bdp, *bdbase; |
1180 | unsigned char *cp; | 977 | unsigned char *cp; |
978 | unsigned long flags; | ||
979 | int nolock = oops_in_progress; | ||
980 | |||
981 | if (unlikely(nolock)) { | ||
982 | local_irq_save(flags); | ||
983 | } else { | ||
984 | spin_lock_irqsave(&pinfo->port.lock, flags); | ||
985 | } | ||
1181 | 986 | ||
1182 | /* Get the address of the host memory buffer. | 987 | /* Get the address of the host memory buffer. |
1183 | */ | 988 | */ |
@@ -1239,6 +1044,12 @@ static void cpm_uart_console_write(struct console *co, const char *s, | |||
1239 | ; | 1044 | ; |
1240 | 1045 | ||
1241 | pinfo->tx_cur = bdp; | 1046 | pinfo->tx_cur = bdp; |
1047 | |||
1048 | if (unlikely(nolock)) { | ||
1049 | local_irq_restore(flags); | ||
1050 | } else { | ||
1051 | spin_unlock_irqrestore(&pinfo->port.lock, flags); | ||
1052 | } | ||
1242 | } | 1053 | } |
1243 | 1054 | ||
1244 | 1055 | ||
@@ -1252,7 +1063,6 @@ static int __init cpm_uart_console_setup(struct console *co, char *options) | |||
1252 | struct uart_cpm_port *pinfo; | 1063 | struct uart_cpm_port *pinfo; |
1253 | struct uart_port *port; | 1064 | struct uart_port *port; |
1254 | 1065 | ||
1255 | #ifdef CONFIG_PPC_CPM_NEW_BINDING | ||
1256 | struct device_node *np = NULL; | 1066 | struct device_node *np = NULL; |
1257 | int i = 0; | 1067 | int i = 0; |
1258 | 1068 | ||
@@ -1284,35 +1094,6 @@ static int __init cpm_uart_console_setup(struct console *co, char *options) | |||
1284 | if (ret) | 1094 | if (ret) |
1285 | return ret; | 1095 | return ret; |
1286 | 1096 | ||
1287 | #else | ||
1288 | |||
1289 | struct fs_uart_platform_info *pdata; | ||
1290 | struct platform_device* pdev = early_uart_get_pdev(co->index); | ||
1291 | |||
1292 | if (!pdev) { | ||
1293 | pr_info("cpm_uart: console: compat mode\n"); | ||
1294 | /* compatibility - will be cleaned up */ | ||
1295 | cpm_uart_init_portdesc(); | ||
1296 | } | ||
1297 | |||
1298 | port = | ||
1299 | (struct uart_port *)&cpm_uart_ports[cpm_uart_port_map[co->index]]; | ||
1300 | pinfo = (struct uart_cpm_port *)port; | ||
1301 | if (!pdev) { | ||
1302 | if (pinfo->set_lineif) | ||
1303 | pinfo->set_lineif(pinfo); | ||
1304 | } else { | ||
1305 | pdata = pdev->dev.platform_data; | ||
1306 | if (pdata) | ||
1307 | if (pdata->init_ioports) | ||
1308 | pdata->init_ioports(pdata); | ||
1309 | |||
1310 | cpm_uart_drv_get_platform_data(pdev, 1); | ||
1311 | } | ||
1312 | |||
1313 | pinfo->flags |= FLAG_CONSOLE; | ||
1314 | #endif | ||
1315 | |||
1316 | if (options) { | 1097 | if (options) { |
1317 | uart_parse_options(options, &baud, &parity, &bits, &flow); | 1098 | uart_parse_options(options, &baud, &parity, &bits, &flow); |
1318 | } else { | 1099 | } else { |
@@ -1386,7 +1167,6 @@ static struct uart_driver cpm_reg = { | |||
1386 | .nr = UART_NR, | 1167 | .nr = UART_NR, |
1387 | }; | 1168 | }; |
1388 | 1169 | ||
1389 | #ifdef CONFIG_PPC_CPM_NEW_BINDING | ||
1390 | static int probe_index; | 1170 | static int probe_index; |
1391 | 1171 | ||
1392 | static int __devinit cpm_uart_probe(struct of_device *ofdev, | 1172 | static int __devinit cpm_uart_probe(struct of_device *ofdev, |
@@ -1457,135 +1237,6 @@ static void __exit cpm_uart_exit(void) | |||
1457 | of_unregister_platform_driver(&cpm_uart_driver); | 1237 | of_unregister_platform_driver(&cpm_uart_driver); |
1458 | uart_unregister_driver(&cpm_reg); | 1238 | uart_unregister_driver(&cpm_reg); |
1459 | } | 1239 | } |
1460 | #else | ||
1461 | static int cpm_uart_drv_probe(struct device *dev) | ||
1462 | { | ||
1463 | struct platform_device *pdev = to_platform_device(dev); | ||
1464 | struct fs_uart_platform_info *pdata; | ||
1465 | int ret = -ENODEV; | ||
1466 | |||
1467 | if(!pdev) { | ||
1468 | printk(KERN_ERR"CPM UART: platform data missing!\n"); | ||
1469 | return ret; | ||
1470 | } | ||
1471 | |||
1472 | pdata = pdev->dev.platform_data; | ||
1473 | |||
1474 | if ((ret = cpm_uart_drv_get_platform_data(pdev, 0))) | ||
1475 | return ret; | ||
1476 | |||
1477 | pr_debug("cpm_uart_drv_probe: Adding CPM UART %d\n", cpm_uart_id2nr(pdata->fs_no)); | ||
1478 | |||
1479 | if (pdata->init_ioports) | ||
1480 | pdata->init_ioports(pdata); | ||
1481 | |||
1482 | ret = uart_add_one_port(&cpm_reg, &cpm_uart_ports[pdata->fs_no].port); | ||
1483 | |||
1484 | return ret; | ||
1485 | } | ||
1486 | |||
1487 | static int cpm_uart_drv_remove(struct device *dev) | ||
1488 | { | ||
1489 | struct platform_device *pdev = to_platform_device(dev); | ||
1490 | struct fs_uart_platform_info *pdata = pdev->dev.platform_data; | ||
1491 | |||
1492 | pr_debug("cpm_uart_drv_remove: Removing CPM UART %d\n", | ||
1493 | cpm_uart_id2nr(pdata->fs_no)); | ||
1494 | |||
1495 | uart_remove_one_port(&cpm_reg, &cpm_uart_ports[pdata->fs_no].port); | ||
1496 | return 0; | ||
1497 | } | ||
1498 | |||
1499 | static struct device_driver cpm_smc_uart_driver = { | ||
1500 | .name = "fsl-cpm-smc:uart", | ||
1501 | .bus = &platform_bus_type, | ||
1502 | .probe = cpm_uart_drv_probe, | ||
1503 | .remove = cpm_uart_drv_remove, | ||
1504 | }; | ||
1505 | |||
1506 | static struct device_driver cpm_scc_uart_driver = { | ||
1507 | .name = "fsl-cpm-scc:uart", | ||
1508 | .bus = &platform_bus_type, | ||
1509 | .probe = cpm_uart_drv_probe, | ||
1510 | .remove = cpm_uart_drv_remove, | ||
1511 | }; | ||
1512 | |||
1513 | /* | ||
1514 | This is supposed to match uart devices on platform bus, | ||
1515 | */ | ||
1516 | static int match_is_uart (struct device* dev, void* data) | ||
1517 | { | ||
1518 | struct platform_device* pdev = container_of(dev, struct platform_device, dev); | ||
1519 | int ret = 0; | ||
1520 | /* this was setfunc as uart */ | ||
1521 | if(strstr(pdev->name,":uart")) { | ||
1522 | ret = 1; | ||
1523 | } | ||
1524 | return ret; | ||
1525 | } | ||
1526 | |||
1527 | |||
1528 | static int cpm_uart_init(void) { | ||
1529 | |||
1530 | int ret; | ||
1531 | int i; | ||
1532 | struct device *dev; | ||
1533 | printk(KERN_INFO "Serial: CPM driver $Revision: 0.02 $\n"); | ||
1534 | |||
1535 | /* lookup the bus for uart devices */ | ||
1536 | dev = bus_find_device(&platform_bus_type, NULL, 0, match_is_uart); | ||
1537 | |||
1538 | /* There are devices on the bus - all should be OK */ | ||
1539 | if (dev) { | ||
1540 | cpm_uart_count(); | ||
1541 | cpm_reg.nr = cpm_uart_nr; | ||
1542 | |||
1543 | if (!(ret = uart_register_driver(&cpm_reg))) { | ||
1544 | if ((ret = driver_register(&cpm_smc_uart_driver))) { | ||
1545 | uart_unregister_driver(&cpm_reg); | ||
1546 | return ret; | ||
1547 | } | ||
1548 | if ((ret = driver_register(&cpm_scc_uart_driver))) { | ||
1549 | driver_unregister(&cpm_scc_uart_driver); | ||
1550 | uart_unregister_driver(&cpm_reg); | ||
1551 | } | ||
1552 | } | ||
1553 | } else { | ||
1554 | /* No capable platform devices found - falling back to legacy mode */ | ||
1555 | pr_info("cpm_uart: WARNING: no UART devices found on platform bus!\n"); | ||
1556 | pr_info( | ||
1557 | "cpm_uart: the driver will guess configuration, but this mode is no longer supported.\n"); | ||
1558 | |||
1559 | /* Don't run this again, if the console driver did it already */ | ||
1560 | if (cpm_uart_nr == 0) | ||
1561 | cpm_uart_init_portdesc(); | ||
1562 | |||
1563 | cpm_reg.nr = cpm_uart_nr; | ||
1564 | ret = uart_register_driver(&cpm_reg); | ||
1565 | |||
1566 | if (ret) | ||
1567 | return ret; | ||
1568 | |||
1569 | for (i = 0; i < cpm_uart_nr; i++) { | ||
1570 | int con = cpm_uart_port_map[i]; | ||
1571 | cpm_uart_ports[con].port.line = i; | ||
1572 | cpm_uart_ports[con].port.flags = UPF_BOOT_AUTOCONF; | ||
1573 | if (cpm_uart_ports[con].set_lineif) | ||
1574 | cpm_uart_ports[con].set_lineif(&cpm_uart_ports[con]); | ||
1575 | uart_add_one_port(&cpm_reg, &cpm_uart_ports[con].port); | ||
1576 | } | ||
1577 | |||
1578 | } | ||
1579 | return ret; | ||
1580 | } | ||
1581 | |||
1582 | static void __exit cpm_uart_exit(void) | ||
1583 | { | ||
1584 | driver_unregister(&cpm_scc_uart_driver); | ||
1585 | driver_unregister(&cpm_smc_uart_driver); | ||
1586 | uart_unregister_driver(&cpm_reg); | ||
1587 | } | ||
1588 | #endif | ||
1589 | 1240 | ||
1590 | module_init(cpm_uart_init); | 1241 | module_init(cpm_uart_init); |
1591 | module_exit(cpm_uart_exit); | 1242 | module_exit(cpm_uart_exit); |
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm1.c b/drivers/serial/cpm_uart/cpm_uart_cpm1.c index 74f1432bb248..0f0aff06c596 100644 --- a/drivers/serial/cpm_uart/cpm_uart_cpm1.c +++ b/drivers/serial/cpm_uart/cpm_uart_cpm1.c | |||
@@ -9,7 +9,7 @@ | |||
9 | * Copyright (C) 2004 Freescale Semiconductor, Inc. | 9 | * Copyright (C) 2004 Freescale Semiconductor, Inc. |
10 | * (C) 2004 Intracom, S.A. | 10 | * (C) 2004 Intracom, S.A. |
11 | * (C) 2006 MontaVista Software, Inc. | 11 | * (C) 2006 MontaVista Software, Inc. |
12 | * Vitaly Bordug <vbordug@ru.mvista.com> | 12 | * Vitaly Bordug <vbordug@ru.mvista.com> |
13 | * | 13 | * |
14 | * This program is free software; you can redistribute it and/or modify | 14 | * This program is free software; you can redistribute it and/or modify |
15 | * it under the terms of the GNU General Public License as published by | 15 | * it under the terms of the GNU General Public License as published by |
@@ -51,7 +51,6 @@ | |||
51 | 51 | ||
52 | /**************************************************************/ | 52 | /**************************************************************/ |
53 | 53 | ||
54 | #ifdef CONFIG_PPC_CPM_NEW_BINDING | ||
55 | void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd) | 54 | void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd) |
56 | { | 55 | { |
57 | cpm_command(port->command, cmd); | 56 | cpm_command(port->command, cmd); |
@@ -68,75 +67,6 @@ void cpm_uart_unmap_pram(struct uart_cpm_port *port, void __iomem *pram) | |||
68 | iounmap(pram); | 67 | iounmap(pram); |
69 | } | 68 | } |
70 | 69 | ||
71 | #else | ||
72 | void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd) | ||
73 | { | ||
74 | ushort val; | ||
75 | int line = port - cpm_uart_ports; | ||
76 | volatile cpm8xx_t *cp = cpmp; | ||
77 | |||
78 | switch (line) { | ||
79 | case UART_SMC1: | ||
80 | val = mk_cr_cmd(CPM_CR_CH_SMC1, cmd) | CPM_CR_FLG; | ||
81 | break; | ||
82 | case UART_SMC2: | ||
83 | val = mk_cr_cmd(CPM_CR_CH_SMC2, cmd) | CPM_CR_FLG; | ||
84 | break; | ||
85 | case UART_SCC1: | ||
86 | val = mk_cr_cmd(CPM_CR_CH_SCC1, cmd) | CPM_CR_FLG; | ||
87 | break; | ||
88 | case UART_SCC2: | ||
89 | val = mk_cr_cmd(CPM_CR_CH_SCC2, cmd) | CPM_CR_FLG; | ||
90 | break; | ||
91 | case UART_SCC3: | ||
92 | val = mk_cr_cmd(CPM_CR_CH_SCC3, cmd) | CPM_CR_FLG; | ||
93 | break; | ||
94 | case UART_SCC4: | ||
95 | val = mk_cr_cmd(CPM_CR_CH_SCC4, cmd) | CPM_CR_FLG; | ||
96 | break; | ||
97 | default: | ||
98 | return; | ||
99 | |||
100 | } | ||
101 | cp->cp_cpcr = val; | ||
102 | while (cp->cp_cpcr & CPM_CR_FLG) ; | ||
103 | } | ||
104 | |||
105 | void smc1_lineif(struct uart_cpm_port *pinfo) | ||
106 | { | ||
107 | pinfo->brg = 1; | ||
108 | } | ||
109 | |||
110 | void smc2_lineif(struct uart_cpm_port *pinfo) | ||
111 | { | ||
112 | pinfo->brg = 2; | ||
113 | } | ||
114 | |||
115 | void scc1_lineif(struct uart_cpm_port *pinfo) | ||
116 | { | ||
117 | /* XXX SCC1: insert port configuration here */ | ||
118 | pinfo->brg = 1; | ||
119 | } | ||
120 | |||
121 | void scc2_lineif(struct uart_cpm_port *pinfo) | ||
122 | { | ||
123 | /* XXX SCC2: insert port configuration here */ | ||
124 | pinfo->brg = 2; | ||
125 | } | ||
126 | |||
127 | void scc3_lineif(struct uart_cpm_port *pinfo) | ||
128 | { | ||
129 | /* XXX SCC3: insert port configuration here */ | ||
130 | pinfo->brg = 3; | ||
131 | } | ||
132 | |||
133 | void scc4_lineif(struct uart_cpm_port *pinfo) | ||
134 | { | ||
135 | /* XXX SCC4: insert port configuration here */ | ||
136 | pinfo->brg = 4; | ||
137 | } | ||
138 | #endif | ||
139 | |||
140 | /* | 70 | /* |
141 | * Allocate DP-Ram and memory buffers. We need to allocate a transmit and | 71 | * Allocate DP-Ram and memory buffers. We need to allocate a transmit and |
142 | * receive buffer descriptors from dual port ram, and a character | 72 | * receive buffer descriptors from dual port ram, and a character |
@@ -205,101 +135,3 @@ void cpm_uart_freebuf(struct uart_cpm_port *pinfo) | |||
205 | 135 | ||
206 | cpm_dpfree(pinfo->dp_addr); | 136 | cpm_dpfree(pinfo->dp_addr); |
207 | } | 137 | } |
208 | |||
209 | #ifndef CONFIG_PPC_CPM_NEW_BINDING | ||
210 | /* Setup any dynamic params in the uart desc */ | ||
211 | int cpm_uart_init_portdesc(void) | ||
212 | { | ||
213 | pr_debug("CPM uart[-]:init portdesc\n"); | ||
214 | |||
215 | cpm_uart_nr = 0; | ||
216 | #ifdef CONFIG_SERIAL_CPM_SMC1 | ||
217 | cpm_uart_ports[UART_SMC1].smcp = &cpmp->cp_smc[0]; | ||
218 | /* | ||
219 | * Is SMC1 being relocated? | ||
220 | */ | ||
221 | # ifdef CONFIG_I2C_SPI_SMC1_UCODE_PATCH | ||
222 | cpm_uart_ports[UART_SMC1].smcup = | ||
223 | (smc_uart_t *) & cpmp->cp_dparam[0x3C0]; | ||
224 | # else | ||
225 | cpm_uart_ports[UART_SMC1].smcup = | ||
226 | (smc_uart_t *) & cpmp->cp_dparam[PROFF_SMC1]; | ||
227 | # endif | ||
228 | cpm_uart_ports[UART_SMC1].port.mapbase = | ||
229 | (unsigned long)&cpmp->cp_smc[0]; | ||
230 | cpm_uart_ports[UART_SMC1].smcp->smc_smcm |= (SMCM_RX | SMCM_TX); | ||
231 | cpm_uart_ports[UART_SMC1].smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); | ||
232 | cpm_uart_ports[UART_SMC1].port.uartclk = uart_clock(); | ||
233 | cpm_uart_port_map[cpm_uart_nr++] = UART_SMC1; | ||
234 | #endif | ||
235 | |||
236 | #ifdef CONFIG_SERIAL_CPM_SMC2 | ||
237 | cpm_uart_ports[UART_SMC2].smcp = &cpmp->cp_smc[1]; | ||
238 | cpm_uart_ports[UART_SMC2].smcup = | ||
239 | (smc_uart_t *) & cpmp->cp_dparam[PROFF_SMC2]; | ||
240 | cpm_uart_ports[UART_SMC2].port.mapbase = | ||
241 | (unsigned long)&cpmp->cp_smc[1]; | ||
242 | cpm_uart_ports[UART_SMC2].smcp->smc_smcm |= (SMCM_RX | SMCM_TX); | ||
243 | cpm_uart_ports[UART_SMC2].smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); | ||
244 | cpm_uart_ports[UART_SMC2].port.uartclk = uart_clock(); | ||
245 | cpm_uart_port_map[cpm_uart_nr++] = UART_SMC2; | ||
246 | #endif | ||
247 | |||
248 | #ifdef CONFIG_SERIAL_CPM_SCC1 | ||
249 | cpm_uart_ports[UART_SCC1].sccp = &cpmp->cp_scc[0]; | ||
250 | cpm_uart_ports[UART_SCC1].sccup = | ||
251 | (scc_uart_t *) & cpmp->cp_dparam[PROFF_SCC1]; | ||
252 | cpm_uart_ports[UART_SCC1].port.mapbase = | ||
253 | (unsigned long)&cpmp->cp_scc[0]; | ||
254 | cpm_uart_ports[UART_SCC1].sccp->scc_sccm &= | ||
255 | ~(UART_SCCM_TX | UART_SCCM_RX); | ||
256 | cpm_uart_ports[UART_SCC1].sccp->scc_gsmrl &= | ||
257 | ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); | ||
258 | cpm_uart_ports[UART_SCC1].port.uartclk = uart_clock(); | ||
259 | cpm_uart_port_map[cpm_uart_nr++] = UART_SCC1; | ||
260 | #endif | ||
261 | |||
262 | #ifdef CONFIG_SERIAL_CPM_SCC2 | ||
263 | cpm_uart_ports[UART_SCC2].sccp = &cpmp->cp_scc[1]; | ||
264 | cpm_uart_ports[UART_SCC2].sccup = | ||
265 | (scc_uart_t *) & cpmp->cp_dparam[PROFF_SCC2]; | ||
266 | cpm_uart_ports[UART_SCC2].port.mapbase = | ||
267 | (unsigned long)&cpmp->cp_scc[1]; | ||
268 | cpm_uart_ports[UART_SCC2].sccp->scc_sccm &= | ||
269 | ~(UART_SCCM_TX | UART_SCCM_RX); | ||
270 | cpm_uart_ports[UART_SCC2].sccp->scc_gsmrl &= | ||
271 | ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); | ||
272 | cpm_uart_ports[UART_SCC2].port.uartclk = uart_clock(); | ||
273 | cpm_uart_port_map[cpm_uart_nr++] = UART_SCC2; | ||
274 | #endif | ||
275 | |||
276 | #ifdef CONFIG_SERIAL_CPM_SCC3 | ||
277 | cpm_uart_ports[UART_SCC3].sccp = &cpmp->cp_scc[2]; | ||
278 | cpm_uart_ports[UART_SCC3].sccup = | ||
279 | (scc_uart_t *) & cpmp->cp_dparam[PROFF_SCC3]; | ||
280 | cpm_uart_ports[UART_SCC3].port.mapbase = | ||
281 | (unsigned long)&cpmp->cp_scc[2]; | ||
282 | cpm_uart_ports[UART_SCC3].sccp->scc_sccm &= | ||
283 | ~(UART_SCCM_TX | UART_SCCM_RX); | ||
284 | cpm_uart_ports[UART_SCC3].sccp->scc_gsmrl &= | ||
285 | ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); | ||
286 | cpm_uart_ports[UART_SCC3].port.uartclk = uart_clock(); | ||
287 | cpm_uart_port_map[cpm_uart_nr++] = UART_SCC3; | ||
288 | #endif | ||
289 | |||
290 | #ifdef CONFIG_SERIAL_CPM_SCC4 | ||
291 | cpm_uart_ports[UART_SCC4].sccp = &cpmp->cp_scc[3]; | ||
292 | cpm_uart_ports[UART_SCC4].sccup = | ||
293 | (scc_uart_t *) & cpmp->cp_dparam[PROFF_SCC4]; | ||
294 | cpm_uart_ports[UART_SCC4].port.mapbase = | ||
295 | (unsigned long)&cpmp->cp_scc[3]; | ||
296 | cpm_uart_ports[UART_SCC4].sccp->scc_sccm &= | ||
297 | ~(UART_SCCM_TX | UART_SCCM_RX); | ||
298 | cpm_uart_ports[UART_SCC4].sccp->scc_gsmrl &= | ||
299 | ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); | ||
300 | cpm_uart_ports[UART_SCC4].port.uartclk = uart_clock(); | ||
301 | cpm_uart_port_map[cpm_uart_nr++] = UART_SCC4; | ||
302 | #endif | ||
303 | return 0; | ||
304 | } | ||
305 | #endif | ||
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm1.h b/drivers/serial/cpm_uart/cpm_uart_cpm1.h index ddf46d3c964b..10eecd6af6d4 100644 --- a/drivers/serial/cpm_uart/cpm_uart_cpm1.h +++ b/drivers/serial/cpm_uart/cpm_uart_cpm1.h | |||
@@ -2,7 +2,7 @@ | |||
2 | * linux/drivers/serial/cpm_uart/cpm_uart_cpm1.h | 2 | * linux/drivers/serial/cpm_uart/cpm_uart_cpm1.h |
3 | * | 3 | * |
4 | * Driver for CPM (SCC/SMC) serial ports | 4 | * Driver for CPM (SCC/SMC) serial ports |
5 | * | 5 | * |
6 | * definitions for cpm1 | 6 | * definitions for cpm1 |
7 | * | 7 | * |
8 | */ | 8 | */ |
@@ -12,16 +12,6 @@ | |||
12 | 12 | ||
13 | #include <asm/cpm1.h> | 13 | #include <asm/cpm1.h> |
14 | 14 | ||
15 | /* defines for IRQs */ | ||
16 | #ifndef CONFIG_PPC_CPM_NEW_BINDING | ||
17 | #define SMC1_IRQ (CPM_IRQ_OFFSET + CPMVEC_SMC1) | ||
18 | #define SMC2_IRQ (CPM_IRQ_OFFSET + CPMVEC_SMC2) | ||
19 | #define SCC1_IRQ (CPM_IRQ_OFFSET + CPMVEC_SCC1) | ||
20 | #define SCC2_IRQ (CPM_IRQ_OFFSET + CPMVEC_SCC2) | ||
21 | #define SCC3_IRQ (CPM_IRQ_OFFSET + CPMVEC_SCC3) | ||
22 | #define SCC4_IRQ (CPM_IRQ_OFFSET + CPMVEC_SCC4) | ||
23 | #endif | ||
24 | |||
25 | static inline void cpm_set_brg(int brg, int baud) | 15 | static inline void cpm_set_brg(int brg, int baud) |
26 | { | 16 | { |
27 | cpm_setbrg(brg, baud); | 17 | cpm_setbrg(brg, baud); |
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm2.c b/drivers/serial/cpm_uart/cpm_uart_cpm2.c index bb862e2f54cf..b8db4d3eed36 100644 --- a/drivers/serial/cpm_uart/cpm_uart_cpm2.c +++ b/drivers/serial/cpm_uart/cpm_uart_cpm2.c | |||
@@ -5,11 +5,11 @@ | |||
5 | * | 5 | * |
6 | * Maintainer: Kumar Gala (galak@kernel.crashing.org) (CPM2) | 6 | * Maintainer: Kumar Gala (galak@kernel.crashing.org) (CPM2) |
7 | * Pantelis Antoniou (panto@intracom.gr) (CPM1) | 7 | * Pantelis Antoniou (panto@intracom.gr) (CPM1) |
8 | * | 8 | * |
9 | * Copyright (C) 2004 Freescale Semiconductor, Inc. | 9 | * Copyright (C) 2004 Freescale Semiconductor, Inc. |
10 | * (C) 2004 Intracom, S.A. | 10 | * (C) 2004 Intracom, S.A. |
11 | * (C) 2006 MontaVista Software, Inc. | 11 | * (C) 2006 MontaVista Software, Inc. |
12 | * Vitaly Bordug <vbordug@ru.mvista.com> | 12 | * Vitaly Bordug <vbordug@ru.mvista.com> |
13 | * | 13 | * |
14 | * This program is free software; you can redistribute it and/or modify | 14 | * This program is free software; you can redistribute it and/or modify |
15 | * it under the terms of the GNU General Public License as published by | 15 | * it under the terms of the GNU General Public License as published by |
@@ -41,9 +41,7 @@ | |||
41 | #include <asm/io.h> | 41 | #include <asm/io.h> |
42 | #include <asm/irq.h> | 42 | #include <asm/irq.h> |
43 | #include <asm/fs_pd.h> | 43 | #include <asm/fs_pd.h> |
44 | #ifdef CONFIG_PPC_CPM_NEW_BINDING | ||
45 | #include <asm/prom.h> | 44 | #include <asm/prom.h> |
46 | #endif | ||
47 | 45 | ||
48 | #include <linux/serial_core.h> | 46 | #include <linux/serial_core.h> |
49 | #include <linux/kernel.h> | 47 | #include <linux/kernel.h> |
@@ -52,7 +50,6 @@ | |||
52 | 50 | ||
53 | /**************************************************************/ | 51 | /**************************************************************/ |
54 | 52 | ||
55 | #ifdef CONFIG_PPC_CPM_NEW_BINDING | ||
56 | void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd) | 53 | void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd) |
57 | { | 54 | { |
58 | cpm_command(port->command, cmd); | 55 | cpm_command(port->command, cmd); |
@@ -106,174 +103,8 @@ void cpm_uart_unmap_pram(struct uart_cpm_port *port, void __iomem *pram) | |||
106 | iounmap(pram); | 103 | iounmap(pram); |
107 | } | 104 | } |
108 | 105 | ||
109 | #else | ||
110 | void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd) | ||
111 | { | ||
112 | ulong val; | ||
113 | int line = port - cpm_uart_ports; | ||
114 | volatile cpm_cpm2_t *cp = cpm2_map(im_cpm); | ||
115 | |||
116 | |||
117 | switch (line) { | ||
118 | case UART_SMC1: | ||
119 | val = mk_cr_cmd(CPM_CR_SMC1_PAGE, CPM_CR_SMC1_SBLOCK, 0, | ||
120 | cmd) | CPM_CR_FLG; | ||
121 | break; | ||
122 | case UART_SMC2: | ||
123 | val = mk_cr_cmd(CPM_CR_SMC2_PAGE, CPM_CR_SMC2_SBLOCK, 0, | ||
124 | cmd) | CPM_CR_FLG; | ||
125 | break; | ||
126 | case UART_SCC1: | ||
127 | val = mk_cr_cmd(CPM_CR_SCC1_PAGE, CPM_CR_SCC1_SBLOCK, 0, | ||
128 | cmd) | CPM_CR_FLG; | ||
129 | break; | ||
130 | case UART_SCC2: | ||
131 | val = mk_cr_cmd(CPM_CR_SCC2_PAGE, CPM_CR_SCC2_SBLOCK, 0, | ||
132 | cmd) | CPM_CR_FLG; | ||
133 | break; | ||
134 | case UART_SCC3: | ||
135 | val = mk_cr_cmd(CPM_CR_SCC3_PAGE, CPM_CR_SCC3_SBLOCK, 0, | ||
136 | cmd) | CPM_CR_FLG; | ||
137 | break; | ||
138 | case UART_SCC4: | ||
139 | val = mk_cr_cmd(CPM_CR_SCC4_PAGE, CPM_CR_SCC4_SBLOCK, 0, | ||
140 | cmd) | CPM_CR_FLG; | ||
141 | break; | ||
142 | default: | ||
143 | return; | ||
144 | |||
145 | } | ||
146 | cp->cp_cpcr = val; | ||
147 | while (cp->cp_cpcr & CPM_CR_FLG) ; | ||
148 | |||
149 | cpm2_unmap(cp); | ||
150 | } | ||
151 | |||
152 | void smc1_lineif(struct uart_cpm_port *pinfo) | ||
153 | { | ||
154 | volatile iop_cpm2_t *io = cpm2_map(im_ioport); | ||
155 | volatile cpmux_t *cpmux = cpm2_map(im_cpmux); | ||
156 | |||
157 | /* SMC1 is only on port D */ | ||
158 | io->iop_ppard |= 0x00c00000; | ||
159 | io->iop_pdird |= 0x00400000; | ||
160 | io->iop_pdird &= ~0x00800000; | ||
161 | io->iop_psord &= ~0x00c00000; | ||
162 | |||
163 | /* Wire BRG1 to SMC1 */ | ||
164 | cpmux->cmx_smr &= 0x0f; | ||
165 | pinfo->brg = 1; | ||
166 | |||
167 | cpm2_unmap(cpmux); | ||
168 | cpm2_unmap(io); | ||
169 | } | ||
170 | |||
171 | void smc2_lineif(struct uart_cpm_port *pinfo) | ||
172 | { | ||
173 | volatile iop_cpm2_t *io = cpm2_map(im_ioport); | ||
174 | volatile cpmux_t *cpmux = cpm2_map(im_cpmux); | ||
175 | |||
176 | /* SMC2 is only on port A */ | ||
177 | io->iop_ppara |= 0x00c00000; | ||
178 | io->iop_pdira |= 0x00400000; | ||
179 | io->iop_pdira &= ~0x00800000; | ||
180 | io->iop_psora &= ~0x00c00000; | ||
181 | |||
182 | /* Wire BRG2 to SMC2 */ | ||
183 | cpmux->cmx_smr &= 0xf0; | ||
184 | pinfo->brg = 2; | ||
185 | |||
186 | cpm2_unmap(cpmux); | ||
187 | cpm2_unmap(io); | ||
188 | } | ||
189 | |||
190 | void scc1_lineif(struct uart_cpm_port *pinfo) | ||
191 | { | ||
192 | volatile iop_cpm2_t *io = cpm2_map(im_ioport); | ||
193 | volatile cpmux_t *cpmux = cpm2_map(im_cpmux); | ||
194 | |||
195 | /* Use Port D for SCC1 instead of other functions. */ | ||
196 | io->iop_ppard |= 0x00000003; | ||
197 | io->iop_psord &= ~0x00000001; /* Rx */ | ||
198 | io->iop_psord |= 0x00000002; /* Tx */ | ||
199 | io->iop_pdird &= ~0x00000001; /* Rx */ | ||
200 | io->iop_pdird |= 0x00000002; /* Tx */ | ||
201 | |||
202 | /* Wire BRG1 to SCC1 */ | ||
203 | cpmux->cmx_scr &= 0x00ffffff; | ||
204 | cpmux->cmx_scr |= 0x00000000; | ||
205 | pinfo->brg = 1; | ||
206 | |||
207 | cpm2_unmap(cpmux); | ||
208 | cpm2_unmap(io); | ||
209 | } | ||
210 | |||
211 | void scc2_lineif(struct uart_cpm_port *pinfo) | ||
212 | { | ||
213 | /* | ||
214 | * STx GP3 uses the SCC2 secondary option pin assignment | ||
215 | * which this driver doesn't account for in the static | ||
216 | * pin assignments. This kind of board specific info | ||
217 | * really has to get out of the driver so boards can | ||
218 | * be supported in a sane fashion. | ||
219 | */ | ||
220 | volatile cpmux_t *cpmux = cpm2_map(im_cpmux); | ||
221 | #ifndef CONFIG_STX_GP3 | ||
222 | volatile iop_cpm2_t *io = cpm2_map(im_ioport); | ||
223 | |||
224 | io->iop_pparb |= 0x008b0000; | ||
225 | io->iop_pdirb |= 0x00880000; | ||
226 | io->iop_psorb |= 0x00880000; | ||
227 | io->iop_pdirb &= ~0x00030000; | ||
228 | io->iop_psorb &= ~0x00030000; | ||
229 | #endif | ||
230 | cpmux->cmx_scr &= 0xff00ffff; | ||
231 | cpmux->cmx_scr |= 0x00090000; | ||
232 | pinfo->brg = 2; | ||
233 | |||
234 | cpm2_unmap(cpmux); | ||
235 | cpm2_unmap(io); | ||
236 | } | ||
237 | |||
238 | void scc3_lineif(struct uart_cpm_port *pinfo) | ||
239 | { | ||
240 | volatile iop_cpm2_t *io = cpm2_map(im_ioport); | ||
241 | volatile cpmux_t *cpmux = cpm2_map(im_cpmux); | ||
242 | |||
243 | io->iop_pparb |= 0x008b0000; | ||
244 | io->iop_pdirb |= 0x00880000; | ||
245 | io->iop_psorb |= 0x00880000; | ||
246 | io->iop_pdirb &= ~0x00030000; | ||
247 | io->iop_psorb &= ~0x00030000; | ||
248 | cpmux->cmx_scr &= 0xffff00ff; | ||
249 | cpmux->cmx_scr |= 0x00001200; | ||
250 | pinfo->brg = 3; | ||
251 | |||
252 | cpm2_unmap(cpmux); | ||
253 | cpm2_unmap(io); | ||
254 | } | ||
255 | |||
256 | void scc4_lineif(struct uart_cpm_port *pinfo) | ||
257 | { | ||
258 | volatile iop_cpm2_t *io = cpm2_map(im_ioport); | ||
259 | volatile cpmux_t *cpmux = cpm2_map(im_cpmux); | ||
260 | |||
261 | io->iop_ppard |= 0x00000600; | ||
262 | io->iop_psord &= ~0x00000600; /* Tx/Rx */ | ||
263 | io->iop_pdird &= ~0x00000200; /* Rx */ | ||
264 | io->iop_pdird |= 0x00000400; /* Tx */ | ||
265 | |||
266 | cpmux->cmx_scr &= 0xffffff00; | ||
267 | cpmux->cmx_scr |= 0x0000001b; | ||
268 | pinfo->brg = 4; | ||
269 | |||
270 | cpm2_unmap(cpmux); | ||
271 | cpm2_unmap(io); | ||
272 | } | ||
273 | #endif | ||
274 | |||
275 | /* | 106 | /* |
276 | * Allocate DP-Ram and memory buffers. We need to allocate a transmit and | 107 | * Allocate DP-Ram and memory buffers. We need to allocate a transmit and |
277 | * receive buffer descriptors from dual port ram, and a character | 108 | * receive buffer descriptors from dual port ram, and a character |
278 | * buffer area from host mem. If we are allocating for the console we need | 109 | * buffer area from host mem. If we are allocating for the console we need |
279 | * to do it from bootmem | 110 | * to do it from bootmem |
@@ -340,111 +171,3 @@ void cpm_uart_freebuf(struct uart_cpm_port *pinfo) | |||
340 | 171 | ||
341 | cpm_dpfree(pinfo->dp_addr); | 172 | cpm_dpfree(pinfo->dp_addr); |
342 | } | 173 | } |
343 | |||
344 | #ifndef CONFIG_PPC_CPM_NEW_BINDING | ||
345 | /* Setup any dynamic params in the uart desc */ | ||
346 | int cpm_uart_init_portdesc(void) | ||
347 | { | ||
348 | #if defined(CONFIG_SERIAL_CPM_SMC1) || defined(CONFIG_SERIAL_CPM_SMC2) | ||
349 | u16 *addr; | ||
350 | #endif | ||
351 | pr_debug("CPM uart[-]:init portdesc\n"); | ||
352 | |||
353 | cpm_uart_nr = 0; | ||
354 | #ifdef CONFIG_SERIAL_CPM_SMC1 | ||
355 | cpm_uart_ports[UART_SMC1].smcp = (smc_t *) cpm2_map(im_smc[0]); | ||
356 | cpm_uart_ports[UART_SMC1].port.mapbase = | ||
357 | (unsigned long)cpm_uart_ports[UART_SMC1].smcp; | ||
358 | |||
359 | cpm_uart_ports[UART_SMC1].smcup = | ||
360 | (smc_uart_t *) cpm2_map_size(im_dprambase[PROFF_SMC1], PROFF_SMC_SIZE); | ||
361 | addr = (u16 *)cpm2_map_size(im_dprambase[PROFF_SMC1_BASE], 2); | ||
362 | *addr = PROFF_SMC1; | ||
363 | cpm2_unmap(addr); | ||
364 | |||
365 | cpm_uart_ports[UART_SMC1].smcp->smc_smcm |= (SMCM_RX | SMCM_TX); | ||
366 | cpm_uart_ports[UART_SMC1].smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); | ||
367 | cpm_uart_ports[UART_SMC1].port.uartclk = uart_clock(); | ||
368 | cpm_uart_port_map[cpm_uart_nr++] = UART_SMC1; | ||
369 | #endif | ||
370 | |||
371 | #ifdef CONFIG_SERIAL_CPM_SMC2 | ||
372 | cpm_uart_ports[UART_SMC2].smcp = (smc_t *) cpm2_map(im_smc[1]); | ||
373 | cpm_uart_ports[UART_SMC2].port.mapbase = | ||
374 | (unsigned long)cpm_uart_ports[UART_SMC2].smcp; | ||
375 | |||
376 | cpm_uart_ports[UART_SMC2].smcup = | ||
377 | (smc_uart_t *) cpm2_map_size(im_dprambase[PROFF_SMC2], PROFF_SMC_SIZE); | ||
378 | addr = (u16 *)cpm2_map_size(im_dprambase[PROFF_SMC2_BASE], 2); | ||
379 | *addr = PROFF_SMC2; | ||
380 | cpm2_unmap(addr); | ||
381 | |||
382 | cpm_uart_ports[UART_SMC2].smcp->smc_smcm |= (SMCM_RX | SMCM_TX); | ||
383 | cpm_uart_ports[UART_SMC2].smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); | ||
384 | cpm_uart_ports[UART_SMC2].port.uartclk = uart_clock(); | ||
385 | cpm_uart_port_map[cpm_uart_nr++] = UART_SMC2; | ||
386 | #endif | ||
387 | |||
388 | #ifdef CONFIG_SERIAL_CPM_SCC1 | ||
389 | cpm_uart_ports[UART_SCC1].sccp = (scc_t *) cpm2_map(im_scc[0]); | ||
390 | cpm_uart_ports[UART_SCC1].port.mapbase = | ||
391 | (unsigned long)cpm_uart_ports[UART_SCC1].sccp; | ||
392 | cpm_uart_ports[UART_SCC1].sccup = | ||
393 | (scc_uart_t *) cpm2_map_size(im_dprambase[PROFF_SCC1], PROFF_SCC_SIZE); | ||
394 | |||
395 | cpm_uart_ports[UART_SCC1].sccp->scc_sccm &= | ||
396 | ~(UART_SCCM_TX | UART_SCCM_RX); | ||
397 | cpm_uart_ports[UART_SCC1].sccp->scc_gsmrl &= | ||
398 | ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); | ||
399 | cpm_uart_ports[UART_SCC1].port.uartclk = uart_clock(); | ||
400 | cpm_uart_port_map[cpm_uart_nr++] = UART_SCC1; | ||
401 | #endif | ||
402 | |||
403 | #ifdef CONFIG_SERIAL_CPM_SCC2 | ||
404 | cpm_uart_ports[UART_SCC2].sccp = (scc_t *) cpm2_map(im_scc[1]); | ||
405 | cpm_uart_ports[UART_SCC2].port.mapbase = | ||
406 | (unsigned long)cpm_uart_ports[UART_SCC2].sccp; | ||
407 | cpm_uart_ports[UART_SCC2].sccup = | ||
408 | (scc_uart_t *) cpm2_map_size(im_dprambase[PROFF_SCC2], PROFF_SCC_SIZE); | ||
409 | |||
410 | cpm_uart_ports[UART_SCC2].sccp->scc_sccm &= | ||
411 | ~(UART_SCCM_TX | UART_SCCM_RX); | ||
412 | cpm_uart_ports[UART_SCC2].sccp->scc_gsmrl &= | ||
413 | ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); | ||
414 | cpm_uart_ports[UART_SCC2].port.uartclk = uart_clock(); | ||
415 | cpm_uart_port_map[cpm_uart_nr++] = UART_SCC2; | ||
416 | #endif | ||
417 | |||
418 | #ifdef CONFIG_SERIAL_CPM_SCC3 | ||
419 | cpm_uart_ports[UART_SCC3].sccp = (scc_t *) cpm2_map(im_scc[2]); | ||
420 | cpm_uart_ports[UART_SCC3].port.mapbase = | ||
421 | (unsigned long)cpm_uart_ports[UART_SCC3].sccp; | ||
422 | cpm_uart_ports[UART_SCC3].sccup = | ||
423 | (scc_uart_t *) cpm2_map_size(im_dprambase[PROFF_SCC3], PROFF_SCC_SIZE); | ||
424 | |||
425 | cpm_uart_ports[UART_SCC3].sccp->scc_sccm &= | ||
426 | ~(UART_SCCM_TX | UART_SCCM_RX); | ||
427 | cpm_uart_ports[UART_SCC3].sccp->scc_gsmrl &= | ||
428 | ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); | ||
429 | cpm_uart_ports[UART_SCC3].port.uartclk = uart_clock(); | ||
430 | cpm_uart_port_map[cpm_uart_nr++] = UART_SCC3; | ||
431 | #endif | ||
432 | |||
433 | #ifdef CONFIG_SERIAL_CPM_SCC4 | ||
434 | cpm_uart_ports[UART_SCC4].sccp = (scc_t *) cpm2_map(im_scc[3]); | ||
435 | cpm_uart_ports[UART_SCC4].port.mapbase = | ||
436 | (unsigned long)cpm_uart_ports[UART_SCC4].sccp; | ||
437 | cpm_uart_ports[UART_SCC4].sccup = | ||
438 | (scc_uart_t *) cpm2_map_size(im_dprambase[PROFF_SCC4], PROFF_SCC_SIZE); | ||
439 | |||
440 | cpm_uart_ports[UART_SCC4].sccp->scc_sccm &= | ||
441 | ~(UART_SCCM_TX | UART_SCCM_RX); | ||
442 | cpm_uart_ports[UART_SCC4].sccp->scc_gsmrl &= | ||
443 | ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); | ||
444 | cpm_uart_ports[UART_SCC4].port.uartclk = uart_clock(); | ||
445 | cpm_uart_port_map[cpm_uart_nr++] = UART_SCC4; | ||
446 | #endif | ||
447 | |||
448 | return 0; | ||
449 | } | ||
450 | #endif | ||
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm2.h b/drivers/serial/cpm_uart/cpm_uart_cpm2.h index 40006a7dce46..7194c63dcf5f 100644 --- a/drivers/serial/cpm_uart/cpm_uart_cpm2.h +++ b/drivers/serial/cpm_uart/cpm_uart_cpm2.h | |||
@@ -2,7 +2,7 @@ | |||
2 | * linux/drivers/serial/cpm_uart/cpm_uart_cpm2.h | 2 | * linux/drivers/serial/cpm_uart/cpm_uart_cpm2.h |
3 | * | 3 | * |
4 | * Driver for CPM (SCC/SMC) serial ports | 4 | * Driver for CPM (SCC/SMC) serial ports |
5 | * | 5 | * |
6 | * definitions for cpm2 | 6 | * definitions for cpm2 |
7 | * | 7 | * |
8 | */ | 8 | */ |
@@ -12,16 +12,6 @@ | |||
12 | 12 | ||
13 | #include <asm/cpm2.h> | 13 | #include <asm/cpm2.h> |
14 | 14 | ||
15 | /* defines for IRQs */ | ||
16 | #ifndef CONFIG_PPC_CPM_NEW_BINDING | ||
17 | #define SMC1_IRQ SIU_INT_SMC1 | ||
18 | #define SMC2_IRQ SIU_INT_SMC2 | ||
19 | #define SCC1_IRQ SIU_INT_SCC1 | ||
20 | #define SCC2_IRQ SIU_INT_SCC2 | ||
21 | #define SCC3_IRQ SIU_INT_SCC3 | ||
22 | #define SCC4_IRQ SIU_INT_SCC4 | ||
23 | #endif | ||
24 | |||
25 | static inline void cpm_set_brg(int brg, int baud) | 15 | static inline void cpm_set_brg(int brg, int baud) |
26 | { | 16 | { |
27 | cpm_setbrg(brg, baud); | 17 | cpm_setbrg(brg, baud); |
diff --git a/drivers/serial/of_serial.c b/drivers/serial/of_serial.c index 25029c7570b6..8fa0ff561e9f 100644 --- a/drivers/serial/of_serial.c +++ b/drivers/serial/of_serial.c | |||
@@ -13,8 +13,8 @@ | |||
13 | #include <linux/module.h> | 13 | #include <linux/module.h> |
14 | #include <linux/serial_core.h> | 14 | #include <linux/serial_core.h> |
15 | #include <linux/serial_8250.h> | 15 | #include <linux/serial_8250.h> |
16 | #include <linux/of_platform.h> | ||
16 | 17 | ||
17 | #include <asm/of_platform.h> | ||
18 | #include <asm/prom.h> | 18 | #include <asm/prom.h> |
19 | 19 | ||
20 | struct of_serial_info { | 20 | struct of_serial_info { |
diff --git a/drivers/spi/mpc52xx_psc_spi.c b/drivers/spi/mpc52xx_psc_spi.c index 681d62325d3d..604e5f0a2d95 100644 --- a/drivers/spi/mpc52xx_psc_spi.c +++ b/drivers/spi/mpc52xx_psc_spi.c | |||
@@ -17,7 +17,7 @@ | |||
17 | #include <linux/interrupt.h> | 17 | #include <linux/interrupt.h> |
18 | 18 | ||
19 | #if defined(CONFIG_PPC_MERGE) | 19 | #if defined(CONFIG_PPC_MERGE) |
20 | #include <asm/of_platform.h> | 20 | #include <linux/of_platform.h> |
21 | #else | 21 | #else |
22 | #include <linux/platform_device.h> | 22 | #include <linux/platform_device.h> |
23 | #endif | 23 | #endif |
diff --git a/drivers/video/platinumfb.c b/drivers/video/platinumfb.c index cbe71a5338d0..03b3670130a0 100644 --- a/drivers/video/platinumfb.c +++ b/drivers/video/platinumfb.c | |||
@@ -31,11 +31,11 @@ | |||
31 | #include <linux/fb.h> | 31 | #include <linux/fb.h> |
32 | #include <linux/init.h> | 32 | #include <linux/init.h> |
33 | #include <linux/nvram.h> | 33 | #include <linux/nvram.h> |
34 | #include <linux/of_device.h> | ||
35 | #include <linux/of_platform.h> | ||
34 | #include <asm/io.h> | 36 | #include <asm/io.h> |
35 | #include <asm/prom.h> | 37 | #include <asm/prom.h> |
36 | #include <asm/pgtable.h> | 38 | #include <asm/pgtable.h> |
37 | #include <asm/of_device.h> | ||
38 | #include <asm/of_platform.h> | ||
39 | 39 | ||
40 | #include "macmodes.h" | 40 | #include "macmodes.h" |
41 | #include "platinumfb.h" | 41 | #include "platinumfb.h" |
diff --git a/drivers/watchdog/mpc5200_wdt.c b/drivers/watchdog/mpc5200_wdt.c index 80a91d4cea11..77c1c2ae2cc2 100644 --- a/drivers/watchdog/mpc5200_wdt.c +++ b/drivers/watchdog/mpc5200_wdt.c | |||
@@ -4,7 +4,7 @@ | |||
4 | #include <linux/watchdog.h> | 4 | #include <linux/watchdog.h> |
5 | #include <linux/io.h> | 5 | #include <linux/io.h> |
6 | #include <linux/spinlock.h> | 6 | #include <linux/spinlock.h> |
7 | #include <asm/of_platform.h> | 7 | #include <linux/of_platform.h> |
8 | #include <asm/uaccess.h> | 8 | #include <asm/uaccess.h> |
9 | #include <asm/mpc52xx.h> | 9 | #include <asm/mpc52xx.h> |
10 | 10 | ||