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 | ||
