diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-15 19:04:58 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-15 19:04:58 -0700 |
commit | 45158894d4d6704afbb4cefe55e5f6ca279fe12a (patch) | |
tree | d57e745e2d0848d75cd4a46ca04178b16f186b50 /drivers | |
parent | 89a93f2f4834f8c126e8d9dd6b368d0b9e21ec3d (diff) | |
parent | 84c3d4aaec3338201b449034beac41635866bddf (diff) |
Merge branch 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
* 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc: (249 commits)
powerpc: Fix pte_update for CONFIG_PTE_64BIT and !PTE_ATOMIC_UPDATES
powerpc: Fix a build problem on ppc32 with new DMA_ATTRs
ibm_newemac: Add MII mode support to the EMAC RGMII bridge.
powerpc: Don't spin on sync instruction at boot time
powerpc: Add VSX load/store alignment exception handler
powerpc: fix giveup_vsx to save registers correctly
powerpc: support for latencytop
powerpc: Remove unnecessary condition when sanity-checking WIMG bits
powerpc: Add PPC_FEATURE_PSERIES_PERFMON_COMPAT
powerpc: Add driver for Barrier Synchronization Register
powerpc: mman.h export fixups
powerpc/fsl: update crypto node definition and device tree instances
powerpc/fsl: Refactor device bindings
powerpc/85xx: Minor fixes for 85xxds and 8536ds board.
powerpc: Add 82xx/83xx/86xx to 6xx Multiplatform
powerpc/85xx: publish of device for cds platforms
powerpc/booke: don't reinitialize time base
powerpc/86xx: Refactor pic init
powerpc/CPM: Add i2c pins to dts and board setup
cpm_uart: Support uart_wait_until_sent()
...
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 bc79df6e7cb..a9e827356d0 100644 --- a/drivers/ata/pata_mpc52xx.c +++ b/drivers/ata/pata_mpc52xx.c @@ -16,10 +16,10 @@ #include <linux/slab.h> #include <linux/delay.h> #include <linux/libata.h> +#include <linux/of_platform.h> #include <asm/types.h> #include <asm/prom.h> -#include <asm/of_platform.h> #include <asm/mpc52xx.h> diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 2d854bb9373..650e6b44ce6 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig @@ -649,6 +649,14 @@ config HVCS which will also be compiled when this driver is built as a module. +config IBM_BSR + tristate "IBM POWER Barrier Synchronization Register support" + depends on PPC_PSERIES + help + This devices exposes a hardware mechanism for fast synchronization + of threads across a large system which avoids bouncing a cacheline + between several cores on a system + source "drivers/char/ipmi/Kconfig" config DS1620 diff --git a/drivers/char/Makefile b/drivers/char/Makefile index 81630a68475..0e0d12a0646 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile @@ -57,6 +57,7 @@ obj-$(CONFIG_MMTIMER) += mmtimer.o obj-$(CONFIG_VIOCONS) += viocons.o obj-$(CONFIG_VIOTAPE) += viotape.o obj-$(CONFIG_HVCS) += hvcs.o +obj-$(CONFIG_IBM_BSR) += bsr.o obj-$(CONFIG_SGI_MBCS) += mbcs.o obj-$(CONFIG_BRIQ_PANEL) += briq_panel.o obj-$(CONFIG_BFIN_OTP) += bfin-otp.o diff --git a/drivers/char/bsr.c b/drivers/char/bsr.c new file mode 100644 index 00000000000..b650b4e48e5 --- /dev/null +++ b/drivers/char/bsr.c @@ -0,0 +1,312 @@ +/* IBM POWER Barrier Synchronization Register Driver + * + * Copyright IBM Corporation 2008 + * + * Author: Sonny Rao <sonnyrao@us.ibm.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/kernel.h> +#include <linux/of.h> +#include <linux/of_device.h> +#include <linux/of_platform.h> +#include <linux/module.h> +#include <linux/cdev.h> +#include <linux/list.h> +#include <linux/mm.h> +#include <asm/io.h> + +/* + This driver exposes a special register which can be used for fast + synchronization across a large SMP machine. The hardware is exposed + as an array of bytes where each process will write to one of the bytes to + indicate it has finished the current stage and this update is broadcast to + all processors without having to bounce a cacheline between them. In + POWER5 and POWER6 there is one of these registers per SMP, but it is + presented in two forms; first, it is given as a whole and then as a number + of smaller registers which alias to parts of the single whole register. + This can potentially allow multiple groups of processes to each have their + own private synchronization device. + + Note that this hardware *must* be written to using *only* single byte writes. + It may be read using 1, 2, 4, or 8 byte loads which must be aligned since + this region is treated as cache-inhibited processes should also use a + full sync before and after writing to the BSR to ensure all stores and + the BSR update have made it to all chips in the system +*/ + +/* This is arbitrary number, up to Power6 it's been 17 or fewer */ +#define BSR_MAX_DEVS (32) + +struct bsr_dev { + u64 bsr_addr; /* Real address */ + u64 bsr_len; /* length of mem region we can map */ + unsigned bsr_bytes; /* size of the BSR reg itself */ + unsigned bsr_stride; /* interval at which BSR repeats in the page */ + unsigned bsr_type; /* maps to enum below */ + unsigned bsr_num; /* bsr id number for its type */ + int bsr_minor; + + dev_t bsr_dev; + struct cdev bsr_cdev; + struct device *bsr_device; + char bsr_name[32]; + +}; + +static unsigned num_bsr_devs; +static struct bsr_dev *bsr_devs; +static struct class *bsr_class; +static int bsr_major; + +enum { + BSR_8 = 0, + BSR_16 = 1, + BSR_64 = 2, + BSR_128 = 3, + BSR_UNKNOWN = 4, + BSR_MAX = 5, +}; + +static unsigned bsr_types[BSR_MAX]; + +static ssize_t +bsr_size_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct bsr_dev *bsr_dev = dev_get_drvdata(dev); + return sprintf(buf, "%u\n", bsr_dev->bsr_bytes); +} + +static ssize_t +bsr_stride_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct bsr_dev *bsr_dev = dev_get_drvdata(dev); + return sprintf(buf, "%u\n", bsr_dev->bsr_stride); +} + +static ssize_t +bsr_len_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct bsr_dev *bsr_dev = dev_get_drvdata(dev); + return sprintf(buf, "%lu\n", bsr_dev->bsr_len); +} + +static struct device_attribute bsr_dev_attrs[] = { + __ATTR(bsr_size, S_IRUGO, bsr_size_show, NULL), + __ATTR(bsr_stride, S_IRUGO, bsr_stride_show, NULL), + __ATTR(bsr_length, S_IRUGO, bsr_len_show, NULL), + __ATTR_NULL +}; + +static int bsr_mmap(struct file *filp, struct vm_area_struct *vma) +{ + unsigned long size = vma->vm_end - vma->vm_start; + struct bsr_dev *dev = filp->private_data; + + if (size > dev->bsr_len || (size & (PAGE_SIZE-1))) + return -EINVAL; + + vma->vm_flags |= (VM_IO | VM_DONTEXPAND); + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + + if (io_remap_pfn_range(vma, vma->vm_start, dev->bsr_addr >> PAGE_SHIFT, + size, vma->vm_page_prot)) + return -EAGAIN; + + return 0; +} + +static int bsr_open(struct inode * inode, struct file * filp) +{ + struct cdev *cdev = inode->i_cdev; + struct bsr_dev *dev = container_of(cdev, struct bsr_dev, bsr_cdev); + + filp->private_data = dev; + return 0; +} + +const static struct file_operations bsr_fops = { + .owner = THIS_MODULE, + .mmap = bsr_mmap, + .open = bsr_open, +}; + +static void bsr_cleanup_devs(void) +{ + int i; + for (i=0 ; i < num_bsr_devs; i++) { + struct bsr_dev *cur = bsr_devs + i; + if (cur->bsr_device) { + cdev_del(&cur->bsr_cdev); + device_del(cur->bsr_device); + } + } + + kfree(bsr_devs); +} + +static int bsr_create_devs(struct device_node *bn) +{ + int bsr_stride_len, bsr_bytes_len; + const u32 *bsr_stride; + const u32 *bsr_bytes; + unsigned i; + + bsr_stride = of_get_property(bn, "ibm,lock-stride", &bsr_stride_len); + bsr_bytes = of_get_property(bn, "ibm,#lock-bytes", &bsr_bytes_len); + + if (!bsr_stride || !bsr_bytes || + (bsr_stride_len != bsr_bytes_len)) { + printk(KERN_ERR "bsr of-node has missing/incorrect property\n"); + return -ENODEV; + } + + num_bsr_devs = bsr_bytes_len / sizeof(u32); + + /* only a warning, its informational since we'll fail and exit */ + WARN_ON(num_bsr_devs > BSR_MAX_DEVS); + + bsr_devs = kzalloc(sizeof(struct bsr_dev) * num_bsr_devs, GFP_KERNEL); + if (!bsr_devs) + return -ENOMEM; + + for (i = 0 ; i < num_bsr_devs; i++) { + struct bsr_dev *cur = bsr_devs + i; + struct resource res; + int result; + + result = of_address_to_resource(bn, i, &res); + if (result < 0) { + printk(KERN_ERR "bsr of-node has invalid reg property\n"); + goto out_err; + } + + cur->bsr_minor = i; + cur->bsr_addr = res.start; + cur->bsr_len = res.end - res.start + 1; + cur->bsr_bytes = bsr_bytes[i]; + cur->bsr_stride = bsr_stride[i]; + cur->bsr_dev = MKDEV(bsr_major, i); + + switch(cur->bsr_bytes) { + case 8: + cur->bsr_type = BSR_8; + break; + case 16: + cur->bsr_type = BSR_16; + break; + case 64: + cur->bsr_type = BSR_64; + break; + case 128: + cur->bsr_type = BSR_128; + break; + default: + cur->bsr_type = BSR_UNKNOWN; + printk(KERN_INFO "unknown BSR size %d\n",cur->bsr_bytes); + } + + cur->bsr_num = bsr_types[cur->bsr_type]; + bsr_types[cur->bsr_type] = cur->bsr_num + 1; + snprintf(cur->bsr_name, 32, "bsr%d_%d", + cur->bsr_bytes, cur->bsr_num); + + cdev_init(&cur->bsr_cdev, &bsr_fops); + result = cdev_add(&cur->bsr_cdev, cur->bsr_dev, 1); + if (result) + goto out_err; + + cur->bsr_device = device_create_drvdata(bsr_class, NULL, + cur->bsr_dev, + cur, cur->bsr_name); + if (!cur->bsr_device) { + printk(KERN_ERR "device_create failed for %s\n", + cur->bsr_name); + cdev_del(&cur->bsr_cdev); + goto out_err; + } + } + + return 0; + + out_err: + + bsr_cleanup_devs(); + return -ENODEV; +} + +static int __init bsr_init(void) +{ + struct device_node *np; + dev_t bsr_dev = MKDEV(bsr_major, 0); + int ret = -ENODEV; + int result; + + np = of_find_compatible_node(NULL, "ibm,bsr", "ibm,bsr"); + if (!np) + goto out_err; + + bsr_class = class_create(THIS_MODULE, "bsr"); + if (IS_ERR(bsr_class)) { + printk(KERN_ERR "class_create() failed for bsr_class\n"); + goto out_err_1; + } + bsr_class->dev_attrs = bsr_dev_attrs; + + result = alloc_chrdev_region(&bsr_dev, 0, BSR_MAX_DEVS, "bsr"); + bsr_major = MAJOR(bsr_dev); + if (result < 0) { + printk(KERN_ERR "alloc_chrdev_region() failed for bsr\n"); + goto out_err_2; + } + + if ((ret = bsr_create_devs(np)) < 0) + goto out_err_3; + + of_node_put(np); + + return 0; + + out_err_3: + unregister_chrdev_region(bsr_dev, BSR_MAX_DEVS); + + out_err_2: + class_destroy(bsr_class); + + out_err_1: + of_node_put(np); + + out_err: + + return ret; +} + +static void __exit bsr_exit(void) +{ + + bsr_cleanup_devs(); + + if (bsr_class) + class_destroy(bsr_class); + + if (bsr_major) + unregister_chrdev_region(MKDEV(bsr_major, 0), BSR_MAX_DEVS); +} + +module_init(bsr_init); +module_exit(bsr_exit); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Sonny Rao <sonnyrao@us.ibm.com>"); diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c index 44160d5ebca..2f9759d625c 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) return poll_mask; } -#if defined(CONFIG_XMON) && defined(CONFIG_SMP) -extern cpumask_t cpus_in_xmon; -#else -static const cpumask_t cpus_in_xmon = CPU_MASK_NONE; -#endif - /* * This kthread is either polling or interrupt driven. This is determined by * calling hvc_poll() who determines whether a console adapter support @@ -698,7 +692,7 @@ static int khvcd(void *unused) hvc_kicked = 0; try_to_freeze(); wmb(); - if (cpus_empty(cpus_in_xmon)) { + if (!cpus_are_in_xmon()) { spin_lock(&hvc_structs_lock); list_for_each_entry(hp, &hvc_structs, next) { poll_mask |= hvc_poll(hp); diff --git a/drivers/char/hvc_console.h b/drivers/char/hvc_console.h index 8c59818050e..42ffb17e15d 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, /* remove a vterm from hvc tty operation (modele_exit or hotplug remove) */ extern int __devexit hvc_remove(struct hvc_struct *hp); + +#if defined(CONFIG_XMON) && defined(CONFIG_SMP) +#include <asm/xmon.h> +#else +static inline int cpus_are_in_xmon(void) +{ + return 0; +} +#endif + #endif // HVC_CONSOLE_H diff --git a/drivers/char/hw_random/pasemi-rng.c b/drivers/char/hw_random/pasemi-rng.c index 6d50e9bc700..7fa61dd1d9d 100644 --- a/drivers/char/hw_random/pasemi-rng.c +++ b/drivers/char/hw_random/pasemi-rng.c @@ -24,7 +24,7 @@ #include <linux/platform_device.h> #include <linux/hw_random.h> #include <linux/delay.h> -#include <asm/of_platform.h> +#include <linux/of_platform.h> #include <asm/io.h> #define SDCRNG_CTL_REG 0x00 diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c index 977f7d35e76..e5da98d8f9c 100644 --- a/drivers/char/viotape.c +++ b/drivers/char/viotape.c @@ -678,6 +678,17 @@ free_op: return ret; } +static long viotap_unlocked_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) +{ + long rc; + + lock_kernel(); + rc = viotap_ioctl(file->f_path.dentry->d_inode, file, cmd, arg); + unlock_kernel(); + return rc; +} + static int viotap_open(struct inode *inode, struct file *file) { HvLpEvent_Rc hvrc; @@ -786,12 +797,12 @@ free_op: } const struct file_operations viotap_fops = { - .owner = THIS_MODULE, - .read = viotap_read, - .write = viotap_write, - .ioctl = viotap_ioctl, - .open = viotap_open, - .release = viotap_release, + .owner = THIS_MODULE, + .read = viotap_read, + .write = viotap_write, + .unlocked_ioctl = viotap_unlocked_ioctl, + .open = viotap_open, + .release = viotap_release, }; /* Handle interrupt events for tape */ diff --git a/drivers/hwmon/ams/ams-core.c b/drivers/hwmon/ams/ams-core.c index a112a03e8f2..fbefa82a015 100644 --- a/drivers/hwmon/ams/ams-core.c +++ b/drivers/hwmon/ams/ams-core.c @@ -23,8 +23,8 @@ #include <linux/types.h> #include <linux/errno.h> #include <linux/init.h> +#include <linux/of_platform.h> #include <asm/pmac_pfunc.h> -#include <asm/of_platform.h> #include "ams.h" diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index 10b9342a36c..27443f073bc 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c @@ -17,7 +17,8 @@ #include <linux/module.h> #include <linux/sched.h> #include <linux/init.h> -#include <linux/platform_device.h> +#include <linux/of_platform.h> +#include <linux/of_i2c.h> #include <asm/io.h> #include <linux/fsl_devices.h> @@ -25,13 +26,13 @@ #include <linux/interrupt.h> #include <linux/delay.h> -#define MPC_I2C_ADDR 0x00 +#define DRV_NAME "mpc-i2c" + #define MPC_I2C_FDR 0x04 #define MPC_I2C_CR 0x08 #define MPC_I2C_SR 0x0c #define MPC_I2C_DR 0x10 #define MPC_I2C_DFSRR 0x14 -#define MPC_I2C_REGION 0x20 #define CCR_MEN 0x80 #define CCR_MIEN 0x40 @@ -315,102 +316,117 @@ static struct i2c_adapter mpc_ops = { .timeout = 1, }; -static int fsl_i2c_probe(struct platform_device *pdev) +static int __devinit fsl_i2c_probe(struct of_device *op, const struct of_device_id *match) { int result = 0; struct mpc_i2c *i2c; - struct fsl_i2c_platform_data *pdata; - struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0); - - pdata = (struct fsl_i2c_platform_data *) pdev->dev.platform_data; i2c = kzalloc(sizeof(*i2c), GFP_KERNEL); if (!i2c) return -ENOMEM; - i2c->irq = platform_get_irq(pdev, 0); - if (i2c->irq < 0) - i2c->irq = NO_IRQ; /* Use polling */ + if (of_get_property(op->node, "dfsrr", NULL)) + i2c->flags |= FSL_I2C_DEV_SEPARATE_DFSRR; - i2c->flags = pdata->device_flags; - init_waitqueue_head(&i2c->queue); + if (of_device_is_compatible(op->node, "fsl,mpc5200-i2c") || + of_device_is_compatible(op->node, "mpc5200-i2c")) + i2c->flags |= FSL_I2C_DEV_CLOCK_5200; - i2c->base = ioremap((phys_addr_t)r->start, MPC_I2C_REGION); + init_waitqueue_head(&i2c->queue); + i2c->base = of_iomap(op->node, 0); if (!i2c->base) { printk(KERN_ERR "i2c-mpc - failed to map controller\n"); result = -ENOMEM; goto fail_map; } - if (i2c->irq != NO_IRQ) - if ((result = request_irq(i2c->irq, mpc_i2c_isr, - IRQF_SHARED, "i2c-mpc", i2c)) < 0) { - printk(KERN_ERR - "i2c-mpc - failed to attach interrupt\n"); - goto fail_irq; + i2c->irq = irq_of_parse_and_map(op->node, 0); + if (i2c->irq != NO_IRQ) { /* i2c->irq = NO_IRQ implies polling */ + result = request_irq(i2c->irq, mpc_i2c_isr, + IRQF_SHARED, "i2c-mpc", i2c); + if (result < 0) { + printk(KERN_ERR "i2c-mpc - failed to attach interrupt\n"); + goto fail_request; } - + } + mpc_i2c_setclock(i2c); - platform_set_drvdata(pdev, i2c); + + dev_set_drvdata(&op->dev, i2c); i2c->adap = mpc_ops; - i2c->adap.nr = pdev->id; i2c_set_adapdata(&i2c->adap, i2c); - i2c->adap.dev.parent = &pdev->dev; - if ((result = i2c_add_numbered_adapter(&i2c->adap)) < 0) { + i2c->adap.dev.parent = &op->dev; + + result = i2c_add_adapter(&i2c->adap); + if (result < 0) { printk(KERN_ERR "i2c-mpc - failed to add adapter\n"); goto fail_add; } + of_register_i2c_devices(&i2c->adap, op->node); return result; - fail_add: - if (i2c->irq != NO_IRQ) - free_irq(i2c->irq, i2c); - fail_irq: - iounmap(i2c->base); - fail_map: + fail_add: + dev_set_drvdata(&op->dev, NULL); + free_irq(i2c->irq, i2c); + fail_request: + irq_dispose_mapping(i2c->irq); + iounmap(i2c->base); + fail_map: kfree(i2c); return result; }; -static int fsl_i2c_remove(struct platform_device *pdev) +static int __devexit fsl_i2c_remove(struct of_device *op) { - struct mpc_i2c *i2c = platform_get_drvdata(pdev); + struct mpc_i2c *i2c = dev_get_drvdata(&op->dev); i2c_del_adapter(&i2c->adap); - platform_set_drvdata(pdev, NULL); + dev_set_drvdata(&op->dev, NULL); if (i2c->irq != NO_IRQ) free_irq(i2c->irq, i2c); + irq_dispose_mapping(i2c->irq); iounmap(i2c->base); kfree(i2c); return 0; }; -/* work with hotplug and coldplug */ -MODULE_ALIAS("platform:fsl-i2c"); +static const struct of_device_id mpc_i2c_of_match[] = { + {.compatible = "fsl-i2c",}, + {}, +}; +MODULE_DEVICE_TABLE(of, mpc_i2c_of_match); + /* Structure for a device driver */ -static struct platform_driver fsl_i2c_driver = { - .probe = fsl_i2c_probe, - .remove = fsl_i2c_remove, - .driver = { - .owner = THIS_MODULE, - .name = "fsl-i2c", +static struct of_platform_driver mpc_i2c_driver = { + .match_table = mpc_i2c_of_match, + .probe = fsl_i2c_probe, + .remove = __devexit_p(fsl_i2c_remove), + .driver = { + .owner = THIS_MODULE, + .name = DRV_NAME, }, }; static int __init fsl_i2c_init(void) { - return platform_driver_register(&fsl_i2c_driver); + int rv; + + rv = of_register_platform_driver(&mpc_i2c_driver); + if (rv) + printk(KERN_ERR DRV_NAME + " of_register_platform_driver failed (%i)\n", rv); + return rv; } static void __exit fsl_i2c_exit(void) { - platform_driver_unregister(&fsl_i2c_driver); + of_unregister_platform_driver(&mpc_i2c_driver); } module_init(fsl_i2c_init); diff --git a/drivers/macintosh/adb.c b/drivers/macintosh/adb.c index 40c70ba62bf..e5d446804d3 100644 --- a/drivers/macintosh/adb.c +++ b/drivers/macintosh/adb.c @@ -46,7 +46,6 @@ #endif -EXPORT_SYMBOL(adb_controller); EXPORT_SYMBOL(adb_client_list); extern struct adb_driver via_macii_driver; @@ -80,7 +79,7 @@ static struct adb_driver *adb_driver_list[] = { static struct class *adb_dev_class; -struct adb_driver *adb_controller; +static struct adb_driver *adb_controller; BLOCKING_NOTIFIER_HEAD(adb_client_list); static int adb_got_sleep; static int adb_inited; @@ -290,7 +289,7 @@ static int adb_resume(struct platform_device *dev) } #endif /* CONFIG_PM */ -int __init adb_init(void) +static int __init adb_init(void) { struct adb_driver *driver; int i; diff --git a/drivers/macintosh/adbhid.c b/drivers/macintosh/adbhid.c index ef4c117ea35..59ea520a5d7 100644 --- a/drivers/macintosh/adbhid.c +++ b/drivers/macintosh/adbhid.c @@ -75,7 +75,7 @@ static struct notifier_block adbhid_adb_notifier = { #define ADB_KEY_POWER_OLD 0x7e #define ADB_KEY_POWER 0x7f -u16 adb_to_linux_keycodes[128] = { +static const u16 adb_to_linux_keycodes[128] = { /* 0x00 */ KEY_A, /* 30 */ /* 0x01 */ KEY_S, /* 31 */ /* 0x02 */ KEY_D, /* 32 */ diff --git a/drivers/macintosh/macio_sysfs.c b/drivers/macintosh/macio_sysfs.c index 112e5ef728f..9e9453b5842 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, struct of_device *ofdev = to_of_device(dev); int len; - len = of_device_get_modalias(ofdev, buf, PAGE_SIZE); + len = of_device_get_modalias(ofdev, buf, PAGE_SIZE - 2); buf[len] = '\n'; buf[len+1] = 0; @@ -52,6 +52,15 @@ static ssize_t modalias_show (struct device *dev, struct device_attribute *attr, return len+1; } +static ssize_t devspec_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct of_device *ofdev; + + ofdev = to_of_device(dev); + return sprintf(buf, "%s\n", ofdev->node->full_name); +} + macio_config_of_attr (name, "%s\n"); macio_config_of_attr (type, "%s\n"); @@ -60,5 +69,6 @@ struct device_attribute macio_dev_attrs[] = { __ATTR_RO(type), __ATTR_RO(compatible), __ATTR_RO(modalias), + __ATTR_RO(devspec), __ATTR_NULL }; diff --git a/drivers/macintosh/mediabay.c b/drivers/macintosh/mediabay.c index 818aba36854..b1e5b470525 100644 --- a/drivers/macintosh/mediabay.c +++ b/drivers/macintosh/mediabay.c @@ -21,6 +21,7 @@ #include <linux/init.h> #include <linux/ide.h> #include <linux/kthread.h> +#include <linux/mutex.h> #include <asm/prom.h> #include <asm/pgtable.h> #include <asm/io.h> @@ -77,7 +78,7 @@ struct media_bay_info { int index; int cached_gpio; int sleeping; - struct semaphore lock; + struct mutex lock; #ifdef CONFIG_BLK_DEV_IDE_PMAC ide_hwif_t *cd_port; void __iomem *cd_base; @@ -459,27 +460,27 @@ int media_bay_set_ide_infos(struct device_node* which_bay, unsigned long base, if (bay->mdev && which_bay == bay->mdev->ofdev.node) { int timeout = 5000, index = hwif->index; - down(&bay->lock); + mutex_lock(&bay->lock); bay->cd_port = hwif; bay->cd_base = (void __iomem *) base; bay->cd_irq = irq; if ((MB_CD != bay->content_id) || bay->state != mb_up) { - up(&bay->lock); + mutex_unlock(&bay->lock); return 0; } printk(KERN_DEBUG "Registered ide%d for media bay %d\n", index, i); do { if (MB_IDE_READY(i)) { bay->cd_index = index; - up(&bay->lock); + mutex_unlock(&bay->lock); return 0; } mdelay(1); } while(--timeout); printk(KERN_DEBUG "Timeount waiting IDE in bay %d\n", i); - up(&bay->lock); + mutex_unlock(&bay->lock); return -ENODEV; } } @@ -617,10 +618,10 @@ static int media_bay_task(void *x) while (!kthread_should_stop()) { for (i = 0; i < media_bay_count; ++i) { - down(&media_bays[i].lock); + mutex_lock(&media_bays[i].lock); if (!media_bays[i].sleeping) media_bay_step(i); - up(&media_bays[i].lock); + mutex_unlock(&media_bays[i].lock); } msleep_interruptible(MB_POLL_DELAY); @@ -660,7 +661,7 @@ static int __devinit media_bay_attach(struct macio_dev *mdev, const struct of_de bay->index = i; bay->ops = match->data; bay->sleeping = 0; - init_MUTEX(&bay->lock); + mutex_init(&bay->lock); /* Init HW probing */ if (bay->ops->init) @@ -698,10 +699,10 @@ static int media_bay_suspend(struct macio_dev *mdev, pm_message_t state) if (state.event != mdev->ofdev.dev.power.power_state.event && (state.event & PM_EVENT_SLEEP)) { - down(&bay->lock); + mutex_lock(&bay->lock); bay->sleeping = 1; set_mb_power(bay, 0); - up(&bay->lock); + mutex_unlock(&bay->lock); msleep(MB_POLL_DELAY); mdev->ofdev.dev.power.power_state = state; } @@ -720,12 +721,12 @@ static int media_bay_resume(struct macio_dev *mdev) they seem to help the 3400 get it right. */ /* Force MB power to 0 */ - down(&bay->lock); + mutex_lock(&bay->lock); set_mb_power(bay, 0); msleep(MB_POWER_DELAY); if (bay->ops->content(bay) != bay->content_id) { printk("mediabay%d: content changed during sleep...\n", bay->index); - up(&bay->lock); + mutex_unlock(&bay->lock); return 0; } set_mb_power(bay, 1); @@ -741,7 +742,7 @@ static int media_bay_resume(struct macio_dev *mdev) } while((bay->state != mb_empty) && (bay->state != mb_up)); bay->sleeping = 0; - up(&bay->lock); + mutex_unlock(&bay->lock); } return 0; } diff --git a/drivers/macintosh/smu.c b/drivers/macintosh/smu.c index 32cb0298f88..96faa799b82 100644 --- a/drivers/macintosh/smu.c +++ b/drivers/macintosh/smu.c @@ -36,6 +36,8 @@ #include <linux/sysdev.h> #include <linux/poll.h> #include <linux/mutex.h> +#include <linux/of_device.h> +#include <linux/of_platform.h> #include <asm/byteorder.h> #include <asm/io.h> @@ -46,8 +48,6 @@ #include <asm/sections.h> #include <asm/abs_addr.h> #include <asm/uaccess.h> -#include <asm/of_device.h> -#include <asm/of_platform.h> #define VERSION "0.7" #define AUTHOR "(c) 2005 Benjamin Herrenschmidt, IBM Corp." @@ -475,6 +475,7 @@ int __init smu_init (void) { struct device_node *np; const u32 *data; + int ret = 0; np = of_find_node_by_type(NULL, "smu"); if (np == NULL) @@ -484,16 +485,11 @@ int __init smu_init (void) if (smu_cmdbuf_abs == 0) { printk(KERN_ERR "SMU: Command buffer not allocated !\n"); - of_node_put(np); - return -EINVAL; + ret = -EINVAL; + goto fail_np; } smu = alloc_bootmem(sizeof(struct smu_device)); - if (smu == NULL) { - of_node_put(np); - return -ENOMEM; - } - memset(smu, 0, sizeof(*smu)); spin_lock_init(&smu->lock); INIT_LIST_HEAD(&smu->cmd_list); @@ -511,14 +507,14 @@ int __init smu_init (void) smu->db_node = of_find_node_by_name(NULL, "smu-doorbell"); if (smu->db_node == NULL) { printk(KERN_ERR "SMU: Can't find doorbell GPIO !\n"); - goto fail; + ret = -ENXIO; + goto fail_bootmem; } data = of_get_property(smu->db_node, "reg", NULL); if (data == NULL) { - of_node_put(smu->db_node); - smu->db_node = NULL; printk(KERN_ERR "SMU: Can't find doorbell GPIO address !\n"); - goto fail; + ret = -ENXIO; + goto fail_db_node; } /* Current setup has one doorbell GPIO that does both doorbell @@ -552,7 +548,8 @@ int __init smu_init (void) smu->db_buf = ioremap(0x8000860c, 0x1000); if (smu->db_buf == NULL) { printk(KERN_ERR "SMU: Can't map doorbell buffer pointer !\n"); - goto fail; + ret = -ENXIO; + goto fail_msg_node; } /* U3 has an issue with NAP mode when issuing SMU commands */ @@ -563,10 +560,17 @@ int __init smu_init (void) sys_ctrler = SYS_CTRLER_SMU; return 0; - fail: +fail_msg_node: + if (smu->msg_node) + of_node_put(smu->msg_node); +fail_db_node: + of_node_put(smu->db_node); +fail_bootmem: + free_bootmem((unsigned long)smu, sizeof(struct smu_device)); smu = NULL; - return -ENXIO; - +fail_np: + of_node_put(np); + return ret; } diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c index 5366dc93fb3..22bf981d393 100644 --- a/drivers/macintosh/therm_adt746x.c +++ b/drivers/macintosh/therm_adt746x.c @@ -24,13 +24,13 @@ #include <linux/kthread.h> #include <linux/moduleparam.h> #include <linux/freezer.h> +#include <linux/of_platform.h> #include <asm/prom.h> #include <asm/machdep.h> #include <asm/io.h> #include <asm/system.h> #include <asm/sections.h> -#include <asm/of_platform.h> #undef DEBUG diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c index ddfb426a9ab..817607e2af6 100644 --- a/drivers/macintosh/therm_pm72.c +++ b/drivers/macintosh/therm_pm72.c @@ -123,14 +123,14 @@ #include <linux/i2c.h> #include <linux/kthread.h> #include <linux/mutex.h> +#include <linux/of_device.h> +#include <linux/of_platform.h> #include <asm/prom.h> #include <asm/machdep.h> #include <asm/io.h> #include <asm/system.h> #include <asm/sections.h> -#include <asm/of_device.h> #include <asm/macio.h> -#include <asm/of_platform.h> #include "therm_pm72.h" diff --git a/drivers/macintosh/therm_windtunnel.c b/drivers/macintosh/therm_windtunnel.c index d11821af3b8..3da0a02efd7 100644 --- a/drivers/macintosh/therm_windtunnel.c +++ b/drivers/macintosh/therm_windtunnel.c @@ -37,13 +37,13 @@ #include <linux/slab.h> #include <linux/init.h> #include <linux/kthread.h> +#include <linux/of_platform.h> #include <asm/prom.h> #include <asm/machdep.h> #include <asm/io.h> #include <asm/system.h> #include <asm/sections.h> -#include <asm/of_platform.h> #include <asm/macio.h> #define LOG_TEMP 0 /* continously log temperature */ @@ -62,7 +62,7 @@ static struct { volatile int running; struct task_struct *poll_task; - struct semaphore lock; + struct mutex lock; struct of_device *of_dev; struct i2c_client *thermostat; @@ -286,23 +286,23 @@ restore_regs( void ) static int control_loop(void *dummy) { - down(&x.lock); + mutex_lock(&x.lock); setup_hardware(); - up(&x.lock); + mutex_unlock(&x.lock); for (;;) { msleep_interruptible(8000); if (kthread_should_stop()) break; - down(&x.lock); + mutex_lock(&x.lock); poll_temp(); - up(&x.lock); + mutex_unlock(&x.lock); } - down(&x.lock); + mutex_lock(&x.lock); restore_regs(); - up(&x.lock); + mutex_unlock(&x.lock); return 0; } @@ -489,7 +489,7 @@ g4fan_init( void ) const struct apple_thermal_info *info; struct device_node *np; - init_MUTEX( &x.lock ); + mutex_init(&x.lock); if( !(np=of_find_node_by_name(NULL, "power-mgt")) ) return -ENODEV; diff --git a/drivers/macintosh/via-pmu68k.c b/drivers/macintosh/via-pmu68k.c index e2f84da09e7..b64741c95ac 100644 --- a/drivers/macintosh/via-pmu68k.c +++ b/drivers/macintosh/via-pmu68k.c @@ -101,7 +101,6 @@ static int pmu_kind = PMU_UNKNOWN; static int pmu_fully_inited; int asleep; -BLOCKING_NOTIFIER_HEAD(sleep_notifier_list); static int pmu_probe(void); static int pmu_init(void); @@ -741,8 +740,8 @@ pmu_handle_data(unsigned char *data, int len) } } -int backlight_level = -1; -int backlight_enabled = 0; +static int backlight_level = -1; +static int backlight_enabled = 0; #define LEVEL_TO_BRIGHT(lev) ((lev) < 1? 0x7f: 0x4a - ((lev) << 1)) diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 45a41b597da..2683ee32fc1 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -1884,7 +1884,6 @@ config NE_H8300 Say Y here if you want to use the NE2000 compatible controller on the Renesas H8/300 processor. -source "drivers/net/fec_8xx/Kconfig" source "drivers/net/fs_enet/Kconfig" endif # NET_ETHERNET diff --git a/drivers/net/Makefile b/drivers/net/Makefile index dcbfe842115..9010e58da0f 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -217,7 +217,6 @@ obj-$(CONFIG_SMC91X) += smc91x.o obj-$(CONFIG_SMC911X) += smc911x.o obj-$(CONFIG_BFIN_MAC) += bfin_mac.o obj-$(CONFIG_DM9000) += dm9000.o -obj-$(CONFIG_FEC_8XX) += fec_8xx/ obj-$(CONFIG_PASEMI_MAC) += pasemi_mac_driver.o pasemi_mac_driver-objs := pasemi_mac.o pasemi_mac_ethtool.o obj-$(CONFIG_MLX4_CORE) += mlx4/ diff --git a/drivers/net/fec_8xx/Kconfig b/drivers/net/fec_8xx/Kconfig deleted file mode 100644 index afb34ded26e..00000000000 --- a/drivers/net/fec_8xx/Kconfig +++ /dev/null @@ -1,20 +0,0 @@ -config FEC_8XX - tristate "Motorola 8xx FEC driver" - depends on 8XX - select MII - -config FEC_8XX_GENERIC_PHY - bool "Support any generic PHY" - depends on FEC_8XX - default y - -config FEC_8XX_DM9161_PHY - bool "Support DM9161 PHY" - depends on FEC_8XX - default n - -config FEC_8XX_LXT971_PHY - bool "Support LXT971/LXT972 PHY" - depends on FEC_8XX - default n - diff --git a/drivers/net/fec_8xx/Makefile b/drivers/net/fec_8xx/Makefile deleted file mode 100644 index 70c54f8c48e..00000000000 --- a/drivers/net/fec_8xx/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -# -# Makefile for the Motorola 8xx FEC ethernet controller -# - -obj-$(CONFIG_FEC_8XX) += fec_8xx.o - -fec_8xx-objs := fec_main.o fec_mii.o - -# the platform instantatiation objects -ifeq ($(CONFIG_NETTA),y) -fec_8xx-objs += fec_8xx-netta.o -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 79deee222e2..00000000000 --- a/drivers/net/fec_8xx/fec_8xx-netta.c +++ /dev/null @@ -1,151 +0,0 @@ -/* - * FEC instantatiation file for NETTA - */ - -#include <linux/kernel.h> -#include <linux/types.h> -#include <linux/string.h> -#include <linux/ptrace.h> -#include <linux/errno.h> -#include <linux/ioport.h> -#include <linux/slab.h> -#include <linux/interrupt.h> -#include <linux/pci.h> -#include <linux/init.h> -#include <linux/delay.h> -#include <linux/netdevice.h> -#include <linux/etherdevice.h> -#include <linux/skbuff.h> -#include <linux/spinlock.h> -#include <linux/mii.h> -#include <linux/ethtool.h> -#include <linux/bitops.h> - -#include <asm/8xx_immap.h> -#include <asm/pgtable.h> -#include <asm/mpc8xx.h> -#include <asm/irq.h> -#include <asm/uaccess.h> -#include <asm/cpm1.h> - -#include "fec_8xx.h" - -/*************************************************/ - -static struct fec_platform_info fec1_info = { - .fec_no = 0, - .use_mdio = 1, - .phy_addr = 8, - .fec_irq = SIU_LEVEL1, - .phy_irq = CPM_IRQ_OFFSET + CPMVEC_PIO_PC6, - .rx_ring = 128, - .tx_ring = 16, - .rx_copybreak = 240, - .use_napi = 1, - .napi_weight = 17, -}; - -static struct fec_platform_info fec2_info = { - .fec_no = 1, - .use_mdio = 1, - .phy_addr = 2, - .fec_irq = SIU_LEVEL3, - .phy_irq = CPM_IRQ_OFFSET + CPMVEC_PIO_PC7, - .rx_ring = 128, - .tx_ring = 16, - .rx_copybreak = 240, - .use_napi = 1, - .napi_weight = 17, -}; - -static struct net_device *fec1_dev; -static struct net_device *fec2_dev; - -/* XXX custom u-boot & Linux startup needed */ -extern const char *__fw_getenv(const char *var); - -/* access ports */ -#define setbits32(_addr, _v) __fec_out32(&(_addr), __fec_in32(&(_addr)) | (_v)) -#define clrbits32(_addr, _v) __fec_out32(&(_addr), __fec_in32(&(_addr)) & ~(_v)) - -#define setbits16(_addr, _v) __fec_out16(&(_addr), __fec_in16(&(_addr)) | (_v)) -#define clrbits16(_addr, _v) __fec_out16(&(_addr), __fec_in16(&(_addr)) & ~(_v)) - -int fec_8xx_platform_init(void) -{ - immap_t *immap = (immap_t *)IMAP_ADDR; - bd_t *bd = (bd_t *) __res; - const char *s; - char *e; - int i; - - /* use MDC for MII */ - setbits16(immap->im_ioport.iop_pdpar, 0x0080); - clrbits16(immap->im_ioport.iop_pddir, 0x0080); - - /* configure FEC1 pins */ - setbits16(immap->im_ioport.iop_papar, 0xe810); - setbits16(immap->im_ioport.iop_padir, 0x0810); - clrbits16(immap->im_ioport.iop_padir, 0xe000); - - setbits32(immap->im_cpm.cp_pbpar, 0x00000001); - clrbits32(immap->im_cpm.cp_pbdir, 0x00000001); - - setbits32(immap->im_cpm.cp_cptr, 0x00000100); - clrbits32(immap->im_cpm.cp_cptr, 0x00000050); - - clrbits16(immap->im_ioport.iop_pcpar, 0x0200); - clrbits16(immap->im_ioport.iop_pcdir, 0x0200); - clrbits16(immap->im_ioport.iop_pcso, 0x0200); - setbits16(immap->im_ioport.iop_pcint, 0x0200); - - /* configure FEC2 pins */ - setbits32(immap->im_cpm.cp_pepar, 0x00039620); - setbits32(immap->im_cpm.cp_pedir, 0x00039620); - setbits32(immap->im_cpm.cp_peso, 0x00031000); - clrbits32(immap->im_cpm.cp_peso, 0x00008620); - - setbits32(immap->im_cpm.cp_cptr, 0x00000080); - clrbits32(immap->im_cpm.cp_cptr, 0x00000028); - - clrbits16(immap->im_ioport.iop_pcpar, 0x0200); - clrbits16(immap->im_ioport.iop_pcdir, 0x0200); - clrbits16(immap->im_ioport.iop_pcso, 0x0200); - setbits16(immap->im_ioport.iop_pcint, 0x0200); - - /* fill up */ - fec1_info.sys_clk = bd->bi_intfreq; - fec2_info.sys_clk = bd->bi_intfreq; - - s = __fw_getenv("ethaddr"); - if (s != NULL) { - for (i = 0; i < 6; i++) { - fec1_info.macaddr[i] = simple_strtoul(s, &e, 16); - if (*e) - s = e + 1; - } - } - - s = __fw_getenv("eth1addr"); - if (s != NULL) { - for (i = 0; i < 6; i++) { - fec2_info.macaddr[i] = simple_strtoul(s, &e, 16); - if (*e) - s = e + 1; - } - } - - fec_8xx_init_one(&fec1_info, &fec1_dev); - fec_8xx_init_one(&fec2_info, &fec2_dev); - - return fec1_dev != NULL && fec2_dev != NULL ? 0 : -1; -} - -void fec_8xx_platform_cleanup(void) -{ - if (fec2_dev != NULL) - fec_8xx_cleanup_one(fec2_dev); - - if (fec1_dev != NULL) - fec_8xx_cleanup_one(fec1_dev); -} diff --git a/drivers/net/fec_8xx/fec_8xx.h b/drivers/net/fec_8xx/fec_8xx.h deleted file mode 100644 index f3b1c6fbba8..00000000000 --- a/drivers/net/fec_8xx/fec_8xx.h +++ /dev/null @@ -1,220 +0,0 @@ -#ifndef FEC_8XX_H -#define FEC_8XX_H - -#include <linux/mii.h> -#include <linux/netdevice.h> - -#include <linux/types.h> - -/* HW info */ - -/* CRC polynomium used by the FEC for the multicast group filtering */ -#define FEC_CRC_POLY 0x04C11DB7 - -#define MII_ADVERTISE_HALF (ADVERTISE_100HALF | \ - ADVERTISE_10HALF | ADVERTISE_CSMA) -#define MII_ADVERTISE_ALL (ADVERTISE_100FULL | \ - ADVERTISE_10FULL | MII_ADVERTISE_HALF) - -/* Interrupt events/masks. -*/ -#define FEC_ENET_HBERR 0x80000000U /* Heartbeat error */ -#define FEC_ENET_BABR 0x40000000U /* Babbling receiver */ -#define FEC_ENET_BABT 0x20000000U /* Babbling transmitter */ -#define FEC_ENET_GRA 0x10000000U /* Graceful stop complete */ -#define FEC_ENET_TXF 0x08000000U /* Full frame transmitted */ -#define FEC_ENET_TXB 0x04000000U /* A buffer was transmitted */ -#define FEC_ENET_RXF 0x02000000U /* Full frame received */ -#define FEC_ENET_RXB 0x01000000U /* A buffer was received */ -#define FEC_ENET_MII 0x00800000U /* MII interrupt */ -#define FEC_ENET_EBERR 0x00400000U /* SDMA bus error */ - -#define FEC_ECNTRL_PINMUX 0x00000004 -#define FEC_ECNTRL_ETHER_EN 0x00000002 -#define FEC_ECNTRL_RESET 0x00000001 - -#define FEC_RCNTRL_BC_REJ 0x00000010 -#define FEC_RCNTRL_PROM 0x00000008 -#define FEC_RCNTRL_MII_MODE 0x00000004 -#define FEC_RCNTRL_DRT 0x00000002 -#define FEC_RCNTRL_LOOP 0x00000001 - -#define FEC_TCNTRL_FDEN 0x00000004 -#define FEC_TCNTRL_HBC 0x00000002 -#define FEC_TCNTRL_GTS 0x00000001 - -/* values for MII phy_status */ - -#define PHY_CONF_ANE 0x0001 /* 1 auto-negotiation enabled */ -#define PHY_CONF_LOOP 0x0002 /* 1 loopback mode enabled */ -#define PHY_CONF_SPMASK 0x00f0 /* mask for speed */ -#define PHY_CONF_10HDX 0x0010 /* 10 Mbit half duplex supported */ -#define PHY_CONF_10FDX 0x0020 /* 10 Mbit full duplex supported */ -#define PHY_CONF_100HDX 0x0040 /* 100 Mbit half duplex supported */ -#define PHY_CONF_100FDX 0x0080 /* 100 Mbit full duplex supported */ - -#define PHY_STAT_LINK 0x0100 /* 1 up - 0 down */ -#define PHY_STAT_FAULT 0x0200 /* 1 remote fault */ -#define PHY_STAT_ANC 0x0400 /* 1 auto-negotiation complete */ -#define PHY_STAT_SPMASK 0xf000 /* mask for speed */ -#define PHY_STAT_10HDX 0x1000 /* 10 Mbit half duplex selected */ -#define PHY_STAT_10FDX 0x2000 /* 10 Mbit full duplex selected */ -#define PHY_STAT_100HDX 0x4000 /* 100 Mbit half duplex selected */ -#define PHY_STAT_100FDX 0x8000 /* 100 Mbit full duplex selected */ - -typedef struct phy_info { - unsigned int id; - const char *name; - void (*startup) (struct net_device * dev); - void (*shutdown) (struct net_device * dev); - void (*ack_int) (struct net_device * dev); -} phy_info_t; - -/* The FEC stores dest/src/type, data, and checksum for receive packets. - */ -#define MAX_MTU 1508 /* Allow fullsized pppoe packets over VLAN */ -#define MIN_MTU 46 /* this is data size */ -#define CRC_LEN 4 - -#define PKT_MAXBUF_SIZE (MAX_MTU+ETH_HLEN+CRC_LEN) -#define PKT_MINBUF_SIZE (MIN_MTU+ETH_HLEN+CRC_LEN) - -/* Must be a multiple of 4 */ -#define PKT_MAXBLR_SIZE ((PKT_MAXBUF_SIZE+3) & ~3) -/* This is needed so that invalidate_xxx wont invalidate too much */ -#define ENET_RX_FRSIZE L1_CACHE_ALIGN(PKT_MAXBUF_SIZE) - -/* platform interface */ - -struct fec_platform_info { - int fec_no; /* FEC index */ - int use_mdio; /* use external MII */ - int phy_addr; /* the phy address */ - int fec_irq, phy_irq; /* the irq for the controller */ - int rx_ring, tx_ring; /* number of buffers on rx */ - int sys_clk; /* system clock */ - __u8 macaddr[6]; /* mac address */ - int rx_copybreak; /* limit we copy small frames */ - int use_napi; /* use NAPI */ - int napi_weight; /* NAPI weight */ -}; - -/* forward declaration */ -struct fec; - -struct fec_enet_private { - spinlock_t lock; /* during all ops except TX pckt processing */ - spinlock_t tx_lock; /* during fec_start_xmit and fec_tx */ - struct net_device *dev; - struct napi_struct napi; - int fecno; - struct fec *fecp; - const struct fec_platform_info *fpi; - int rx_ring, tx_ring; - dma_addr_t ring_mem_addr; - void *ring_base; - struct sk_buff **rx_skbuff; - struct sk_buff **tx_skbuff; - cbd_t *rx_bd_base; /* Address of Rx and Tx buffers. */ - cbd_t *tx_bd_base; - cbd_t *dirty_tx; /* ring entries to be free()ed. */ - cbd_t *cur_rx; - cbd_t *cur_tx; - int tx_free; - struct net_device_stats stats; - struct timer_list phy_timer_list; - const struct phy_info *phy; - unsigned int fec_phy_speed; - __u32 msg_enable; - struct mii_if_info mii_if; -}; - -/***************************************************************************/ - -void fec_restart(struct net_device *dev, int duplex, int speed); -void fec_stop(struct net_device *dev); - -/***************************************************************************/ - -int fec_mii_read(struct net_device *dev, int phy_id, int location); -void fec_mii_write(struct net_device *dev, int phy_id, int location, int value); - -int fec_mii_phy_id_detect(struct net_device *dev); -void fec_mii_startup(struct net_device *dev); -void fec_mii_shutdown(struct net_device *dev); -void fec_mii_ack_int(struct net_device *dev); - -void fec_mii_link_status_change_check(struct net_device *dev, int init_media); - -/***************************************************************************/ - -#define FEC1_NO 0x00 -#define FEC2_NO 0x01 -#define FEC3_NO 0x02 - -int fec_8xx_init_one(const struct fec_platform_info *fpi, - struct net_device **devp); -int fec_8xx_cleanup_one(struct net_device *dev); - -/***************************************************************************/ - -#define DRV_MODULE_NAME "fec_8xx" -#define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "0.1" -#define DRV_MODULE_RELDATE "May 6, 2004" - -/***************************************************************************/ - -int fec_8xx_platform_init(void); -void fec_8xx_platform_cleanup(void); - -/***************************************************************************/ - -/* FEC access macros */ -#if defined(CONFIG_8xx) -/* for a 8xx __raw_xxx's are sufficient */ -#define __fec_out32(addr, x) __raw_writel(x, addr) -#define __fec_out16(addr, x) __raw_writew(x, addr) -#define __fec_in32(addr) __raw_readl(addr) -#define __fec_in16(addr) __raw_readw(addr) -#else -/* for others play it safe */ -#define __fec_out32(addr, x) out_be32(addr, x) -#define __fec_out16(addr, x) out_be16(addr, x) -#define __fec_in32(addr) in_be32(addr) -#define __fec_in16(addr) in_be16(addr) -#endif - -/* write */ -#define FW(_fecp, _reg, _v) __fec_out32(&(_fecp)->fec_ ## _reg, (_v)) - -/* read */ -#define FR(_fecp, _reg) __fec_in32(&(_fecp)->fec_ ## _reg) - -/* set bits */ -#define FS(_fecp, _reg, _v) FW(_fecp, _reg, FR(_fecp, _reg) | (_v)) - -/* clear bits */ -#define FC(_fecp, _reg, _v) FW(_fecp, _reg, FR(_fecp, _reg) & ~(_v)) - -/* buffer descriptor access macros */ - -/* write */ -#define CBDW_SC(_cbd, _sc) __fec_out16(&(_cbd)->cbd_sc, (_sc)) -#define CBDW_DATLEN(_cbd, _datlen) __fec_out16(&(_cbd)->cbd_datlen, (_datlen)) -#define CBDW_BUFADDR(_cbd, _bufaddr) __fec_out32(&(_cbd)->cbd_bufaddr, (_bufaddr)) - -/* read */ -#define CBDR_SC(_cbd) __fec_in16(&(_cbd)->cbd_sc) -#define CBDR_DATLEN(_cbd) __fec_in16(&(_cbd)->cbd_datlen) -#define CBDR_BUFADDR(_cbd) __fec_in32(&(_cbd)->cbd_bufaddr) - -/* set bits */ -#define CBDS_SC(_cbd, _sc) CBDW_SC(_cbd, CBDR_SC(_cbd) | (_sc)) - -/* clear bits */ -#define CBDC_SC(_cbd, _sc) CBDW_SC(_cbd, CBDR_SC(_cbd) & ~(_sc)) - -/***************************************************************************/ - -#endif diff --git a/drivers/net/fec_8xx/fec_main.c b/drivers/net/fec_8xx/fec_main.c deleted file mode 100644 index ca8d2e83ab0..00000000000 --- a/drivers/net/fec_8xx/fec_main.c +++ /dev/null @@ -1,1264 +0,0 @@ -/* - * Fast Ethernet Controller (FEC) driver for Motorola MPC8xx. - * - * Copyright (c) 2003 Intracom S.A. - * by Pantelis Antoniou <panto@intracom.gr> - * - * Heavily based on original FEC driver by Dan Malek <dan@embeddededge.com> - * and modifications by Joakim Tjernlund <joakim.tjernlund@lumentis.se> - * - * Released under the GPL - */ - -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/types.h> -#include <linux/string.h> -#include <linux/ptrace.h> -#include <linux/errno.h> -#include <linux/ioport.h> -#include <linux/slab.h> -#include <linux/interrupt.h> -#include <linux/init.h> -#include <linux/delay.h> -#include <linux/netdevice.h> -#include <linux/etherdevice.h> -#include <linux/skbuff.h> -#include <linux/spinlock.h> -#include <linux/mii.h> -#include <linux/ethtool.h> -#include <linux/bitops.h> -#include <linux/dma-mapping.h> - -#include <asm/8xx_immap.h> -#include <asm/pgtable.h> -#include <asm/mpc8xx.h> -#include <asm/irq.h> -#include <asm/uaccess.h> -#include <asm/cpm1.h> - -#include "fec_8xx.h" - -/*************************************************/ - -#define FEC_MAX_MULTICAST_ADDRS 64 - -/*************************************************/ - -static char version[] __devinitdata = - DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")" "\n"; - -MODULE_AUTHOR("Pantelis Antoniou <panto@intracom.gr>"); -MODULE_DESCRIPTION("Motorola 8xx FEC ethernet driver"); -MODULE_LICENSE("GPL"); - -int fec_8xx_debug = -1; /* -1 == use FEC_8XX_DEF_MSG_ENABLE as value */ -module_param(fec_8xx_debug, int, 0); -MODULE_PARM_DESC(fec_8xx_debug, - "FEC 8xx bitmapped debugging message enable value"); - - -/*************************************************/ - -/* - * Delay to wait for FEC reset command to complete (in us) - */ -#define FEC_RESET_DELAY 50 - -/*****************************************************************************************/ - -static void fec_whack_reset(fec_t * fecp) -{ - int i; - - /* - * Whack a reset. We should wait for this. - */ - FW(fecp, ecntrl, FEC_ECNTRL_PINMUX | FEC_ECNTRL_RESET); - for (i = 0; - (FR(fecp, ecntrl) & FEC_ECNTRL_RESET) != 0 && i < FEC_RESET_DELAY; - i++) - udelay(1); - - if (i == FEC_RESET_DELAY) - printk(KERN_WARNING "FEC Reset timeout!\n"); - -} - -/****************************************************************************/ - -/* - * Transmitter timeout. - */ -#define TX_TIMEOUT (2*HZ) - -/****************************************************************************/ - -/* - * Returns the CRC needed when filling in the hash table for - * multicast group filtering - * pAddr must point to a MAC address (6 bytes) - */ -static __u32 fec_mulicast_calc_crc(char *pAddr) -{ - u8 byte; - int byte_count; - int bit_count; - __u32 crc = 0xffffffff; - u8 msb; - - for (byte_count = 0; byte_count < 6; byte_count++) { - byte = pAddr[byte_count]; - for (bit_count = 0; bit_count < 8; bit_count++) { - msb = crc >> 31; - crc <<= 1; - if (msb ^ (byte & 0x1)) { - crc ^= FEC_CRC_POLY; - } - byte >>= 1; - } - } - return (crc); -} - -/* - * Set or clear the multicast filter for this adaptor. - * Skeleton taken from sunlance driver. - * The CPM Ethernet implementation allows Multicast as well as individual - * MAC address filtering. Some of the drivers check to make sure it is - * a group multicast address, and discard those that are not. I guess I - * will do the same for now, but just remove the test if you want - * individual filtering as well (do the upper net layers want or support - * this kind of feature?). - */ -static void fec_set_multicast_list(struct net_device *dev) -{ - struct fec_enet_private *fep = netdev_priv(dev); - fec_t *fecp = fep->fecp; - struct dev_mc_list *pmc; - __u32 crc; - int temp; - __u32 csrVal; - int hash_index; - __u32 hthi, htlo; - unsigned long flags; - - - if ((dev->flags & IFF_PROMISC) != 0) { - - spin_lock_irqsave(&fep->lock, flags); - FS(fecp, r_cntrl, FEC_RCNTRL_PROM); - spin_unlock_irqrestore(&fep->lock, flags); - - /* - * Log any net taps. - */ - printk(KERN_WARNING DRV_MODULE_NAME - ": %s: Promiscuous mode enabled.\n", dev->name); - return; - - } - - if ((dev->flags & IFF_ALLMULTI) != 0 || - dev->mc_count > FEC_MAX_MULTICAST_ADDRS) { - /* - * Catch all multicast addresses, set the filter to all 1's. - */ - hthi = 0xffffffffU; - htlo = 0xffffffffU; - } else { - hthi = 0; - htlo = 0; - - /* - * Now populate the hash table - */ - for (pmc = dev->mc_list; pmc != NULL; pmc = pmc->next) { - crc = fec_mulicast_calc_crc(pmc->dmi_addr); - temp = (crc & 0x3f) >> 1; - hash_index = ((temp & 0x01) << 4) | - ((temp & 0x02) << 2) | - ((temp & 0x04)) | - ((temp & 0x08) >> 2) | - ((temp & 0x10) >> 4); - csrVal = (1 << hash_index); - if (crc & 1) - hthi |= csrVal; - else - htlo |= csrVal; - } - } - - spin_lock_irqsave(&fep->lock, flags); - FC(fecp, r_cntrl, FEC_RCNTRL_PROM); - FW(fecp, hash_table_high, hthi); - FW(fecp, hash_table_low, htlo); - spin_unlock_irqrestore(&fep->lock, flags); -} - -static int fec_set_mac_address(struct net_device *dev, void *addr) -{ - struct sockaddr *mac = addr; - struct fec_enet_private *fep = netdev_priv(dev); - struct fec *fecp = fep->fecp; - int i; - __u32 addrhi, addrlo; - unsigned long flags; - - /* Get pointer to SCC area in parameter RAM. */ - for (i = 0; i < 6; i++) - dev->dev_addr[i] = mac->sa_data[i]; - - /* - * Set station address. - */ - addrhi = ((__u32) dev->dev_addr[0] << 24) | - ((__u32) dev->dev_addr[1] << 16) | - ((__u32) dev->dev_addr[2] << 8) | - (__u32) dev->dev_addr[3]; - addrlo = ((__u32) dev->dev_addr[4] << 24) | - ((__u32) dev->dev_addr[5] << 16); - - spin_lock_irqsave(&fep->lock, flags); - FW(fecp, addr_low, addrhi); - FW(fecp, addr_high, addrlo); - spin_unlock_irqrestore(&fep->lock, flags); - - return 0; -} - -/* - * This function is called to start or restart the FEC during a link - * change. This only happens when switching between half and full - * duplex. - */ -void fec_restart(struct net_device *dev, int duplex, int speed) -{ -#ifdef CONFIG_DUET - immap_t *immap = (immap_t *) IMAP_ADDR; - __u32 cptr; -#endif - struct fec_enet_private *fep = netdev_priv(dev); - struct fec *fecp = fep->fecp; - const struct fec_platform_info *fpi = fep->fpi; - cbd_t *bdp; - struct sk_buff *skb; - int i; - __u32 addrhi, addrlo; - - fec_whack_reset(fep->fecp); - - /* - * Set station address. - */ - addrhi = ((__u32) dev->dev_addr[0] << 24) | - ((__u32) dev->dev_addr[1] << 16) | - ((__u32) dev->dev_addr[2] << 8) | - (__u32) dev->dev_addr[3]; - addrlo = ((__u32) dev->dev_addr[4] << 24) | - ((__u32) dev->dev_addr[5] << 16); - FW(fecp, addr_low, addrhi); - FW(fecp, addr_high, addrlo); - - /* - * Reset all multicast. - */ - FW(fecp, hash_table_high, 0); - FW(fecp, hash_table_low, 0); - - /* - * Set maximum receive buffer size. - */ - FW(fecp, r_buff_size, PKT_MAXBLR_SIZE); - FW(fecp, r_hash, PKT_MAXBUF_SIZE); - - /* - * Set receive and transmit descriptor base. - */ - FW(fecp, r_des_start, iopa((__u32) (fep->rx_bd_base))); - FW(fecp, x_des_start, iopa((__u32) (fep->tx_bd_base))); - - fep->dirty_tx = fep->cur_tx = fep->tx_bd_base; - fep->tx_free = fep->tx_ring; - fep->cur_rx = fep->rx_bd_base; - - /* - * Reset SKB receive buffers - */ - for (i = 0; i < fep->rx_ring; i++) { - if ((skb = fep->rx_skbuff[i]) == NULL) - continue; - fep->rx_skbuff[i] = NULL; - dev_kfree_skb(skb); - } - - /* - * Initialize the receive buffer descriptors. - */ - for (i = 0, bdp = fep->rx_bd_base; i < fep->rx_ring; i++, bdp++) { - skb = dev_alloc_skb(ENET_RX_FRSIZE); - if (skb == NULL) { - printk(KERN_WARNING DRV_MODULE_NAME - ": %s Memory squeeze, unable to allocate skb\n", - dev->name); - fep->stats.rx_dropped++; - break; - } - fep->rx_skbuff[i] = skb; - skb->dev = dev; - CBDW_BUFADDR(bdp, dma_map_single(NULL, skb->data, - L1_CACHE_ALIGN(PKT_MAXBUF_SIZE), - DMA_FROM_DEVICE)); - CBDW_DATLEN(bdp, 0); /* zero */ - CBDW_SC(bdp, BD_ENET_RX_EMPTY | - ((i < fep->rx_ring - 1) ? 0 : BD_SC_WRAP)); - } - /* - * if we failed, fillup remainder - */ - for (; i < fep->rx_ring; i++, bdp++) { - fep->rx_skbuff[i] = NULL; - CBDW_SC(bdp, (i < fep->rx_ring - 1) ? 0 : BD_SC_WRAP); - } - - /* - * Reset SKB transmit buffers. - */ - for (i = 0; i < fep->tx_ring; i++) { - if ((skb = fep->tx_skbuff[i]) == NULL) - continue; - fep->tx_skbuff[i] = NULL; - dev_kfree_skb(skb); - } - - /* - * ...and the same for transmit. - */ - for (i = 0, bdp = fep->tx_bd_base; i < fep->tx_ring; i++, bdp++) { - fep->tx_skbuff[i] = NULL; - CBDW_BUFADDR(bdp, virt_to_bus(NULL)); - CBDW_DATLEN(bdp, 0); - CBDW_SC(bdp, (i < fep->tx_ring - 1) ? 0 : BD_SC_WRAP); - } - - /* - * Enable big endian and don't care about SDMA FC. - */ - FW(fecp, fun_code, 0x78000000); - - /* - * Set MII speed. - */ - FW(fecp, mii_speed, fep->fec_phy_speed); - - /* - * Clear any outstanding interrupt. - */ - FW(fecp, ievent, 0xffc0); - FW(fecp, ivec, (fpi->fec_irq / 2) << 29); - - /* - * adjust to speed (only for DUET & RMII) - */ -#ifdef CONFIG_DUET - cptr = in_be32(&immap->im_cpm.cp_cptr); - switch (fpi->fec_no) { - case 0: - /* - * check if in RMII mode - */ - if ((cptr & 0x100) == 0) - break; - - if (speed == 10) - cptr |= 0x0000010; - else if (speed == 100) - cptr &= ~0x0000010; - break; - case 1: - /* - * check if in RMII mode - */ - if ((cptr & 0x80) == 0) - break; - - if (speed == 10) - cptr |= 0x0000008; - else if (speed == 100) - cptr &= ~0x0000008; - break; - default: - break; - } - out_be32(&immap->im_cpm.cp_cptr, cptr); -#endif - - FW(fecp, r_cntrl, FEC_RCNTRL_MII_MODE); /* MII enable */ - /* - * adjust to duplex mode - */ - if (duplex) { - FC(fecp, r_cntrl, FEC_RCNTRL_DRT); - FS(fecp, x_cntrl, FEC_TCNTRL_FDEN); /* FD enable */ - } else { - FS(fecp, r_cntrl, FEC_RCNTRL_DRT); - FC(fecp, x_cntrl, FEC_TCNTRL_FDEN); /* FD disable */ - } - - /* - * Enable interrupts we wish to service. - */ - FW(fecp, imask, FEC_ENET_TXF | FEC_ENET_TXB | - FEC_ENET_RXF | FEC_ENET_RXB); - - /* - * And last, enable the transmit and receive processing. - */ - FW(fecp, ecntrl, FEC_ECNTRL_PINMUX | FEC_ECNTRL_ETHER_EN); - FW(fecp, r_des_active, 0x01000000); -} - -void fec_stop(struct net_device *dev) -{ - struct fec_enet_private *fep = netdev_priv(dev); - fec_t *fecp = fep->fecp; - struct sk_buff *skb; - int i; - - if ((FR(fecp, ecntrl) & FEC_ECNTRL_ETHER_EN) == 0) - return; /* already down */ - - FW(fecp, x_cntrl, 0x01); /* Graceful transmit stop */ - for (i = 0; ((FR(fecp, ievent) & 0x10000000) == 0) && - i < FEC_RESET_DELAY; i++) - udelay(1); - - if (i == FEC_RESET_DELAY) - printk(KERN_WARNING DRV_MODULE_NAME - ": %s FEC timeout on graceful transmit stop\n", - dev->name); - /* - * Disable FEC. Let only MII interrupts. - */ - FW(fecp, imask, 0); - FW(fecp, ecntrl, ~FEC_ECNTRL_ETHER_EN); - - /* - * Reset SKB transmit buffers. - */ - for (i = 0; i < fep->tx_ring; i++) { - if ((skb = fep->tx_skbuff[i]) == NULL) - continue; - fep->tx_skbuff[i] = NULL; - dev_kfree_skb(skb); - } - - /* - * Reset SKB receive buffers - */ - for (i = 0; i < fep->rx_ring; i++) { - if ((skb = fep->rx_skbuff[i]) == NULL) - continue; - fep->rx_skbuff[i] = NULL; - dev_kfree_skb(skb); - } -} - -/* common receive function */ -static int fec_enet_rx_common(struct fec_enet_private *ep, - struct net_device *dev, int budget) -{ - fec_t *fecp = fep->fecp; - const struct fec_platform_info *fpi = fep->fpi; - cbd_t *bdp; - struct sk_buff *skb, *skbn, *skbt; - int received = 0; - __u16 pkt_len, sc; - int curidx; - - /* - * First, grab all of the stats for the incoming packet. - * These get messed up if we get called due to a busy condition. - */ - bdp = fep->cur_rx; - - /* clear RX status bits for napi*/ - if (fpi->use_napi) - FW(fecp, ievent, FEC_ENET_RXF | FEC_ENET_RXB); - - while (((sc = CBDR_SC(bdp)) & BD_ENET_RX_EMPTY) == 0) { - - curidx = bdp - fep->rx_bd_base; - - /* - * Since we have allocated space to hold a complete frame, - * the last indicator should be set. - */ - if ((sc & BD_ENET_RX_LAST) == 0) - printk(KERN_WARNING DRV_MODULE_NAME - ": %s rcv is not +last\n", - dev->name); - - /* - * Check for errors. - */ - if (sc & (BD_ENET_RX_LG | BD_ENET_RX_SH | BD_ENET_RX_CL | - BD_ENET_RX_NO | BD_ENET_RX_CR | BD_ENET_RX_OV)) { - fep->stats.rx_errors++; - /* Frame too long or too short. */ - if (sc & (BD_ENET_RX_LG | BD_ENET_RX_SH)) - fep->stats.rx_length_errors++; - /* Frame alignment */ - if (sc & (BD_ENET_RX_NO | BD_ENET_RX_CL)) - fep->stats.rx_frame_errors++; - /* CRC Error */ - if (sc & BD_ENET_RX_CR) - fep->stats.rx_crc_errors++; - /* FIFO overrun */ - if (sc & BD_ENET_RX_OV) - fep->stats.rx_crc_errors++; - - skbn = fep->rx_skbuff[curidx]; - BUG_ON(skbn == NULL); - - } else { - skb = fep->rx_skbuff[curidx]; - BUG_ON(skb == NULL); - - /* - * Process the incoming frame. - */ - fep->stats.rx_packets++; - pkt_len = CBDR_DATLEN(bdp) - 4; /* remove CRC */ - fep->stats.rx_bytes += pkt_len + 4; - - if (pkt_len <= fpi->rx_copybreak) { - /* +2 to make IP header L1 cache aligned */ - skbn = dev_alloc_skb(pkt_len + 2); - if (skbn != NULL) { - skb_reserve(skbn, 2); /* align IP header */ - skb_copy_from_linear_data(skb, - skbn->data, - pkt_len); - /* swap */ - skbt = skb; - skb = skbn; - skbn = skbt; - } - } else - skbn = dev_alloc_skb(ENET_RX_FRSIZE); - - if (skbn != NULL) { - skb_put(skb, pkt_len); /* Make room */ - skb->protocol = eth_type_trans(skb, dev); - received++; - if (!fpi->use_napi) - netif_rx(skb); - else - netif_receive_skb(skb); - } else { - printk(KERN_WARNING DRV_MODULE_NAME - ": %s Memory squeeze, dropping packet.\n", - dev->name); - fep->stats.rx_dropped++; - skbn = skb; - } - } - - fep->rx_skbuff[curidx] = skbn; - CBDW_BUFADDR(bdp, dma_map_single(NULL, skbn->data, - L1_CACHE_ALIGN(PKT_MAXBUF_SIZE), - DMA_FROM_DEVICE)); - CBDW_DATLEN(bdp, 0); - CBDW_SC(bdp, (sc & ~BD_ENET_RX_STATS) | BD_ENET_RX_EMPTY); - - /* - * Update BD pointer to next entry. - */ - if ((sc & BD_ENET_RX_WRAP) == 0) - bdp++; - else - bdp = fep->rx_bd_base; - - /* - * Doing this here will keep the FEC running while we process - * incoming frames. On a heavily loaded network, we should be - * able to keep up at the expense of system resources. - */ - FW(fecp, r_des_active, 0x01000000); - - if (received >= budget) - break; - - } - - fep->cur_rx = bdp; - - if (fpi->use_napi) { - if (received < budget) { - netif_rx_complete(dev, &fep->napi); - - /* enable RX interrupt bits */ - FS(fecp, imask, FEC_ENET_RXF | FEC_ENET_RXB); - } - } - - return received; -} - -static void fec_enet_tx(struct net_device *dev) -{ - struct fec_enet_private *fep = netdev_priv(dev); - cbd_t *bdp; - struct sk_buff *skb; - int dirtyidx, do_wake; - __u16 sc; - - spin_lock(&fep->lock); - bdp = fep->dirty_tx; - - do_wake = 0; - while (((sc = CBDR_SC(bdp)) & BD_ENET_TX_READY) == 0) { - - dirtyidx = bdp - fep->tx_bd_base; - - if (fep->tx_free == fep->tx_ring) - break; - - skb = fep->tx_skbuff[dirtyidx]; - - /* - * Check for errors. - */ - if (sc & (BD_ENET_TX_HB | BD_ENET_TX_LC | - BD_ENET_TX_RL | BD_ENET_TX_UN | BD_ENET_TX_CSL)) { - fep->stats.tx_errors++; - if (sc & BD_ENET_TX_HB) /* No heartbeat */ - fep->stats.tx_heartbeat_errors++; - if (sc & BD_ENET_TX_LC) /* Late collision */ - fep->stats.tx_window_errors++; - if (sc & BD_ENET_TX_RL) /* Retrans limit */ - fep->stats.tx_aborted_errors++; - if (sc & BD_ENET_TX_UN) /* Underrun */ - fep->stats.tx_fifo_errors++; - if (sc & BD_ENET_TX_CSL) /* Carrier lost */ - fep->stats.tx_carrier_errors++; - } else - fep->stats.tx_packets++; - - if (sc & BD_ENET_TX_READY) - printk(KERN_WARNING DRV_MODULE_NAME - ": %s HEY! Enet xmit interrupt and TX_READY.\n", - dev->name); - - /* - * Deferred means some collisions occurred during transmit, - * but we eventually sent the packet OK. - */ - if (sc & BD_ENET_TX_DEF) - fep->stats.collisions++; - - /* - * Free the sk buffer associated with this last transmit. - */ - dev_kfree_skb_irq(skb); - fep->tx_skbuff[dirtyidx] = NULL; - - /* - * Update pointer to next buffer descriptor to be transmitted. - */ - if ((sc & BD_ENET_TX_WRAP) == 0) - bdp++; - else - bdp = fep->tx_bd_base; - - /* - * Since we have freed up a buffer, the ring is no longer - * full. - */ - if (!fep->tx_free++) - do_wake = 1; - } - - fep->dirty_tx = bdp; - - spin_unlock(&fep->lock); - - if (do_wake && netif_queue_stopped(dev)) - netif_wake_queue(dev); -} - -/* - * The interrupt handler. - * This is called from the MPC core interrupt. - */ -static irqreturn_t -fec_enet_interrupt(int irq, void *dev_id) -{ - struct net_device *dev = dev_id; - struct fec_enet_private *fep; - const struct fec_platform_info *fpi; - fec_t *fecp; - __u32 int_events; - __u32 int_events_napi; - - if (unlikely(dev == NULL)) - return IRQ_NONE; - - fep = netdev_priv(dev); - fecp = fep->fecp; - fpi = fep->fpi; - - /* - * Get the interrupt events that caused us to be here. - */ - while ((int_events = FR(fecp, ievent) & FR(fecp, imask)) != 0) { - - if (!fpi->use_napi) - FW(fecp, ievent, int_events); - else { - int_events_napi = int_events & ~(FEC_ENET_RXF | FEC_ENET_RXB); - FW(fecp, ievent, int_events_napi); - } - - if ((int_events & (FEC_ENET_HBERR | FEC_ENET_BABR | - FEC_ENET_BABT | FEC_ENET_EBERR)) != 0) - printk(KERN_WARNING DRV_MODULE_NAME - ": %s FEC ERROR(s) 0x%x\n", - dev->name, int_events); - - if ((int_events & FEC_ENET_RXF) != 0) { - if (!fpi->use_napi) - fec_enet_rx_common(fep, dev, ~0); - else { - if (netif_rx_schedule_prep(dev, &fep->napi)) { - /* disable rx interrupts */ - FC(fecp, imask, FEC_ENET_RXF | FEC_ENET_RXB); - __netif_rx_schedule(dev, &fep->napi); - } else { - printk(KERN_ERR DRV_MODULE_NAME - ": %s driver bug! interrupt while in poll!\n", - dev->name); - FC(fecp, imask, FEC_ENET_RXF | FEC_ENET_RXB); - } - } - } - - if ((int_events & FEC_ENET_TXF) != 0) - fec_enet_tx(dev); - } - - return IRQ_HANDLED; -} - -/* This interrupt occurs when the PHY detects a link change. */ -static irqreturn_t -fec_mii_link_interrupt(int irq, void *dev_id) -{ - struct net_device *dev = dev_id; - struct fec_enet_private *fep; - const struct fec_platform_info *fpi; - - if (unlikely(dev == NULL)) - return IRQ_NONE; - - fep = netdev_priv(dev); - fpi = fep->fpi; - - if (!fpi->use_mdio) - return IRQ_NONE; - - /* - * Acknowledge the interrupt if possible. If we have not - * found the PHY yet we can't process or acknowledge the - * interrupt now. Instead we ignore this interrupt for now, - * which we can do since it is edge triggered. It will be - * acknowledged later by fec_enet_open(). - */ - if (!fep->phy) - return IRQ_NONE; - - fec_mii_ack_int(dev); - fec_mii_link_status_change_check(dev, 0); - - return IRQ_HANDLED; -} - - -/**********************************************************************************/ - -static int fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) -{ - struct fec_enet_private *fep = netdev_priv(dev); - fec_t *fecp = fep->fecp; - cbd_t *bdp; - int curidx; - unsigned long flags; - - spin_lock_irqsave(&fep->tx_lock, flags); - - /* - * Fill in a Tx ring entry - */ - bdp = fep->cur_tx; - - if (!fep->tx_free || (CBDR_SC(bdp) & BD_ENET_TX_READY)) { - netif_stop_queue(dev); - spin_unlock_irqrestore(&fep->tx_lock, flags); - - /* - * Ooops. All transmit buffers are full. Bail out. - * This should not happen, since the tx queue should be stopped. - */ - printk(KERN_WARNING DRV_MODULE_NAME - ": %s tx queue full!.\n", dev->name); - return 1; - } - - curidx = bdp - fep->tx_bd_base; - /* - * Clear all of the status flags. - */ - CBDC_SC(bdp, BD_ENET_TX_STATS); - - /* - * Save skb pointer. - */ - fep->tx_skbuff[curidx] = skb; - - fep->stats.tx_bytes += skb->len; - - /* - * Push the data cache so the CPM does not get stale memory data. - */ - CBDW_BUFADDR(bdp, dma_map_single(NULL, skb->data, - skb->len, DMA_TO_DEVICE)); - CBDW_DATLEN(bdp, skb->len); - - dev->trans_start = jiffies; - - /* - * If this was the last BD in the ring, start at the beginning again. - */ - if ((CBDR_SC(bdp) & BD_ENET_TX_WRAP) == 0) - fep->cur_tx++; - else - fep->cur_tx = fep->tx_bd_base; - - if (!--fep->tx_free) - netif_stop_queue(dev); - - /* - * Trigger transmission start - */ - CBDS_SC(bdp, BD_ENET_TX_READY | BD_ENET_TX_INTR | - BD_ENET_TX_LAST | BD_ENET_TX_TC); - FW(fecp, x_des_active, 0x01000000); - - spin_unlock_irqrestore(&fep->tx_lock, flags); - - return 0; -} - -static void fec_timeout(struct net_device *dev) -{ - struct fec_enet_private *fep = netdev_priv(dev); - - fep->stats.tx_errors++; - - if (fep->tx_free) - netif_wake_queue(dev); - - /* check link status again */ - fec_mii_link_status_change_check(dev, 0); -} - -static int fec_enet_open(struct net_device *dev) -{ - struct fec_enet_private *fep = netdev_priv(dev); - const struct fec_platform_info *fpi = fep->fpi; - unsigned long flags; - - napi_enable(&fep->napi); - - /* Install our interrupt handler. */ - if (request_irq(fpi->fec_irq, fec_enet_interrupt, 0, "fec", dev) != 0) { - printk(KERN_ERR DRV_MODULE_NAME - ": %s Could not allocate FEC IRQ!", dev->name); - napi_disable(&fep->napi); - return -EINVAL; - } - - /* Install our phy interrupt handler */ - if (fpi->phy_irq != -1 && - request_irq(fpi->phy_irq, fec_mii_link_interrupt, 0, "fec-phy", - dev) != 0) { - printk(KERN_ERR DRV_MODULE_NAME - ": %s Could not allocate PHY IRQ!", dev->name); - free_irq(fpi->fec_irq, dev); - napi_disable(&fep->napi); - return -EINVAL; - } - - if (fpi->use_mdio) { - fec_mii_startup(dev); - netif_carrier_off(dev); - fec_mii_link_status_change_check(dev, 1); - } else { - spin_lock_irqsave(&fep->lock, flags); - fec_restart(dev, 1, 100); /* XXX this sucks */ - spin_unlock_irqrestore(&fep->lock, flags); - - netif_carrier_on(dev); - netif_start_queue(dev); - } - return 0; -} - -static int fec_enet_close(struct net_device *dev) -{ - struct fec_enet_private *fep = netdev_priv(dev); - const struct fec_platform_info *fpi = fep->fpi; - unsigned long flags; - - netif_stop_queue(dev); - napi_disable(&fep->napi); - netif_carrier_off(dev); - - if (fpi->use_mdio) - fec_mii_shutdown(dev); - - spin_lock_irqsave(&fep->lock, flags); - fec_stop(dev); - spin_unlock_irqrestore(&fep->lock, flags); - - /* release any irqs */ - if (fpi->phy_irq != -1) - free_irq(fpi->phy_irq, dev); - free_irq(fpi->fec_irq, dev); - - return 0; -} - -static struct net_device_stats *fec_enet_get_stats(struct net_device *dev) -{ - struct fec_enet_private *fep = netdev_priv(dev); - return &fep->stats; -} - -static int fec_enet_poll(struct napi_struct *napi, int budget) -{ - struct fec_enet_private *fep = container_of(napi, struct fec_enet_private, napi); - struct net_device *dev = fep->dev; - - return fec_enet_rx_common(fep, dev, budget); -} - -/*************************************************************************/ - -static void fec_get_drvinfo(struct net_device *dev, - struct ethtool_drvinfo *info) -{ - strcpy(info->driver, DRV_MODULE_NAME); - strcpy(info->version, DRV_MODULE_VERSION); -} - -static int fec_get_regs_len(struct net_device *dev) -{ - return sizeof(fec_t); -} - -static void fec_get_regs(struct net_device *dev, struct ethtool_regs *regs, - void *p) -{ - struct fec_enet_private *fep = netdev_priv(dev); - unsigned long flags; - - if (regs->len < sizeof(fec_t)) - return; - - regs->version = 0; - spin_lock_irqsave(&fep->lock, flags); - memcpy_fromio(p, fep->fecp, sizeof(fec_t)); - spin_unlock_irqrestore(&fep->lock, flags); -} - -static int fec_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) -{ - struct fec_enet_private *fep = netdev_priv(dev); - unsigned long flags; - int rc; - - spin_lock_irqsave(&fep->lock, flags); - rc = mii_ethtool_gset(&fep->mii_if, cmd); - spin_unlock_irqrestore(&fep->lock, flags); - - return rc; -} - -static int fec_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) -{ - struct fec_enet_private *fep = netdev_priv(dev); - unsigned long flags; - int rc; - - spin_lock_irqsave(&fep->lock, flags); - rc = mii_ethtool_sset(&fep->mii_if, cmd); - spin_unlock_irqrestore(&fep->lock, flags); - - return rc; -} - -static int fec_nway_reset(struct net_device *dev) -{ - struct fec_enet_private *fep = netdev_priv(dev); - return mii_nway_restart(&fep->mii_if); -} - -static __u32 fec_get_msglevel(struct net_device *dev) -{ - struct fec_enet_private *fep = netdev_priv(dev); - return fep->msg_enable; -} - -static void fec_set_msglevel(struct net_device *dev, __u32 value) -{ - struct fec_enet_private *fep = netdev_priv(dev); - fep->msg_enable = value; -} - -static const struct ethtool_ops fec_ethtool_ops = { - .get_drvinfo = fec_get_drvinfo, - .get_regs_len = fec_get_regs_len, - .get_settings = fec_get_settings, - .set_settings = fec_set_settings, - .nway_reset = fec_nway_reset, - .get_link = ethtool_op_get_link, - .get_msglevel = fec_get_msglevel, - .set_msglevel = fec_set_msglevel, - .set_tx_csum = ethtool_op_set_tx_csum, /* local! */ - .set_sg = ethtool_op_set_sg, - .get_regs = fec_get_regs, -}; - -static int fec_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) -{ - struct fec_enet_private *fep = netdev_priv(dev); - struct mii_ioctl_data *mii = (struct mii_ioctl_data *)&rq->ifr_data; - unsigned long flags; - int rc; - - if (!netif_running(dev)) - return -EINVAL; - - spin_lock_irqsave(&fep->lock, flags); - rc = generic_mii_ioctl(&fep->mii_if, mii, cmd, NULL); - spin_unlock_irqrestore(&fep->lock, flags); - return rc; -} - -int fec_8xx_init_one(const struct fec_platform_info *fpi, - struct net_device **devp) -{ - immap_t *immap = (immap_t *) IMAP_ADDR; - static int fec_8xx_version_printed = 0; - struct net_device *dev = NULL; - struct fec_enet_private *fep = NULL; - fec_t *fecp = NULL; - int i; - int err = 0; - int registered = 0; - __u32 siel; - - *devp = NULL; - - switch (fpi->fec_no) { - case 0: - fecp = &((immap_t *) IMAP_ADDR)->im_cpm.cp_fec; - break; -#ifdef CONFIG_DUET - case 1: - fecp = &((immap_t *) IMAP_ADDR)->im_cpm.cp_fec2; - break; -#endif - default: - return -EINVAL; - } - - if (fec_8xx_version_printed++ == 0) - printk(KERN_INFO "%s", version); - - i = sizeof(*fep) + (sizeof(struct sk_buff **) * - (fpi->rx_ring + fpi->tx_ring)); - - dev = alloc_etherdev(i); - if (!dev) { - err = -ENOMEM; - goto err; - } - - fep = netdev_priv(dev); - fep->dev = dev; - - /* partial reset of FEC */ - fec_whack_reset(fecp); - - /* point rx_skbuff, tx_skbuff */ - fep->rx_skbuff = (struct sk_buff **)&fep[1]; - fep->tx_skbuff = fep->rx_skbuff + fpi->rx_ring; - - fep->fecp = fecp; - fep->fpi = fpi; - - /* init locks */ - spin_lock_init(&fep->lock); - spin_lock_init(&fep->tx_lock); - - /* - * Set the Ethernet address. - */ - for (i = 0; i < 6; i++) - dev->dev_addr[i] = fpi->macaddr[i]; - - fep->ring_base = dma_alloc_coherent(NULL, - (fpi->tx_ring + fpi->rx_ring) * - sizeof(cbd_t), &fep->ring_mem_addr, - GFP_KERNEL); - if (fep->ring_base == NULL) { - printk(KERN_ERR DRV_MODULE_NAME - ": %s dma alloc failed.\n", dev->name); - err = -ENOMEM; - goto err; - } - - /* - * Set receive and transmit descriptor base. - */ - fep->rx_bd_base = fep->ring_base; - fep->tx_bd_base = fep->rx_bd_base + fpi->rx_ring; - - /* initialize ring size variables */ - fep->tx_ring = fpi->tx_ring; - fep->rx_ring = fpi->rx_ring; - - /* SIU interrupt */ - if (fpi->phy_irq != -1 && - (fpi->phy_irq >= SIU_IRQ0 && fpi->phy_irq < SIU_LEVEL7)) { - - siel = in_be32(&immap->im_siu_conf.sc_siel); - if ((fpi->phy_irq & 1) == 0) - siel |= (0x80000000 >> fpi->phy_irq); - else - siel &= ~(0x80000000 >> (fpi->phy_irq & ~1)); - out_be32(&immap->im_siu_conf.sc_siel, siel); - } - - /* - * The FEC Ethernet specific entries in the device structure. - */ - dev->open = fec_enet_open; - dev->hard_start_xmit = fec_enet_start_xmit; - dev->tx_timeout = fec_timeout; - dev->watchdog_timeo = TX_TIMEOUT; - dev->stop = fec_enet_close; - dev->get_stats = fec_enet_get_stats; - dev->set_multicast_list = fec_set_multicast_list; - dev->set_mac_address = fec_set_mac_address; - netif_napi_add(dev, &fec->napi, - fec_enet_poll, fpi->napi_weight); - - dev->ethtool_ops = &fec_ethtool_ops; - dev->do_ioctl = fec_ioctl; - - fep->fec_phy_speed = - ((((fpi->sys_clk + 4999999) / 2500000) / 2) & 0x3F) << 1; - - init_timer(&fep->phy_timer_list); - - /* partial reset of FEC so that only MII works */ - FW(fecp, mii_speed, fep->fec_phy_speed); - FW(fecp, ievent, 0xffc0); - FW(fecp, ivec, (fpi->fec_irq / 2) << 29); - FW(fecp, imask, 0); - FW(fecp, r_cntrl, FEC_RCNTRL_MII_MODE); /* MII enable */ - FW(fecp, ecntrl, FEC_ECNTRL_PINMUX | FEC_ECNTRL_ETHER_EN); - - netif_carrier_off(dev); - - err = register_netdev(dev); - if (err != 0) - goto err; - registered = 1; - - if (fpi->use_mdio) { - fep->mii_if.dev = dev; - fep->mii_if.mdio_read = fec_mii_read; - fep->mii_if.mdio_write = fec_mii_write; - fep->mii_if.phy_id_mask = 0x1f; - fep->mii_if.reg_num_mask = 0x1f; - fep->mii_if.phy_id = fec_mii_phy_id_detect(dev); - } - - *devp = dev; - - return 0; - - err: - if (dev != NULL) { - if (fecp != NULL) - fec_whack_reset(fecp); - - if (registered) - unregister_netdev(dev); - - if (fep != NULL) { - if (fep->ring_base) - dma_free_coherent(NULL, - (fpi->tx_ring + - fpi->rx_ring) * - sizeof(cbd_t), fep->ring_base, - fep->ring_mem_addr); - } - free_netdev(dev); - } - return err; -} - -int fec_8xx_cleanup_one(struct net_device *dev) -{ - struct fec_enet_private *fep = netdev_priv(dev); - fec_t *fecp = fep->fecp; - const struct fec_platform_info *fpi = fep->fpi; - - fec_whack_reset(fecp); - - unregister_netdev(dev); - - dma_free_coherent(NULL, (fpi->tx_ring + fpi->rx_ring) * sizeof(cbd_t), - fep->ring_base, fep->ring_mem_addr); - - free_netdev(dev); - - return 0; -} - -/**************************************************************************************/ -/**************************************************************************************/ -/**************************************************************************************/ - -static int __init fec_8xx_init(void) -{ - return fec_8xx_platform_init(); -} - -static void __exit fec_8xx_cleanup(void) -{ - fec_8xx_platform_cleanup(); -} - -/**************************************************************************************/ -/**************************************************************************************/ -/**************************************************************************************/ - -module_init(fec_8xx_init); -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 3b6ca29d31f..00000000000 --- a/drivers/net/fec_8xx/fec_mii.c +++ /dev/null @@ -1,418 +0,0 @@ -/* - * Fast Ethernet Controller (FEC) driver for Motorola MPC8xx. - * - * Copyright (c) 2003 Intracom S.A. - * by Pantelis Antoniou <panto@intracom.gr> - * - * Heavily based on original FEC driver by Dan Malek <dan@embeddededge.com> - * and modifications by Joakim Tjernlund <joakim.tjernlund@lumentis.se> - * - * Released under the GPL - */ - -#include <linux/module.h> -#include <linux/types.h> -#include <linux/kernel.h> -#include <linux/string.h> -#include <linux/ptrace.h> -#include <linux/errno.h> -#include <linux/ioport.h> -#include <linux/slab.h> -#include <linux/interrupt.h> -#include <linux/init.h> -#include <linux/delay.h> -#include <linux/netdevice.h> -#include <linux/etherdevice.h> -#include <linux/skbuff.h> -#include <linux/spinlock.h> -#include <linux/mii.h> -#include <linux/ethtool.h> -#include <linux/bitops.h> - -#include <asm/8xx_immap.h> -#include <asm/pgtable.h> -#include <asm/mpc8xx.h> -#include <asm/irq.h> -#include <asm/uaccess.h> -#include <asm/cpm1.h> - -/*************************************************/ - -#include "fec_8xx.h" - -/*************************************************/ - -/* Make MII read/write commands for the FEC. -*/ -#define mk_mii_read(REG) (0x60020000 | ((REG & 0x1f) << 18)) -#define mk_mii_write(REG, VAL) (0x50020000 | ((REG & 0x1f) << 18) | (VAL & 0xffff)) -#define mk_mii_end 0 - -/*************************************************/ - -/* XXX both FECs use the MII interface of FEC1 */ -static DEFINE_SPINLOCK(fec_mii_lock); - -#define FEC_MII_LOOPS 10000 - -int fec_mii_read(struct net_device *dev, int phy_id, int location) -{ - struct fec_enet_private *fep = netdev_priv(dev); - fec_t *fecp; - int i, ret = -1; - unsigned long flags; - - /* XXX MII interface is only connected to FEC1 */ - fecp = &((immap_t *) IMAP_ADDR)->im_cpm.cp_fec; - - spin_lock_irqsave(&fec_mii_lock, flags); - - if ((FR(fecp, r_cntrl) & FEC_RCNTRL_MII_MODE) == 0) { - FS(fecp, r_cntrl, FEC_RCNTRL_MII_MODE); /* MII enable */ - FS(fecp, ecntrl, FEC_ECNTRL_PINMUX | FEC_ECNTRL_ETHER_EN); - FW(fecp, ievent, FEC_ENET_MII); - } - - /* Add PHY address to register command. */ - FW(fecp, mii_speed, fep->fec_phy_speed); - FW(fecp, mii_data, (phy_id << 23) | mk_mii_read(location)); - - for (i = 0; i < FEC_MII_LOOPS; i++) - if ((FR(fecp, ievent) & FEC_ENET_MII) != 0) - break; - - if (i < FEC_MII_LOOPS) { - FW(fecp, ievent, FEC_ENET_MII); - ret = FR(fecp, mii_data) & 0xffff; - } - - spin_unlock_irqrestore(&fec_mii_lock, flags); - - return ret; -} - -void fec_mii_write(struct net_device *dev, int phy_id, int location, int value) -{ - struct fec_enet_private *fep = netdev_priv(dev); - fec_t *fecp; - unsigned long flags; - int i; - - /* XXX MII interface is only connected to FEC1 */ - fecp = &((immap_t *) IMAP_ADDR)->im_cpm.cp_fec; - - spin_lock_irqsave(&fec_mii_lock, flags); - - if ((FR(fecp, r_cntrl) & FEC_RCNTRL_MII_MODE) == 0) { - FS(fecp, r_cntrl, FEC_RCNTRL_MII_MODE); /* MII enable */ - FS(fecp, ecntrl, FEC_ECNTRL_PINMUX | FEC_ECNTRL_ETHER_EN); - FW(fecp, ievent, FEC_ENET_MII); - } - - /* Add PHY address to register command. */ - FW(fecp, mii_speed, fep->fec_phy_speed); /* always adapt mii speed */ - FW(fecp, mii_data, (phy_id << 23) | mk_mii_write(location, value)); - - for (i = 0; i < FEC_MII_LOOPS; i++) - if ((FR(fecp, ievent) & FEC_ENET_MII) != 0) - break; - - if (i < FEC_MII_LOOPS) - FW(fecp, ievent, FEC_ENET_MII); - - spin_unlock_irqrestore(&fec_mii_lock, flags); -} - -/*************************************************/ - -#ifdef CONFIG_FEC_8XX_GENERIC_PHY - -/* - * Generic PHY support. - * Should work for all PHYs, but link change is detected by polling - */ - -static void generic_timer_callback(unsigned long data) -{ - struct net_device *dev = (struct net_device *)data; - struct fec_enet_private *fep = netdev_priv(dev); - - fep->phy_timer_list.expires = jiffies + HZ / 2; - - add_timer(&fep->phy_timer_list); - - fec_mii_link_status_change_check(dev, 0); -} - -static void generic_startup(struct net_device *dev) -{ - struct fec_enet_private *fep = netdev_priv(dev); - - fep->phy_timer_list.expires = jiffies + HZ / 2; /* every 500ms */ - fep->phy_timer_list.data = (unsigned long)dev; - fep->phy_timer_list.function = generic_timer_callback; - add_timer(&fep->phy_timer_list); -} - -static void generic_shutdown(struct net_device *dev) -{ - struct fec_enet_private *fep = netdev_priv(dev); - - del_timer_sync(&fep->phy_timer_list); -} - -#endif - -#ifdef CONFIG_FEC_8XX_DM9161_PHY - -/* ------------------------------------------------------------------------- */ -/* The Davicom DM9161 is used on the NETTA board */ - -/* register definitions */ - -#define MII_DM9161_ACR 16 /* Aux. Config Register */ -#define MII_DM9161_ACSR 17 /* Aux. Config/Status Register */ -#define MII_DM9161_10TCSR 18 /* 10BaseT Config/Status Reg. */ -#define MII_DM9161_INTR 21 /* Interrupt Register */ -#define MII_DM9161_RECR 22 /* Receive Error Counter Reg. */ -#define MII_DM9161_DISCR 23 /* Disconnect Counter Register */ - -static void dm9161_startup(struct net_device *dev) -{ - struct fec_enet_private *fep = netdev_priv(dev); - - fec_mii_write(dev, fep->mii_if.phy_id, MII_DM9161_INTR, 0x0000); -} - -static void dm9161_ack_int(struct net_device *dev) -{ - struct fec_enet_private *fep = netdev_priv(dev); - - fec_mii_read(dev, fep->mii_if.phy_id, MII_DM9161_INTR); -} - -static void dm9161_shutdown(struct net_device *dev) -{ - struct fec_enet_private *fep = netdev_priv(dev); - - fec_mii_write(dev, fep->mii_if.phy_id, MII_DM9161_INTR, 0x0f00); -} - -#endif - -#ifdef CONFIG_FEC_8XX_LXT971_PHY - -/* Support for LXT971/972 PHY */ - -#define MII_LXT971_PCR 16 /* Port Control Register */ -#define MII_LXT971_SR2 17 /* Status Register 2 */ -#define MII_LXT971_IER 18 /* Interrupt Enable Register */ -#define MII_LXT971_ISR 19 /* Interrupt Status Register */ -#define MII_LXT971_LCR 20 /* LED Control Register */ -#define MII_LXT971_TCR 30 /* Transmit Control Register */ - -static void lxt971_startup(struct net_device *dev) -{ - struct fec_enet_private *fep = netdev_priv(dev); - - fec_mii_write(dev, fep->mii_if.phy_id, MII_LXT971_IER, 0x00F2); -} - -static void lxt971_ack_int(struct net_device *dev) -{ - struct fec_enet_private *fep = netdev_priv(dev); - - fec_mii_read(dev, fep->mii_if.phy_id, MII_LXT971_ISR); -} - -static void lxt971_shutdown(struct net_device *dev) -{ - struct fec_enet_private *fep = netdev_priv(dev); - - fec_mii_write(dev, fep->mii_if.phy_id, MII_LXT971_IER, 0x0000); -} -#endif - -/**********************************************************************************/ - -static const struct phy_info phy_info[] = { -#ifdef CONFIG_FEC_8XX_DM9161_PHY - { - .id = 0x00181b88, - .name = "DM9161", - .startup = dm9161_startup, - .ack_int = dm9161_ack_int, - .shutdown = dm9161_shutdown, - }, -#endif -#ifdef CONFIG_FEC_8XX_LXT971_PHY - { - .id = 0x0001378e, - .name = "LXT971/972", - .startup = lxt971_startup, - .ack_int = lxt971_ack_int, - .shutdown = lxt971_shutdown, - }, -#endif -#ifdef CONFIG_FEC_8XX_GENERIC_PHY - { - .id = 0, - .name = "GENERIC", - .startup = generic_startup, - .shutdown = generic_shutdown, - }, -#endif -}; - -/**********************************************************************************/ - -int fec_mii_phy_id_detect(struct net_device *dev) -{ - struct fec_enet_private *fep = netdev_priv(dev); - const struct fec_platform_info *fpi = fep->fpi; - int i, r, start, end, phytype, physubtype; - const struct phy_info *phy; - int phy_hwid, phy_id; - - /* if no MDIO */ - if (fpi->use_mdio == 0) - return -1; - - phy_hwid = -1; - fep->phy = NULL; - - /* auto-detect? */ - if (fpi->phy_addr == -1) { - start = 0; - end = 32; - } else { /* direct */ - start = fpi->phy_addr; - end = start + 1; - } - - for (phy_id = start; phy_id < end; phy_id++) { - r = fec_mii_read(dev, phy_id, MII_PHYSID1); - if (r == -1 || (phytype = (r & 0xffff)) == 0xffff) - continue; - r = fec_mii_read(dev, phy_id, MII_PHYSID2); - if (r == -1 || (physubtype = (r & 0xffff)) == 0xffff) - continue; - phy_hwid = (phytype << 16) | physubtype; - if (phy_hwid != -1) - break; - } - - if (phy_hwid == -1) { - printk(KERN_ERR DRV_MODULE_NAME - ": %s No PHY detected!\n", dev->name); - return -1; - } - - for (i = 0, phy = phy_info; i < ARRAY_SIZE(phy_info); i++, phy++) - if (phy->id == (phy_hwid >> 4) || phy->id == 0) - break; - - if (i >= ARRAY_SIZE(phy_info)) { - printk(KERN_ERR DRV_MODULE_NAME - ": %s PHY id 0x%08x is not supported!\n", - dev->name, phy_hwid); - return -1; - } - - fep->phy = phy; - - printk(KERN_INFO DRV_MODULE_NAME - ": %s Phy @ 0x%x, type %s (0x%08x)\n", - dev->name, phy_id, fep->phy->name, phy_hwid); - - return phy_id; -} - -void fec_mii_startup(struct net_device *dev) -{ - struct fec_enet_private *fep = netdev_priv(dev); - const struct fec_platform_info *fpi = fep->fpi; - - if (!fpi->use_mdio || fep->phy == NULL) - return; - - if (fep->phy->startup == NULL) - return; - - (*fep->phy->startup) (dev); -} - -void fec_mii_shutdown(struct net_device *dev) -{ - struct fec_enet_private *fep = netdev_priv(dev); - const struct fec_platform_info *fpi = fep->fpi; - - if (!fpi->use_mdio || fep->phy == NULL) - return; - - if (fep->phy->shutdown == NULL) - return; - - (*fep->phy->shutdown) (dev); -} - -void fec_mii_ack_int(struct net_device *dev) -{ - struct fec_enet_private *fep = netdev_priv(dev); - const struct fec_platform_info *fpi = fep->fpi; - - if (!fpi->use_mdio || fep->phy == NULL) - return; - - if (fep->phy->ack_int == NULL) - return; - - (*fep->phy->ack_int) (dev); -} - -/* helper function */ -static int mii_negotiated(struct mii_if_info *mii) -{ - int advert, lpa, val; - - if (!mii_link_ok(mii)) - return 0; - - val = (*mii->mdio_read) (mii->dev, mii->phy_id, MII_BMSR); - if ((val & BMSR_ANEGCOMPLETE) == 0) - return 0; - - advert = (*mii->mdio_read) (mii->dev, mii->phy_id, MII_ADVERTISE); - lpa = (*mii->mdio_read) (mii->dev, mii->phy_id, MII_LPA); - - return mii_nway_result(advert & lpa); -} - -void fec_mii_link_status_change_check(struct net_device *dev, int init_media) -{ - struct fec_enet_private *fep = netdev_priv(dev); - unsigned int media; - unsigned long flags; - - if (mii_check_media(&fep->mii_if, netif_msg_link(fep), init_media) == 0) - return; - - media = mii_negotiated(&fep->mii_if); - - if (netif_carrier_ok(dev)) { - spin_lock_irqsave(&fep->lock, flags); - fec_restart(dev, !!(media & ADVERTISE_FULL), - (media & (ADVERTISE_100FULL | ADVERTISE_100HALF)) ? - 100 : 10); - spin_unlock_irqrestore(&fep->lock, flags); - - netif_start_queue(dev); - } else { - netif_stop_queue(dev); - - spin_lock_irqsave(&fep->lock, flags); - fec_stop(dev); - spin_unlock_irqrestore(&fep->lock, flags); - - } -} diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c index a5baaf59ff6..352574a3f05 100644 --- a/drivers/net/fs_enet/fs_enet-main.c +++ b/drivers/net/fs_enet/fs_enet-main.c @@ -43,7 +43,7 @@ #include <asm/uaccess.h> #ifdef CONFIG_PPC_CPM_NEW_BINDING -#include <asm/of_platform.h> +#include <linux/of_platform.h> #endif #include "fs_enet.h" diff --git a/drivers/net/fs_enet/mac-scc.c b/drivers/net/fs_enet/mac-scc.c index d7ca31945c8..e3557eca7b6 100644 --- a/drivers/net/fs_enet/mac-scc.c +++ b/drivers/net/fs_enet/mac-scc.c @@ -44,7 +44,7 @@ #endif #ifdef CONFIG_PPC_CPM_NEW_BINDING -#include <asm/of_platform.h> +#include <linux/of_platform.h> #endif #include "fs_enet.h" diff --git a/drivers/net/fs_enet/mii-fec.c b/drivers/net/fs_enet/mii-fec.c index f0014cfbb27..8f6a43b0e0f 100644 --- a/drivers/net/fs_enet/mii-fec.c +++ b/drivers/net/fs_enet/mii-fec.c @@ -37,7 +37,7 @@ #include <asm/uaccess.h> #ifdef CONFIG_PPC_CPM_NEW_BINDING -#include <asm/of_platform.h> +#include <linux/of_platform.h> #endif #include "fs_enet.h" diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c index babc79ad490..61af02b4c9d 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) static void emac_hash_mc(struct emac_instance *dev) { - struct emac_regs __iomem *p = dev->emacp; - u16 gaht[4] = { 0 }; + const int regs = EMAC_XAHT_REGS(dev); + u32 *gaht_base = emac_gaht_base(dev); + u32 gaht_temp[regs]; struct dev_mc_list *dmi; + int i; DBG(dev, "hash_mc %d" NL, dev->ndev->mc_count); + memset(gaht_temp, 0, sizeof (gaht_temp)); + for (dmi = dev->ndev->mc_list; dmi; dmi = dmi->next) { - int bit; + int slot, reg, mask; DBG2(dev, "mc %02x:%02x:%02x:%02x:%02x:%02x" NL, dmi->dmi_addr[0], dmi->dmi_addr[1], dmi->dmi_addr[2], dmi->dmi_addr[3], dmi->dmi_addr[4], dmi->dmi_addr[5]); - bit = 63 - (ether_crc(ETH_ALEN, dmi->dmi_addr) >> 26); - gaht[bit >> 4] |= 0x8000 >> (bit & 0x0f); + slot = EMAC_XAHT_CRC_TO_SLOT(dev, ether_crc(ETH_ALEN, dmi->dmi_addr)); + reg = EMAC_XAHT_SLOT_TO_REG(dev, slot); + mask = EMAC_XAHT_SLOT_TO_MASK(dev, slot); + + gaht_temp[reg] |= mask; } - out_be32(&p->gaht1, gaht[0]); - out_be32(&p->gaht2, gaht[1]); - out_be32(&p->gaht3, gaht[2]); - out_be32(&p->gaht4, gaht[3]); + + for (i = 0; i < regs; i++) + out_be32(gaht_base + i, gaht_temp[i]); } static inline u32 emac_iff2rmr(struct net_device *ndev) @@ -398,7 +404,8 @@ static inline u32 emac_iff2rmr(struct net_device *ndev) if (ndev->flags & IFF_PROMISC) r |= EMAC_RMR_PME; - else if (ndev->flags & IFF_ALLMULTI || ndev->mc_count > 32) + else if (ndev->flags & IFF_ALLMULTI || + (ndev->mc_count > EMAC_XAHT_SLOTS(dev))) r |= EMAC_RMR_PMME; else if (ndev->mc_count > 0) r |= EMAC_RMR_MAE; @@ -542,7 +549,7 @@ static int emac_configure(struct emac_instance *dev) /* Put some arbitrary OUI, Manuf & Rev IDs so we can * identify this GPCS PHY later. */ - out_be32(&p->ipcr, 0xdeadbeef); + out_be32(&p->u1.emac4.ipcr, 0xdeadbeef); } else mr1 |= EMAC_MR1_MF_1000; @@ -2021,10 +2028,10 @@ static int emac_get_regs_len(struct emac_instance *dev) { if (emac_has_feature(dev, EMAC_FTR_EMAC4)) return sizeof(struct emac_ethtool_regs_subhdr) + - EMAC4_ETHTOOL_REGS_SIZE; + EMAC4_ETHTOOL_REGS_SIZE(dev); else return sizeof(struct emac_ethtool_regs_subhdr) + - EMAC_ETHTOOL_REGS_SIZE; + EMAC_ETHTOOL_REGS_SIZE(dev); } 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) hdr->index = dev->cell_index; if (emac_has_feature(dev, EMAC_FTR_EMAC4)) { hdr->version = EMAC4_ETHTOOL_REGS_VER; - memcpy_fromio(hdr + 1, dev->emacp, EMAC4_ETHTOOL_REGS_SIZE); - return ((void *)(hdr + 1) + EMAC4_ETHTOOL_REGS_SIZE); + memcpy_fromio(hdr + 1, dev->emacp, EMAC4_ETHTOOL_REGS_SIZE(dev)); + return ((void *)(hdr + 1) + EMAC4_ETHTOOL_REGS_SIZE(dev)); } else { hdr->version = EMAC_ETHTOOL_REGS_VER; - memcpy_fromio(hdr + 1, dev->emacp, EMAC_ETHTOOL_REGS_SIZE); - return ((void *)(hdr + 1) + EMAC_ETHTOOL_REGS_SIZE); + memcpy_fromio(hdr + 1, dev->emacp, EMAC_ETHTOOL_REGS_SIZE(dev)); + return ((void *)(hdr + 1) + EMAC_ETHTOOL_REGS_SIZE(dev)); } } @@ -2546,7 +2553,9 @@ static int __devinit emac_init_config(struct emac_instance *dev) } /* Check EMAC version */ - if (of_device_is_compatible(np, "ibm,emac4")) { + if (of_device_is_compatible(np, "ibm,emac4sync")) { + dev->features |= (EMAC_FTR_EMAC4 | EMAC_FTR_EMAC4SYNC); + } else if (of_device_is_compatible(np, "ibm,emac4")) { dev->features |= EMAC_FTR_EMAC4; if (of_device_is_compatible(np, "ibm,emac-440gx")) dev->features |= EMAC_FTR_440GX_PHY_CLK_FIX; @@ -2607,6 +2616,15 @@ static int __devinit emac_init_config(struct emac_instance *dev) } memcpy(dev->ndev->dev_addr, p, 6); + /* IAHT and GAHT filter parameterization */ + if (emac_has_feature(dev, EMAC_FTR_EMAC4SYNC)) { + dev->xaht_slots_shift = EMAC4SYNC_XAHT_SLOTS_SHIFT; + dev->xaht_width_shift = EMAC4SYNC_XAHT_WIDTH_SHIFT; + } else { + dev->xaht_slots_shift = EMAC4_XAHT_SLOTS_SHIFT; + dev->xaht_width_shift = EMAC4_XAHT_WIDTH_SHIFT; + } + DBG(dev, "features : 0x%08x / 0x%08x\n", dev->features, EMAC_FTRS_POSSIBLE); DBG(dev, "tx_fifo_size : %d (%d gige)\n", dev->tx_fifo_size, dev->tx_fifo_size_gige); 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, goto err_irq_unmap; } // TODO : request_mem_region - dev->emacp = ioremap(dev->rsrc_regs.start, sizeof(struct emac_regs)); + dev->emacp = ioremap(dev->rsrc_regs.start, + dev->rsrc_regs.end - dev->rsrc_regs.start + 1); if (dev->emacp == NULL) { printk(KERN_ERR "%s: Can't map device registers!\n", np->full_name); @@ -2892,6 +2911,10 @@ static struct of_device_id emac_match[] = .type = "network", .compatible = "ibm,emac4", }, + { + .type = "network", + .compatible = "ibm,emac4sync", + }, {}, }; diff --git a/drivers/net/ibm_newemac/core.h b/drivers/net/ibm_newemac/core.h index 1683db9870a..6545e69d12c 100644 --- a/drivers/net/ibm_newemac/core.h +++ b/drivers/net/ibm_newemac/core.h @@ -33,8 +33,8 @@ #include <linux/netdevice.h> #include <linux/dma-mapping.h> #include <linux/spinlock.h> +#include <linux/of_platform.h> -#include <asm/of_platform.h> #include <asm/io.h> #include <asm/dcr.h> @@ -235,6 +235,10 @@ struct emac_instance { u32 fifo_entry_size; u32 mal_burst_size; /* move to MAL ? */ + /* IAHT and GAHT filter parameterization */ + u32 xaht_slots_shift; + u32 xaht_width_shift; + /* Descriptor management */ struct mal_descriptor *tx_desc; @@ -309,6 +313,10 @@ struct emac_instance { * Set if we need phy clock workaround for 440ep or 440gr */ #define EMAC_FTR_440EP_PHY_CLK_FIX 0x00000100 +/* + * The 405EX and 460EX contain the EMAC4SYNC core + */ +#define EMAC_FTR_EMAC4SYNC 0x00000200 /* Right now, we don't quite handle the always/possible masks on the @@ -320,7 +328,8 @@ enum { EMAC_FTRS_POSSIBLE = #ifdef CONFIG_IBM_NEW_EMAC_EMAC4 - EMAC_FTR_EMAC4 | EMAC_FTR_HAS_NEW_STACR | + EMAC_FTR_EMAC4 | EMAC_FTR_EMAC4SYNC | + EMAC_FTR_HAS_NEW_STACR | EMAC_FTR_STACR_OC_INVERT | EMAC_FTR_440GX_PHY_CLK_FIX | #endif #ifdef CONFIG_IBM_NEW_EMAC_TAH @@ -342,6 +351,71 @@ static inline int emac_has_feature(struct emac_instance *dev, (EMAC_FTRS_POSSIBLE & dev->features & feature); } +/* + * Various instances of the EMAC core have varying 1) number of + * address match slots, 2) width of the registers for handling address + * match slots, 3) number of registers for handling address match + * slots and 4) base offset for those registers. + * + * These macros and inlines handle these differences based on + * parameters supplied by the device structure which are, in turn, + * initialized based on the "compatible" entry in the device tree. + */ + +#define EMAC4_XAHT_SLOTS_SHIFT 6 +#define EMAC4_XAHT_WIDTH_SHIFT 4 + +#define EMAC4SYNC_XAHT_SLOTS_SHIFT 8 +#define EMAC4SYNC_XAHT_WIDTH_SHIFT 5 + +#define EMAC_XAHT_SLOTS(dev) (1 << (dev)->xaht_slots_shift) +#define EMAC_XAHT_WIDTH(dev) (1 << (dev)->xaht_width_shift) +#define EMAC_XAHT_REGS(dev) (1 << ((dev)->xaht_slots_shift - \ + (dev)->xaht_width_shift)) + +#define EMAC_XAHT_CRC_TO_SLOT(dev, crc) \ + ((EMAC_XAHT_SLOTS(dev) - 1) - \ + ((crc) >> ((sizeof (u32) * BITS_PER_BYTE) - \ + (dev)->xaht_slots_shift))) + +#define EMAC_XAHT_SLOT_TO_REG(dev, slot) \ + ((slot) >> (dev)->xaht_width_shift) + +#define EMAC_XAHT_SLOT_TO_MASK(dev, slot) \ + ((u32)(1 << (EMAC_XAHT_WIDTH(dev) - 1)) >> \ + ((slot) & (u32)(EMAC_XAHT_WIDTH(dev) - 1))) + +static inline u32 *emac_xaht_base(struct emac_instance *dev) +{ + struct emac_regs __iomem *p = dev->emacp; + int offset; + + /* The first IAHT entry always is the base of the block of + * IAHT and GAHT registers. + */ + if (emac_has_feature(dev, EMAC_FTR_EMAC4SYNC)) + offset = offsetof(struct emac_regs, u1.emac4sync.iaht1); + else + offset = offsetof(struct emac_regs, u0.emac4.iaht1); + + return ((u32 *)((ptrdiff_t)p + offset)); +} + +static inline u32 *emac_gaht_base(struct emac_instance *dev) +{ + /* GAHT registers always come after an identical number of + * IAHT registers. + */ + return (emac_xaht_base(dev) + EMAC_XAHT_REGS(dev)); +} + +static inline u32 *emac_iaht_base(struct emac_instance *dev) +{ + /* IAHT registers always come before an identical number of + * GAHT registers. + */ + return (emac_xaht_base(dev)); +} /* Ethtool get_regs complex data. * We want to get not just EMAC registers, but also MAL, ZMII, RGMII, TAH @@ -366,4 +440,11 @@ struct emac_ethtool_regs_subhdr { u32 index; }; +#define EMAC_ETHTOOL_REGS_VER 0 +#define EMAC_ETHTOOL_REGS_SIZE(dev) ((dev)->rsrc_regs.end - \ + (dev)->rsrc_regs.start + 1) +#define EMAC4_ETHTOOL_REGS_VER 1 +#define EMAC4_ETHTOOL_REGS_SIZE(dev) ((dev)->rsrc_regs.end - \ + (dev)->rsrc_regs.start + 1) + #endif /* __IBM_NEWEMAC_CORE_H */ diff --git a/drivers/net/ibm_newemac/debug.c b/drivers/net/ibm_newemac/debug.c index 86b756a3078..775c850a425 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) static void emac_mac_dump(struct emac_instance *dev) { struct emac_regs __iomem *p = dev->emacp; + const int xaht_regs = EMAC_XAHT_REGS(dev); + u32 *gaht_base = emac_gaht_base(dev); + u32 *iaht_base = emac_iaht_base(dev); + int emac4sync = emac_has_feature(dev, EMAC_FTR_EMAC4SYNC); + int n; printk("** EMAC %s registers **\n" "MR0 = 0x%08x MR1 = 0x%08x TMR0 = 0x%08x TMR1 = 0x%08x\n" "RMR = 0x%08x ISR = 0x%08x ISER = 0x%08x\n" - "IAR = %04x%08x VTPID = 0x%04x VTCI = 0x%04x\n" - "IAHT: 0x%04x 0x%04x 0x%04x 0x%04x " - "GAHT: 0x%04x 0x%04x 0x%04x 0x%04x\n" - "LSA = %04x%08x IPGVR = 0x%04x\n" - "STACR = 0x%08x TRTR = 0x%08x RWMR = 0x%08x\n" - "OCTX = 0x%08x OCRX = 0x%08x IPCR = 0x%08x\n", + "IAR = %04x%08x VTPID = 0x%04x VTCI = 0x%04x\n", dev->ofdev->node->full_name, in_be32(&p->mr0), in_be32(&p->mr1), in_be32(&p->tmr0), in_be32(&p->tmr1), in_be32(&p->rmr), in_be32(&p->isr), in_be32(&p->iser), in_be32(&p->iahr), in_be32(&p->ialr), in_be32(&p->vtpid), - in_be32(&p->vtci), - in_be32(&p->iaht1), in_be32(&p->iaht2), in_be32(&p->iaht3), - in_be32(&p->iaht4), - in_be32(&p->gaht1), in_be32(&p->gaht2), in_be32(&p->gaht3), - in_be32(&p->gaht4), + in_be32(&p->vtci) + ); + + if (emac4sync) + printk("MAR = %04x%08x MMAR = %04x%08x\n", + in_be32(&p->u0.emac4sync.mahr), + in_be32(&p->u0.emac4sync.malr), + in_be32(&p->u0.emac4sync.mmahr), + in_be32(&p->u0.emac4sync.mmalr) + ); + + for (n = 0; n < xaht_regs; n++) + printk("IAHT%02d = 0x%08x\n", n + 1, in_be32(iaht_base + n)); + + for (n = 0; n < xaht_regs; n++) + printk("GAHT%02d = 0x%08x\n", n + 1, in_be32(gaht_base + n)); + + printk("LSA = %04x%08x IPGVR = 0x%04x\n" + "STACR = 0x%08x TRTR = 0x%08x RWMR = 0x%08x\n" + "OCTX = 0x%08x OCRX = 0x%08x\n", in_be32(&p->lsah), in_be32(&p->lsal), in_be32(&p->ipgvr), in_be32(&p->stacr), in_be32(&p->trtr), in_be32(&p->rwmr), - in_be32(&p->octx), in_be32(&p->ocrx), in_be32(&p->ipcr) - ); + in_be32(&p->octx), in_be32(&p->ocrx) + ); + + if (!emac4sync) { + printk("IPCR = 0x%08x\n", + in_be32(&p->u1.emac4.ipcr) + ); + } else { + printk("REVID = 0x%08x TPC = 0x%08x\n", + in_be32(&p->u1.emac4sync.revid), + in_be32(&p->u1.emac4sync.tpc) + ); + } emac_desc_dump(dev); } diff --git a/drivers/net/ibm_newemac/emac.h b/drivers/net/ibm_newemac/emac.h index 91cb096ab40..0afc2cf5c52 100644 --- a/drivers/net/ibm_newemac/emac.h +++ b/drivers/net/ibm_newemac/emac.h @@ -27,37 +27,80 @@ #include <linux/types.h> -/* EMAC registers Write Access rules */ +/* EMAC registers Write Access rules */ struct emac_regs { - u32 mr0; /* special */ - u32 mr1; /* Reset */ - u32 tmr0; /* special */ - u32 tmr1; /* special */ - u32 rmr; /* Reset */ - u32 isr; /* Always */ - u32 iser; /* Reset */ - u32 iahr; /* Reset, R, T */ - u32 ialr; /* Reset, R, T */ - u32 vtpid; /* Reset, R, T */ - u32 vtci; /* Reset, R, T */ - u32 ptr; /* Reset, T */ - u32 iaht1; /* Reset, R */ - u32 iaht2; /* Reset, R */ - u32 iaht3; /* Reset, R */ - u32 iaht4; /* Reset, R */ - u32 gaht1; /* Reset, R */ - u32 gaht2; /* Reset, R */ - u32 gaht3; /* Reset, R */ - u32 gaht4; /* Reset, R */ + /* Common registers across all EMAC implementations. */ + u32 mr0; /* Special */ + u32 mr1; /* Reset */ + u32 tmr0; /* Special */ + u32 tmr1; /* Special */ + u32 rmr; /* Reset */ + u32 isr; /* Always */ + u32 iser; /* Reset */ + u32 iahr; /* Reset, R, T */ + u32 ialr; /* Reset, R, T */ + u32 vtpid; /* Reset, R, T */ + u32 vtci; /* Reset, R, T */ + u32 ptr; /* Reset, T */ + union { + /* Registers unique to EMAC4 implementations */ + struct { + u32 iaht1; /* Reset, R */ + u32 iaht2; /* Reset, R */ + u32 iaht3; /* Reset, R */ + u32 iaht4; /* Reset, R */ + u32 gaht1; /* Reset, R */ + u32 gaht2; /* Reset, R */ + u32 gaht3; /* Reset, R */ + u32 gaht4; /* Reset, R */ + } emac4; + /* Registers unique to EMAC4SYNC implementations */ + struct { + u32 mahr; /* Reset, R, T */ + u32 malr; /* Reset, R, T */ + u32 mmahr; /* Reset, R, T */ + u32 mmalr; /* Reset, R, T */ + u32 rsvd0[4]; + } emac4sync; + } u0; + /* Common registers across all EMAC implementations. */ u32 lsah; u32 lsal; - u32 ipgvr; /* Reset, T */ - u32 stacr; /* special */ - u32 trtr; /* special */ - u32 rwmr; /* Reset */ + u32 ipgvr; /* Reset, T */ + u32 stacr; /* Special */ + u32 trtr; /* Special */ + u32 rwmr; /* Reset */ u32 octx; u32 ocrx; - u32 ipcr; + union { + /* Registers unique to EMAC4 implementations */ + struct { + u32 ipcr; + } emac4; + /* Registers unique to EMAC4SYNC implementations */ + struct { + u32 rsvd1; + u32 revid; + u32 rsvd2[2]; + u32 iaht1; /* Reset, R */ + u32 iaht2; /* Reset, R */ + u32 iaht3; /* Reset, R */ + u32 iaht4; /* Reset, R */ + u32 iaht5; /* Reset, R */ + u32 iaht6; /* Reset, R */ + u32 iaht7; /* Reset, R */ + u32 iaht8; /* Reset, R */ + u32 gaht1; /* Reset, R */ + u32 gaht2; /* Reset, R */ + u32 gaht3; /* Reset, R */ + u32 gaht4; /* Reset, R */ + u32 gaht5; /* Reset, R */ + u32 gaht6; /* Reset, R */ + u32 gaht7; /* Reset, R */ + u32 gaht8; /* Reset, R */ + u32 tpc; /* Reset, T */ + } emac4sync; + } u1; }; /* @@ -73,12 +116,6 @@ struct emac_regs { #define PHY_MODE_RTBI 7 #define PHY_MODE_SGMII 8 - -#define EMAC_ETHTOOL_REGS_VER 0 -#define EMAC_ETHTOOL_REGS_SIZE (sizeof(struct emac_regs) - sizeof(u32)) -#define EMAC4_ETHTOOL_REGS_VER 1 -#define EMAC4_ETHTOOL_REGS_SIZE sizeof(struct emac_regs) - /* EMACx_MR0 */ #define EMAC_MR0_RXI 0x80000000 #define EMAC_MR0_TXI 0x40000000 diff --git a/drivers/net/ibm_newemac/rgmii.c b/drivers/net/ibm_newemac/rgmii.c index e32da3de269..1d5379de690 100644 --- a/drivers/net/ibm_newemac/rgmii.c +++ b/drivers/net/ibm_newemac/rgmii.c @@ -39,6 +39,7 @@ #define RGMII_FER_RGMII(idx) (0x5 << ((idx) * 4)) #define RGMII_FER_TBI(idx) (0x6 << ((idx) * 4)) #define RGMII_FER_GMII(idx) (0x7 << ((idx) * 4)) +#define RGMII_FER_MII(idx) RGMII_FER_GMII(idx) /* RGMIIx_SSR */ #define RGMII_SSR_MASK(idx) (0x7 << ((idx) * 8)) @@ -49,6 +50,7 @@ static inline int rgmii_valid_mode(int phy_mode) { return phy_mode == PHY_MODE_GMII || + phy_mode == PHY_MODE_MII || phy_mode == PHY_MODE_RGMII || phy_mode == PHY_MODE_TBI || phy_mode == PHY_MODE_RTBI; @@ -63,6 +65,8 @@ static inline const char *rgmii_mode_name(int mode) return "TBI"; case PHY_MODE_GMII: return "GMII"; + case PHY_MODE_MII: + return "MII"; case PHY_MODE_RTBI: return "RTBI"; default: @@ -79,6 +83,8 @@ static inline u32 rgmii_mode_mask(int mode, int input) return RGMII_FER_TBI(input); case PHY_MODE_GMII: return RGMII_FER_GMII(input); + case PHY_MODE_MII: + return RGMII_FER_MII(input); case PHY_MODE_RTBI: return RGMII_FER_RTBI(input); default: diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index fb0b918e5cc..402e81020fb 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c @@ -28,8 +28,8 @@ #include <linux/mii.h> #include <linux/phy.h> #include <linux/workqueue.h> +#include <linux/of_platform.h> -#include <asm/of_platform.h> #include <asm/uaccess.h> #include <asm/irq.h> #include <asm/io.h> diff --git a/drivers/net/ucc_geth_mii.c b/drivers/net/ucc_geth_mii.c index 94047473692..6d9e7ad9fda 100644 --- a/drivers/net/ucc_geth_mii.c +++ b/drivers/net/ucc_geth_mii.c @@ -36,8 +36,8 @@ #include <linux/mii.h> #include <linux/phy.h> #include <linux/fsl_devices.h> +#include <linux/of_platform.h> -#include <asm/of_platform.h> #include <asm/io.h> #include <asm/irq.h> #include <asm/uaccess.h> diff --git a/drivers/of/device.c b/drivers/of/device.c index 29681c4b700..8a1d93a2bb8 100644 --- a/drivers/of/device.c +++ b/drivers/of/device.c @@ -48,16 +48,32 @@ void of_dev_put(struct of_device *dev) } EXPORT_SYMBOL(of_dev_put); -static ssize_t dev_show_devspec(struct device *dev, +static ssize_t devspec_show(struct device *dev, struct device_attribute *attr, char *buf) { struct of_device *ofdev; ofdev = to_of_device(dev); - return sprintf(buf, "%s", ofdev->node->full_name); + return sprintf(buf, "%s\n", ofdev->node->full_name); } -static DEVICE_ATTR(devspec, S_IRUGO, dev_show_devspec, NULL); +static ssize_t modalias_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct of_device *ofdev = to_of_device(dev); + ssize_t len = 0; + + len = of_device_get_modalias(ofdev, buf, PAGE_SIZE - 2); + buf[len] = '\n'; + buf[len+1] = 0; + return len+1; +} + +struct device_attribute of_platform_device_attrs[] = { + __ATTR_RO(devspec), + __ATTR_RO(modalias), + __ATTR_NULL +}; /** * of_release_dev - free an of device structure when all users of it are finished. @@ -78,25 +94,61 @@ EXPORT_SYMBOL(of_release_dev); int of_device_register(struct of_device *ofdev) { - int rc; - BUG_ON(ofdev->node == NULL); - - rc = device_register(&ofdev->dev); - if (rc) - return rc; - - rc = device_create_file(&ofdev->dev, &dev_attr_devspec); - if (rc) - device_unregister(&ofdev->dev); - - return rc; + return device_register(&ofdev->dev); } EXPORT_SYMBOL(of_device_register); void of_device_unregister(struct of_device *ofdev) { - device_remove_file(&ofdev->dev, &dev_attr_devspec); device_unregister(&ofdev->dev); } EXPORT_SYMBOL(of_device_unregister); + +ssize_t of_device_get_modalias(struct of_device *ofdev, + char *str, ssize_t len) +{ + const char *compat; + int cplen, i; + ssize_t tsize, csize, repend; + + /* Name & Type */ + csize = snprintf(str, len, "of:N%sT%s", + ofdev->node->name, ofdev->node->type); + + /* Get compatible property if any */ + compat = of_get_property(ofdev->node, "compatible", &cplen); + if (!compat) + return csize; + + /* Find true end (we tolerate multiple \0 at the end */ + for (i = (cplen - 1); i >= 0 && !compat[i]; i--) + cplen--; + if (!cplen) + return csize; + cplen++; + + /* Check space (need cplen+1 chars including final \0) */ + tsize = csize + cplen; + repend = tsize; + + if (csize >= len) /* @ the limit, all is already filled */ + return tsize; + + if (tsize >= len) { /* limit compat list */ + cplen = len - csize - 1; + repend = len; + } + + /* Copy and do char replacement */ + memcpy(&str[csize + 1], compat, cplen); + for (i = csize; i < repend; i++) { + char c = str[i]; + if (c == '\0') + str[i] = 'C'; + else if (c == ' ') + str[i] = '_'; + } + + return tsize; +} diff --git a/drivers/of/gpio.c b/drivers/of/gpio.c index 000681e98f2..1c9cab844f1 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, } EXPORT_SYMBOL(of_gpio_simple_xlate); -/* Should be sufficient for now, later we'll use dynamic bases. */ -#if defined(CONFIG_PPC32) || defined(CONFIG_SPARC32) -#define GPIOS_PER_CHIP 32 -#else -#define GPIOS_PER_CHIP 64 -#endif - -static int of_get_gpiochip_base(struct device_node *np) -{ - struct device_node *gc = NULL; - int gpiochip_base = 0; - - while ((gc = of_find_all_nodes(gc))) { - if (!of_get_property(gc, "gpio-controller", NULL)) - continue; - - if (gc != np) { - gpiochip_base += GPIOS_PER_CHIP; - continue; - } - - of_node_put(gc); - - if (gpiochip_base >= ARCH_NR_GPIOS) - return -ENOSPC; - - return gpiochip_base; - } - - return -ENOENT; -} - /** * of_mm_gpiochip_add - Add memory mapped GPIO chip (bank) * @np: device node of the GPIO chip @@ -205,11 +173,7 @@ int of_mm_gpiochip_add(struct device_node *np, if (!mm_gc->regs) goto err1; - gc->base = of_get_gpiochip_base(np); - if (gc->base < 0) { - ret = gc->base; - goto err1; - } + gc->base = -1; if (!of_gc->xlate) of_gc->xlate = of_gpio_simple_xlate; diff --git a/drivers/of/of_i2c.c b/drivers/of/of_i2c.c index b2ccdcbeb89..5c015d310d4 100644 --- a/drivers/of/of_i2c.c +++ b/drivers/of/of_i2c.c @@ -13,6 +13,7 @@ #include <linux/i2c.h> #include <linux/of.h> +#include <linux/of_i2c.h> #include <linux/module.h> struct i2c_driver_device { diff --git a/drivers/of/platform.c b/drivers/of/platform.c index ca09a63a64d..298de0f95d7 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -17,6 +17,8 @@ #include <linux/of_device.h> #include <linux/of_platform.h> +extern struct device_attribute of_platform_device_attrs[]; + static int of_platform_bus_match(struct device *dev, struct device_driver *drv) { 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) bus->suspend = of_platform_device_suspend; bus->resume = of_platform_device_resume; bus->shutdown = of_platform_device_shutdown; + bus->dev_attrs = of_platform_device_attrs; return bus_register(bus); } diff --git a/drivers/pcmcia/electra_cf.c b/drivers/pcmcia/electra_cf.c index 52d0aa8c2e7..c21f9a9c3e3 100644 --- a/drivers/pcmcia/electra_cf.c +++ b/drivers/pcmcia/electra_cf.c @@ -29,9 +29,9 @@ #include <linux/delay.h> #include <linux/interrupt.h> #include <linux/vmalloc.h> +#include <linux/of_platform.h> #include <pcmcia/ss.h> -#include <asm/of_platform.h> static const char driver_name[] = "electra-cf"; diff --git a/drivers/pcmcia/m8xx_pcmcia.c b/drivers/pcmcia/m8xx_pcmcia.c index 13a5fbd50a0..ff66604e90d 100644 --- a/drivers/pcmcia/m8xx_pcmcia.c +++ b/drivers/pcmcia/m8xx_pcmcia.c @@ -49,6 +49,8 @@ #include <linux/interrupt.h> #include <linux/fsl_devices.h> #include <linux/bitops.h> +#include <linux/of_device.h> +#include <linux/of_platform.h> #include <asm/io.h> #include <asm/system.h> @@ -57,8 +59,6 @@ #include <asm/8xx_immap.h> #include <asm/irq.h> #include <asm/fs_pd.h> -#include <asm/of_device.h> -#include <asm/of_platform.h> #include <pcmcia/cs_types.h> #include <pcmcia/cs.h> diff --git a/drivers/serial/cpm_uart/cpm_uart.h b/drivers/serial/cpm_uart/cpm_uart.h index 0cc39f82d7c..5c76e0ae058 100644 --- a/drivers/serial/cpm_uart/cpm_uart.h +++ b/drivers/serial/cpm_uart/cpm_uart.h @@ -6,7 +6,7 @@ * Copyright (C) 2004 Freescale Semiconductor, Inc. * * 2006 (c) MontaVista Software, Inc. - * Vitaly Bordug <vbordug@ru.mvista.com> + * Vitaly Bordug <vbordug@ru.mvista.com> * * This file is licensed under the terms of the GNU General Public License * version 2. This program is licensed "as is" without any warranty of any @@ -28,7 +28,7 @@ #define SERIAL_CPM_MAJOR 204 #define SERIAL_CPM_MINOR 46 -#define IS_SMC(pinfo) (pinfo->flags & FLAG_SMC) +#define IS_SMC(pinfo) (pinfo->flags & FLAG_SMC) #define IS_DISCARDING(pinfo) (pinfo->flags & FLAG_DISCARDING) #define FLAG_DISCARDING 0x00000004 /* when set, don't discard */ #define FLAG_SMC 0x00000002 @@ -70,7 +70,7 @@ struct uart_cpm_port { void (*set_lineif)(struct uart_cpm_port *); u8 brg; uint dp_addr; - void *mem_addr; + void *mem_addr; dma_addr_t dma_addr; u32 mem_size; /* helpers */ @@ -79,14 +79,11 @@ struct uart_cpm_port { /* Keep track of 'odd' SMC2 wirings */ int is_portb; /* wait on close if needed */ - int wait_closing; + int wait_closing; /* value to combine with opcode to form cpm command */ u32 command; }; -#ifndef CONFIG_PPC_CPM_NEW_BINDING -extern int cpm_uart_port_map[UART_NR]; -#endif extern int cpm_uart_nr; extern struct uart_cpm_port cpm_uart_ports[UART_NR]; diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c index a19dc7ef886..abe129cc927 100644 --- a/drivers/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/serial/cpm_uart/cpm_uart_core.c @@ -13,7 +13,7 @@ * Copyright (C) 2004, 2007 Freescale Semiconductor, Inc. * (C) 2004 Intracom, S.A. * (C) 2005-2006 MontaVista Software, Inc. - * Vitaly Bordug <vbordug@ru.mvista.com> + * Vitaly Bordug <vbordug@ru.mvista.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -42,6 +42,7 @@ #include <linux/bootmem.h> #include <linux/dma-mapping.h> #include <linux/fs_uart_pd.h> +#include <linux/of_platform.h> #include <asm/io.h> #include <asm/irq.h> @@ -49,10 +50,6 @@ #include <asm/fs_pd.h> #include <asm/udbg.h> -#ifdef CONFIG_PPC_CPM_NEW_BINDING -#include <linux/of_platform.h> -#endif - #if defined(CONFIG_SERIAL_CPM_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) #define SUPPORT_SYSRQ #endif @@ -72,59 +69,6 @@ static void cpm_uart_initbd(struct uart_cpm_port *pinfo); /**************************************************************/ -#ifndef CONFIG_PPC_CPM_NEW_BINDING -/* Track which ports are configured as uarts */ -int cpm_uart_port_map[UART_NR]; -/* How many ports did we config as uarts */ -int cpm_uart_nr; - -/* Place-holder for board-specific stuff */ -struct platform_device* __attribute__ ((weak)) __init -early_uart_get_pdev(int index) -{ - return NULL; -} - - -static void cpm_uart_count(void) -{ - cpm_uart_nr = 0; -#ifdef CONFIG_SERIAL_CPM_SMC1 - cpm_uart_port_map[cpm_uart_nr++] = UART_SMC1; -#endif -#ifdef CONFIG_SERIAL_CPM_SMC2 - cpm_uart_port_map[cpm_uart_nr++] = UART_SMC2; -#endif -#ifdef CONFIG_SERIAL_CPM_SCC1 - cpm_uart_port_map[cpm_uart_nr++] = UART_SCC1; -#endif -#ifdef CONFIG_SERIAL_CPM_SCC2 - cpm_uart_port_map[cpm_uart_nr++] = UART_SCC2; -#endif -#ifdef CONFIG_SERIAL_CPM_SCC3 - cpm_uart_port_map[cpm_uart_nr++] = UART_SCC3; -#endif -#ifdef CONFIG_SERIAL_CPM_SCC4 - cpm_uart_port_map[cpm_uart_nr++] = UART_SCC4; -#endif -} - -/* Get UART number by its id */ -static int cpm_uart_id2nr(int id) -{ - int i; - if (id < UART_NR) { - for (i=0; i<UART_NR; i++) { - if (cpm_uart_port_map[i] == id) - return i; - } - } - - /* not found or invalid argument */ - return -1; -} -#endif - /* * Check, if transmit buffers are processed */ @@ -547,6 +491,11 @@ static void cpm_uart_set_termios(struct uart_port *port, } /* + * Update the timeout + */ + uart_update_timeout(port, termios->c_cflag, baud); + + /* * Set up parity check flag */ #define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) @@ -935,7 +884,6 @@ static struct uart_ops cpm_uart_pops = { .verify_port = cpm_uart_verify_port, }; -#ifdef CONFIG_PPC_CPM_NEW_BINDING struct uart_cpm_port cpm_uart_ports[UART_NR]; static int cpm_uart_init_port(struct device_node *np, @@ -995,6 +943,7 @@ static int cpm_uart_init_port(struct device_node *np, pinfo->port.type = PORT_CPM; pinfo->port.ops = &cpm_uart_pops, pinfo->port.iotype = UPIO_MEM; + pinfo->port.fifosize = pinfo->tx_nrfifos * pinfo->tx_fifosize; spin_lock_init(&pinfo->port.lock); pinfo->port.irq = of_irq_to_resource(np, 0, NULL); @@ -1012,153 +961,6 @@ out_mem: return ret; } -#else - -struct uart_cpm_port cpm_uart_ports[UART_NR] = { - [UART_SMC1] = { - .port = { - .irq = SMC1_IRQ, - .ops = &cpm_uart_pops, - .iotype = UPIO_MEM, - .lock = __SPIN_LOCK_UNLOCKED(cpm_uart_ports[UART_SMC1].port.lock), - }, - .flags = FLAG_SMC, - .tx_nrfifos = TX_NUM_FIFO, - .tx_fifosize = TX_BUF_SIZE, - .rx_nrfifos = RX_NUM_FIFO, - .rx_fifosize = RX_BUF_SIZE, - .set_lineif = smc1_lineif, - }, - [UART_SMC2] = { - .port = { - .irq = SMC2_IRQ, - .ops = &cpm_uart_pops, - .iotype = UPIO_MEM, - .lock = __SPIN_LOCK_UNLOCKED(cpm_uart_ports[UART_SMC2].port.lock), - }, - .flags = FLAG_SMC, - .tx_nrfifos = TX_NUM_FIFO, - .tx_fifosize = TX_BUF_SIZE, - .rx_nrfifos = RX_NUM_FIFO, - .rx_fifosize = RX_BUF_SIZE, - .set_lineif = smc2_lineif, -#ifdef CONFIG_SERIAL_CPM_ALT_SMC2 - .is_portb = 1, -#endif - }, - [UART_SCC1] = { - .port = { - .irq = SCC1_IRQ, - .ops = &cpm_uart_pops, - .iotype = UPIO_MEM, - .lock = __SPIN_LOCK_UNLOCKED(cpm_uart_ports[UART_SCC1].port.lock), - }, - .tx_nrfifos = TX_NUM_FIFO, - .tx_fifosize = TX_BUF_SIZE, - .rx_nrfifos = RX_NUM_FIFO, - .rx_fifosize = RX_BUF_SIZE, - .set_lineif = scc1_lineif, - .wait_closing = SCC_WAIT_CLOSING, - }, - [UART_SCC2] = { - .port = { - .irq = SCC2_IRQ, - .ops = &cpm_uart_pops, - .iotype = UPIO_MEM, - .lock = __SPIN_LOCK_UNLOCKED(cpm_uart_ports[UART_SCC2].port.lock), - }, - .tx_nrfifos = TX_NUM_FIFO, - .tx_fifosize = TX_BUF_SIZE, - .rx_nrfifos = RX_NUM_FIFO, - .rx_fifosize = RX_BUF_SIZE, - .set_lineif = scc2_lineif, - .wait_closing = SCC_WAIT_CLOSING, - }, - [UART_SCC3] = { - .port = { - .irq = SCC3_IRQ, - .ops = &cpm_uart_pops, - .iotype = UPIO_MEM, - .lock = __SPIN_LOCK_UNLOCKED(cpm_uart_ports[UART_SCC3].port.lock), - }, - .tx_nrfifos = TX_NUM_FIFO, - .tx_fifosize = TX_BUF_SIZE, - .rx_nrfifos = RX_NUM_FIFO, - .rx_fifosize = RX_BUF_SIZE, - .set_lineif = scc3_lineif, - .wait_closing = SCC_WAIT_CLOSING, - }, - [UART_SCC4] = { - .port = { - .irq = SCC4_IRQ, - .ops = &cpm_uart_pops, - .iotype = UPIO_MEM, - .lock = __SPIN_LOCK_UNLOCKED(cpm_uart_ports[UART_SCC4].port.lock), - }, - .tx_nrfifos = TX_NUM_FIFO, - .tx_fifosize = TX_BUF_SIZE, - .rx_nrfifos = RX_NUM_FIFO, - .rx_fifosize = RX_BUF_SIZE, - .set_lineif = scc4_lineif, - .wait_closing = SCC_WAIT_CLOSING, - }, -}; - -int cpm_uart_drv_get_platform_data(struct platform_device *pdev, int is_con) -{ - struct resource *r; - struct fs_uart_platform_info *pdata = pdev->dev.platform_data; - int idx; /* It is UART_SMCx or UART_SCCx index */ - struct uart_cpm_port *pinfo; - int line; - u32 mem, pram; - - idx = pdata->fs_no = fs_uart_get_id(pdata); - - line = cpm_uart_id2nr(idx); - if(line < 0) { - printk(KERN_ERR"%s(): port %d is not registered", __func__, idx); - return -EINVAL; - } - - pinfo = (struct uart_cpm_port *) &cpm_uart_ports[idx]; - - pinfo->brg = pdata->brg; - - if (!is_con) { - pinfo->port.line = line; - pinfo->port.flags = UPF_BOOT_AUTOCONF; - } - - if (!(r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs"))) - return -EINVAL; - mem = (u32)ioremap(r->start, r->end - r->start + 1); - - if (!(r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pram"))) - return -EINVAL; - pram = (u32)ioremap(r->start, r->end - r->start + 1); - - if(idx > fsid_smc2_uart) { - pinfo->sccp = (scc_t *)mem; - pinfo->sccup = (scc_uart_t *)pram; - } else { - pinfo->smcp = (smc_t *)mem; - pinfo->smcup = (smc_uart_t *)pram; - } - pinfo->tx_nrfifos = pdata->tx_num_fifo; - pinfo->tx_fifosize = pdata->tx_buf_size; - - pinfo->rx_nrfifos = pdata->rx_num_fifo; - pinfo->rx_fifosize = pdata->rx_buf_size; - - pinfo->port.uartclk = pdata->uart_clk; - pinfo->port.mapbase = (unsigned long)mem; - pinfo->port.irq = platform_get_irq(pdev, 0); - - return 0; -} -#endif - #ifdef CONFIG_SERIAL_CPM_CONSOLE /* * 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) static void cpm_uart_console_write(struct console *co, const char *s, u_int count) { -#ifdef CONFIG_PPC_CPM_NEW_BINDING struct uart_cpm_port *pinfo = &cpm_uart_ports[co->index]; -#else - struct uart_cpm_port *pinfo = - &cpm_uart_ports[cpm_uart_port_map[co->index]]; -#endif unsigned int i; cbd_t __iomem *bdp, *bdbase; unsigned char *cp; + unsigned long flags; + int nolock = oops_in_progress; + + if (unlikely(nolock)) { + local_irq_save(flags); + } else { + spin_lock_irqsave(&pinfo->port.lock, flags); + } /* Get the address of the host memory buffer. */ @@ -1239,6 +1044,12 @@ static void cpm_uart_console_write(struct console *co, const char *s, ; pinfo->tx_cur = bdp; + + if (unlikely(nolock)) { + local_irq_restore(flags); + } else { + spin_unlock_irqrestore(&pinfo->port.lock, flags); + } } @@ -1252,7 +1063,6 @@ static int __init cpm_uart_console_setup(struct console *co, char *options) struct uart_cpm_port *pinfo; struct uart_port *port; -#ifdef CONFIG_PPC_CPM_NEW_BINDING struct device_node *np = NULL; int i = 0; @@ -1284,35 +1094,6 @@ static int __init cpm_uart_console_setup(struct console *co, char *options) if (ret) return ret; -#else - - struct fs_uart_platform_info *pdata; - struct platform_device* pdev = early_uart_get_pdev(co->index); - - if (!pdev) { - pr_info("cpm_uart: console: compat mode\n"); - /* compatibility - will be cleaned up */ - cpm_uart_init_portdesc(); - } - - port = - (struct uart_port *)&cpm_uart_ports[cpm_uart_port_map[co->index]]; - pinfo = (struct uart_cpm_port *)port; - if (!pdev) { - if (pinfo->set_lineif) - pinfo->set_lineif(pinfo); - } else { - pdata = pdev->dev.platform_data; - if (pdata) - if (pdata->init_ioports) - pdata->init_ioports(pdata); - - cpm_uart_drv_get_platform_data(pdev, 1); - } - - pinfo->flags |= FLAG_CONSOLE; -#endif - if (options) { uart_parse_options(options, &baud, &parity, &bits, &flow); } else { @@ -1386,7 +1167,6 @@ static struct uart_driver cpm_reg = { .nr = UART_NR, }; -#ifdef CONFIG_PPC_CPM_NEW_BINDING static int probe_index; static int __devinit cpm_uart_probe(struct of_device *ofdev, @@ -1457,135 +1237,6 @@ static void __exit cpm_uart_exit(void) of_unregister_platform_driver(&cpm_uart_driver); uart_unregister_driver(&cpm_reg); } -#else -static int cpm_uart_drv_probe(struct device *dev) -{ - struct platform_device *pdev = to_platform_device(dev); - struct fs_uart_platform_info *pdata; - int ret = -ENODEV; - - if(!pdev) { - printk(KERN_ERR"CPM UART: platform data missing!\n"); - return ret; - } - - pdata = pdev->dev.platform_data; - - if ((ret = cpm_uart_drv_get_platform_data(pdev, 0))) - return ret; - - pr_debug("cpm_uart_drv_probe: Adding CPM UART %d\n", cpm_uart_id2nr(pdata->fs_no)); - - if (pdata->init_ioports) - pdata->init_ioports(pdata); - - ret = uart_add_one_port(&cpm_reg, &cpm_uart_ports[pdata->fs_no].port); - - return ret; -} - -static int cpm_uart_drv_remove(struct device *dev) -{ - struct platform_device *pdev = to_platform_device(dev); - struct fs_uart_platform_info *pdata = pdev->dev.platform_data; - - pr_debug("cpm_uart_drv_remove: Removing CPM UART %d\n", - cpm_uart_id2nr(pdata->fs_no)); - - uart_remove_one_port(&cpm_reg, &cpm_uart_ports[pdata->fs_no].port); - return 0; -} - -static struct device_driver cpm_smc_uart_driver = { - .name = "fsl-cpm-smc:uart", - .bus = &platform_bus_type, - .probe = cpm_uart_drv_probe, - .remove = cpm_uart_drv_remove, -}; - -static struct device_driver cpm_scc_uart_driver = { - .name = "fsl-cpm-scc:uart", - .bus = &platform_bus_type, - .probe = cpm_uart_drv_probe, - .remove = cpm_uart_drv_remove, -}; - -/* - This is supposed to match uart devices on platform bus, - */ -static int match_is_uart (struct device* dev, void* data) -{ - struct platform_device* pdev = container_of(dev, struct platform_device, dev); - int ret = 0; - /* this was setfunc as uart */ - if(strstr(pdev->name,":uart")) { - ret = 1; - } - return ret; -} - - -static int cpm_uart_init(void) { - - int ret; - int i; - struct device *dev; - printk(KERN_INFO "Serial: CPM driver $Revision: 0.02 $\n"); - - /* lookup the bus for uart devices */ - dev = bus_find_device(&platform_bus_type, NULL, 0, match_is_uart); - - /* There are devices on the bus - all should be OK */ - if (dev) { - cpm_uart_count(); - cpm_reg.nr = cpm_uart_nr; - - if (!(ret = uart_register_driver(&cpm_reg))) { - if ((ret = driver_register(&cpm_smc_uart_driver))) { - uart_unregister_driver(&cpm_reg); - return ret; - } - if ((ret = driver_register(&cpm_scc_uart_driver))) { - driver_unregister(&cpm_scc_uart_driver); - uart_unregister_driver(&cpm_reg); - } - } - } else { - /* No capable platform devices found - falling back to legacy mode */ - pr_info("cpm_uart: WARNING: no UART devices found on platform bus!\n"); - pr_info( - "cpm_uart: the driver will guess configuration, but this mode is no longer supported.\n"); - - /* Don't run this again, if the console driver did it already */ - if (cpm_uart_nr == 0) - cpm_uart_init_portdesc(); - - cpm_reg.nr = cpm_uart_nr; - ret = uart_register_driver(&cpm_reg); - - if (ret) - return ret; - - for (i = 0; i < cpm_uart_nr; i++) { - int con = cpm_uart_port_map[i]; - cpm_uart_ports[con].port.line = i; - cpm_uart_ports[con].port.flags = UPF_BOOT_AUTOCONF; - if (cpm_uart_ports[con].set_lineif) - cpm_uart_ports[con].set_lineif(&cpm_uart_ports[con]); - uart_add_one_port(&cpm_reg, &cpm_uart_ports[con].port); - } - - } - return ret; -} - -static void __exit cpm_uart_exit(void) -{ - driver_unregister(&cpm_scc_uart_driver); - driver_unregister(&cpm_smc_uart_driver); - uart_unregister_driver(&cpm_reg); -} -#endif module_init(cpm_uart_init); 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 74f1432bb24..0f0aff06c59 100644 --- a/drivers/serial/cpm_uart/cpm_uart_cpm1.c +++ b/drivers/serial/cpm_uart/cpm_uart_cpm1.c @@ -9,7 +9,7 @@ * Copyright (C) 2004 Freescale Semiconductor, Inc. * (C) 2004 Intracom, S.A. * (C) 2006 MontaVista Software, Inc. - * Vitaly Bordug <vbordug@ru.mvista.com> + * Vitaly Bordug <vbordug@ru.mvista.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -51,7 +51,6 @@ /**************************************************************/ -#ifdef CONFIG_PPC_CPM_NEW_BINDING void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd) { cpm_command(port->command, cmd); @@ -68,75 +67,6 @@ void cpm_uart_unmap_pram(struct uart_cpm_port *port, void __iomem *pram) iounmap(pram); } -#else -void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd) -{ - ushort val; - int line = port - cpm_uart_ports; - volatile cpm8xx_t *cp = cpmp; - - switch (line) { - case UART_SMC1: - val = mk_cr_cmd(CPM_CR_CH_SMC1, cmd) | CPM_CR_FLG; - break; - case UART_SMC2: - val = mk_cr_cmd(CPM_CR_CH_SMC2, cmd) | CPM_CR_FLG; - break; - case UART_SCC1: - val = mk_cr_cmd(CPM_CR_CH_SCC1, cmd) | CPM_CR_FLG; - break; - case UART_SCC2: - val = mk_cr_cmd(CPM_CR_CH_SCC2, cmd) | CPM_CR_FLG; - break; - case UART_SCC3: - val = mk_cr_cmd(CPM_CR_CH_SCC3, cmd) | CPM_CR_FLG; - break; - case UART_SCC4: - val = mk_cr_cmd(CPM_CR_CH_SCC4, cmd) | CPM_CR_FLG; - break; - default: - return; - - } - cp->cp_cpcr = val; - while (cp->cp_cpcr & CPM_CR_FLG) ; -} - -void smc1_lineif(struct uart_cpm_port *pinfo) -{ - pinfo->brg = 1; -} - -void smc2_lineif(struct uart_cpm_port *pinfo) -{ - pinfo->brg = 2; -} - -void scc1_lineif(struct uart_cpm_port *pinfo) -{ - /* XXX SCC1: insert port configuration here */ - pinfo->brg = 1; -} - -void scc2_lineif(struct uart_cpm_port *pinfo) -{ - /* XXX SCC2: insert port configuration here */ - pinfo->brg = 2; -} - -void scc3_lineif(struct uart_cpm_port *pinfo) -{ - /* XXX SCC3: insert port configuration here */ - pinfo->brg = 3; -} - -void scc4_lineif(struct uart_cpm_port *pinfo) -{ - /* XXX SCC4: insert port configuration here */ - pinfo->brg = 4; -} -#endif - /* * Allocate DP-Ram and memory buffers. We need to allocate a transmit and * receive buffer descriptors from dual port ram, and a character @@ -205,101 +135,3 @@ void cpm_uart_freebuf(struct uart_cpm_port *pinfo) cpm_dpfree(pinfo->dp_addr); } - -#ifndef CONFIG_PPC_CPM_NEW_BINDING -/* Setup any dynamic params in the uart desc */ -int cpm_uart_init_portdesc(void) -{ - pr_debug("CPM uart[-]:init portdesc\n"); - - cpm_uart_nr = 0; -#ifdef CONFIG_SERIAL_CPM_SMC1 - cpm_uart_ports[UART_SMC1].smcp = &cpmp->cp_smc[0]; -/* - * Is SMC1 being relocated? - */ -# ifdef CONFIG_I2C_SPI_SMC1_UCODE_PATCH - cpm_uart_ports[UART_SMC1].smcup = - (smc_uart_t *) & cpmp->cp_dparam[0x3C0]; -# else - cpm_uart_ports[UART_SMC1].smcup = - (smc_uart_t *) & cpmp->cp_dparam[PROFF_SMC1]; -# endif - cpm_uart_ports[UART_SMC1].port.mapbase = - (unsigned long)&cpmp->cp_smc[0]; - cpm_uart_ports[UART_SMC1].smcp->smc_smcm |= (SMCM_RX | SMCM_TX); - cpm_uart_ports[UART_SMC1].smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); - cpm_uart_ports[UART_SMC1].port.uartclk = uart_clock(); - cpm_uart_port_map[cpm_uart_nr++] = UART_SMC1; -#endif - -#ifdef CONFIG_SERIAL_CPM_SMC2 - cpm_uart_ports[UART_SMC2].smcp = &cpmp->cp_smc[1]; - cpm_uart_ports[UART_SMC2].smcup = - (smc_uart_t *) & cpmp->cp_dparam[PROFF_SMC2]; - cpm_uart_ports[UART_SMC2].port.mapbase = - (unsigned long)&cpmp->cp_smc[1]; - cpm_uart_ports[UART_SMC2].smcp->smc_smcm |= (SMCM_RX | SMCM_TX); - cpm_uart_ports[UART_SMC2].smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); - cpm_uart_ports[UART_SMC2].port.uartclk = uart_clock(); - cpm_uart_port_map[cpm_uart_nr++] = UART_SMC2; -#endif - -#ifdef CONFIG_SERIAL_CPM_SCC1 - cpm_uart_ports[UART_SCC1].sccp = &cpmp->cp_scc[0]; - cpm_uart_ports[UART_SCC1].sccup = - (scc_uart_t *) & cpmp->cp_dparam[PROFF_SCC1]; - cpm_uart_ports[UART_SCC1].port.mapbase = - (unsigned long)&cpmp->cp_scc[0]; - cpm_uart_ports[UART_SCC1].sccp->scc_sccm &= - ~(UART_SCCM_TX | UART_SCCM_RX); - cpm_uart_ports[UART_SCC1].sccp->scc_gsmrl &= - ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); - cpm_uart_ports[UART_SCC1].port.uartclk = uart_clock(); - cpm_uart_port_map[cpm_uart_nr++] = UART_SCC1; -#endif - -#ifdef CONFIG_SERIAL_CPM_SCC2 - cpm_uart_ports[UART_SCC2].sccp = &cpmp->cp_scc[1]; - cpm_uart_ports[UART_SCC2].sccup = - (scc_uart_t *) & cpmp->cp_dparam[PROFF_SCC2]; - cpm_uart_ports[UART_SCC2].port.mapbase = - (unsigned long)&cpmp->cp_scc[1]; - cpm_uart_ports[UART_SCC2].sccp->scc_sccm &= - ~(UART_SCCM_TX | UART_SCCM_RX); - cpm_uart_ports[UART_SCC2].sccp->scc_gsmrl &= - ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); - cpm_uart_ports[UART_SCC2].port.uartclk = uart_clock(); - cpm_uart_port_map[cpm_uart_nr++] = UART_SCC2; -#endif - -#ifdef CONFIG_SERIAL_CPM_SCC3 - cpm_uart_ports[UART_SCC3].sccp = &cpmp->cp_scc[2]; - cpm_uart_ports[UART_SCC3].sccup = - (scc_uart_t *) & cpmp->cp_dparam[PROFF_SCC3]; - cpm_uart_ports[UART_SCC3].port.mapbase = - (unsigned long)&cpmp->cp_scc[2]; - cpm_uart_ports[UART_SCC3].sccp->scc_sccm &= - ~(UART_SCCM_TX | UART_SCCM_RX); - cpm_uart_ports[UART_SCC3].sccp->scc_gsmrl &= - ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); - cpm_uart_ports[UART_SCC3].port.uartclk = uart_clock(); - cpm_uart_port_map[cpm_uart_nr++] = UART_SCC3; -#endif - -#ifdef CONFIG_SERIAL_CPM_SCC4 - cpm_uart_ports[UART_SCC4].sccp = &cpmp->cp_scc[3]; - cpm_uart_ports[UART_SCC4].sccup = - (scc_uart_t *) & cpmp->cp_dparam[PROFF_SCC4]; - cpm_uart_ports[UART_SCC4].port.mapbase = - (unsigned long)&cpmp->cp_scc[3]; - cpm_uart_ports[UART_SCC4].sccp->scc_sccm &= - ~(UART_SCCM_TX | UART_SCCM_RX); - cpm_uart_ports[UART_SCC4].sccp->scc_gsmrl &= - ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); - cpm_uart_ports[UART_SCC4].port.uartclk = uart_clock(); - cpm_uart_port_map[cpm_uart_nr++] = UART_SCC4; -#endif - return 0; -} -#endif diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm1.h b/drivers/serial/cpm_uart/cpm_uart_cpm1.h index ddf46d3c964..10eecd6af6d 100644 --- a/drivers/serial/cpm_uart/cpm_uart_cpm1.h +++ b/drivers/serial/cpm_uart/cpm_uart_cpm1.h @@ -2,7 +2,7 @@ * linux/drivers/serial/cpm_uart/cpm_uart_cpm1.h * * Driver for CPM (SCC/SMC) serial ports - * + * * definitions for cpm1 * */ @@ -12,16 +12,6 @@ #include <asm/cpm1.h> -/* defines for IRQs */ -#ifndef CONFIG_PPC_CPM_NEW_BINDING -#define SMC1_IRQ (CPM_IRQ_OFFSET + CPMVEC_SMC1) -#define SMC2_IRQ (CPM_IRQ_OFFSET + CPMVEC_SMC2) -#define SCC1_IRQ (CPM_IRQ_OFFSET + CPMVEC_SCC1) -#define SCC2_IRQ (CPM_IRQ_OFFSET + CPMVEC_SCC2) -#define SCC3_IRQ (CPM_IRQ_OFFSET + CPMVEC_SCC3) -#define SCC4_IRQ (CPM_IRQ_OFFSET + CPMVEC_SCC4) -#endif - static inline void cpm_set_brg(int brg, int baud) { 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 bb862e2f54c..b8db4d3eed3 100644 --- a/drivers/serial/cpm_uart/cpm_uart_cpm2.c +++ b/drivers/serial/cpm_uart/cpm_uart_cpm2.c @@ -5,11 +5,11 @@ * * Maintainer: Kumar Gala (galak@kernel.crashing.org) (CPM2) * Pantelis Antoniou (panto@intracom.gr) (CPM1) - * + * * Copyright (C) 2004 Freescale Semiconductor, Inc. * (C) 2004 Intracom, S.A. * (C) 2006 MontaVista Software, Inc. - * Vitaly Bordug <vbordug@ru.mvista.com> + * Vitaly Bordug <vbordug@ru.mvista.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -41,9 +41,7 @@ #include <asm/io.h> #include <asm/irq.h> #include <asm/fs_pd.h> -#ifdef CONFIG_PPC_CPM_NEW_BINDING #include <asm/prom.h> -#endif #include <linux/serial_core.h> #include <linux/kernel.h> @@ -52,7 +50,6 @@ /**************************************************************/ -#ifdef CONFIG_PPC_CPM_NEW_BINDING void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd) { cpm_command(port->command, cmd); @@ -106,174 +103,8 @@ void cpm_uart_unmap_pram(struct uart_cpm_port *port, void __iomem *pram) iounmap(pram); } -#else -void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd) -{ - ulong val; - int line = port - cpm_uart_ports; - volatile cpm_cpm2_t *cp = cpm2_map(im_cpm); - - - switch (line) { - case UART_SMC1: - val = mk_cr_cmd(CPM_CR_SMC1_PAGE, CPM_CR_SMC1_SBLOCK, 0, - cmd) | CPM_CR_FLG; - break; - case UART_SMC2: - val = mk_cr_cmd(CPM_CR_SMC2_PAGE, CPM_CR_SMC2_SBLOCK, 0, - cmd) | CPM_CR_FLG; - break; - case UART_SCC1: - val = mk_cr_cmd(CPM_CR_SCC1_PAGE, CPM_CR_SCC1_SBLOCK, 0, - cmd) | CPM_CR_FLG; - break; - case UART_SCC2: - val = mk_cr_cmd(CPM_CR_SCC2_PAGE, CPM_CR_SCC2_SBLOCK, 0, - cmd) | CPM_CR_FLG; - break; - case UART_SCC3: - val = mk_cr_cmd(CPM_CR_SCC3_PAGE, CPM_CR_SCC3_SBLOCK, 0, - cmd) | CPM_CR_FLG; - break; - case UART_SCC4: - val = mk_cr_cmd(CPM_CR_SCC4_PAGE, CPM_CR_SCC4_SBLOCK, 0, - cmd) | CPM_CR_FLG; - break; - default: - return; - - } - cp->cp_cpcr = val; - while (cp->cp_cpcr & CPM_CR_FLG) ; - - cpm2_unmap(cp); -} - -void smc1_lineif(struct uart_cpm_port *pinfo) -{ - volatile iop_cpm2_t *io = cpm2_map(im_ioport); - volatile cpmux_t *cpmux = cpm2_map(im_cpmux); - - /* SMC1 is only on port D */ - io->iop_ppard |= 0x00c00000; - io->iop_pdird |= 0x00400000; - io->iop_pdird &= ~0x00800000; - io->iop_psord &= ~0x00c00000; - - /* Wire BRG1 to SMC1 */ - cpmux->cmx_smr &= 0x0f; - pinfo->brg = 1; - - cpm2_unmap(cpmux); - cpm2_unmap(io); -} - -void smc2_lineif(struct uart_cpm_port *pinfo) -{ - volatile iop_cpm2_t *io = cpm2_map(im_ioport); - volatile cpmux_t *cpmux = cpm2_map(im_cpmux); - - /* SMC2 is only on port A */ - io->iop_ppara |= 0x00c00000; - io->iop_pdira |= 0x00400000; - io->iop_pdira &= ~0x00800000; - io->iop_psora &= ~0x00c00000; - - /* Wire BRG2 to SMC2 */ - cpmux->cmx_smr &= 0xf0; - pinfo->brg = 2; - - cpm2_unmap(cpmux); - cpm2_unmap(io); -} - -void scc1_lineif(struct uart_cpm_port *pinfo) -{ - volatile iop_cpm2_t *io = cpm2_map(im_ioport); - volatile cpmux_t *cpmux = cpm2_map(im_cpmux); - - /* Use Port D for SCC1 instead of other functions. */ - io->iop_ppard |= 0x00000003; - io->iop_psord &= ~0x00000001; /* Rx */ - io->iop_psord |= 0x00000002; /* Tx */ - io->iop_pdird &= ~0x00000001; /* Rx */ - io->iop_pdird |= 0x00000002; /* Tx */ - - /* Wire BRG1 to SCC1 */ - cpmux->cmx_scr &= 0x00ffffff; - cpmux->cmx_scr |= 0x00000000; - pinfo->brg = 1; - - cpm2_unmap(cpmux); - cpm2_unmap(io); -} - -void scc2_lineif(struct uart_cpm_port *pinfo) -{ - /* - * STx GP3 uses the SCC2 secondary option pin assignment - * which this driver doesn't account for in the static - * pin assignments. This kind of board specific info - * really has to get out of the driver so boards can - * be supported in a sane fashion. - */ - volatile cpmux_t *cpmux = cpm2_map(im_cpmux); -#ifndef CONFIG_STX_GP3 - volatile iop_cpm2_t *io = cpm2_map(im_ioport); - - io->iop_pparb |= 0x008b0000; - io->iop_pdirb |= 0x00880000; - io->iop_psorb |= 0x00880000; - io->iop_pdirb &= ~0x00030000; - io->iop_psorb &= ~0x00030000; -#endif - cpmux->cmx_scr &= 0xff00ffff; - cpmux->cmx_scr |= 0x00090000; - pinfo->brg = 2; - - cpm2_unmap(cpmux); - cpm2_unmap(io); -} - -void scc3_lineif(struct uart_cpm_port *pinfo) -{ - volatile iop_cpm2_t *io = cpm2_map(im_ioport); - volatile cpmux_t *cpmux = cpm2_map(im_cpmux); - - io->iop_pparb |= 0x008b0000; - io->iop_pdirb |= 0x00880000; - io->iop_psorb |= 0x00880000; - io->iop_pdirb &= ~0x00030000; - io->iop_psorb &= ~0x00030000; - cpmux->cmx_scr &= 0xffff00ff; - cpmux->cmx_scr |= 0x00001200; - pinfo->brg = 3; - - cpm2_unmap(cpmux); - cpm2_unmap(io); -} - -void scc4_lineif(struct uart_cpm_port *pinfo) -{ - volatile iop_cpm2_t *io = cpm2_map(im_ioport); - volatile cpmux_t *cpmux = cpm2_map(im_cpmux); - - io->iop_ppard |= 0x00000600; - io->iop_psord &= ~0x00000600; /* Tx/Rx */ - io->iop_pdird &= ~0x00000200; /* Rx */ - io->iop_pdird |= 0x00000400; /* Tx */ - - cpmux->cmx_scr &= 0xffffff00; - cpmux->cmx_scr |= 0x0000001b; - pinfo->brg = 4; - - cpm2_unmap(cpmux); - cpm2_unmap(io); -} -#endif - /* - * Allocate DP-Ram and memory buffers. We need to allocate a transmit and + * Allocate DP-Ram and memory buffers. We need to allocate a transmit and * receive buffer descriptors from dual port ram, and a character * buffer area from host mem. If we are allocating for the console we need * to do it from bootmem @@ -340,111 +171,3 @@ void cpm_uart_freebuf(struct uart_cpm_port *pinfo) cpm_dpfree(pinfo->dp_addr); } - -#ifndef CONFIG_PPC_CPM_NEW_BINDING -/* Setup any dynamic params in the uart desc */ -int cpm_uart_init_portdesc(void) -{ -#if defined(CONFIG_SERIAL_CPM_SMC1) || defined(CONFIG_SERIAL_CPM_SMC2) - u16 *addr; -#endif - pr_debug("CPM uart[-]:init portdesc\n"); - - cpm_uart_nr = 0; -#ifdef CONFIG_SERIAL_CPM_SMC1 - cpm_uart_ports[UART_SMC1].smcp = (smc_t *) cpm2_map(im_smc[0]); - cpm_uart_ports[UART_SMC1].port.mapbase = - (unsigned long)cpm_uart_ports[UART_SMC1].smcp; - - cpm_uart_ports[UART_SMC1].smcup = - (smc_uart_t *) cpm2_map_size(im_dprambase[PROFF_SMC1], PROFF_SMC_SIZE); - addr = (u16 *)cpm2_map_size(im_dprambase[PROFF_SMC1_BASE], 2); - *addr = PROFF_SMC1; - cpm2_unmap(addr); - - cpm_uart_ports[UART_SMC1].smcp->smc_smcm |= (SMCM_RX | SMCM_TX); - cpm_uart_ports[UART_SMC1].smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); - cpm_uart_ports[UART_SMC1].port.uartclk = uart_clock(); - cpm_uart_port_map[cpm_uart_nr++] = UART_SMC1; -#endif - -#ifdef CONFIG_SERIAL_CPM_SMC2 - cpm_uart_ports[UART_SMC2].smcp = (smc_t *) cpm2_map(im_smc[1]); - cpm_uart_ports[UART_SMC2].port.mapbase = - (unsigned long)cpm_uart_ports[UART_SMC2].smcp; - - cpm_uart_ports[UART_SMC2].smcup = - (smc_uart_t *) cpm2_map_size(im_dprambase[PROFF_SMC2], PROFF_SMC_SIZE); - addr = (u16 *)cpm2_map_size(im_dprambase[PROFF_SMC2_BASE], 2); - *addr = PROFF_SMC2; - cpm2_unmap(addr); - - cpm_uart_ports[UART_SMC2].smcp->smc_smcm |= (SMCM_RX | SMCM_TX); - cpm_uart_ports[UART_SMC2].smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); - cpm_uart_ports[UART_SMC2].port.uartclk = uart_clock(); - cpm_uart_port_map[cpm_uart_nr++] = UART_SMC2; -#endif - -#ifdef CONFIG_SERIAL_CPM_SCC1 - cpm_uart_ports[UART_SCC1].sccp = (scc_t *) cpm2_map(im_scc[0]); - cpm_uart_ports[UART_SCC1].port.mapbase = - (unsigned long)cpm_uart_ports[UART_SCC1].sccp; - cpm_uart_ports[UART_SCC1].sccup = - (scc_uart_t *) cpm2_map_size(im_dprambase[PROFF_SCC1], PROFF_SCC_SIZE); - - cpm_uart_ports[UART_SCC1].sccp->scc_sccm &= - ~(UART_SCCM_TX | UART_SCCM_RX); - cpm_uart_ports[UART_SCC1].sccp->scc_gsmrl &= - ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); - cpm_uart_ports[UART_SCC1].port.uartclk = uart_clock(); - cpm_uart_port_map[cpm_uart_nr++] = UART_SCC1; -#endif - -#ifdef CONFIG_SERIAL_CPM_SCC2 - cpm_uart_ports[UART_SCC2].sccp = (scc_t *) cpm2_map(im_scc[1]); - cpm_uart_ports[UART_SCC2].port.mapbase = - (unsigned long)cpm_uart_ports[UART_SCC2].sccp; - cpm_uart_ports[UART_SCC2].sccup = - (scc_uart_t *) cpm2_map_size(im_dprambase[PROFF_SCC2], PROFF_SCC_SIZE); - - cpm_uart_ports[UART_SCC2].sccp->scc_sccm &= - ~(UART_SCCM_TX | UART_SCCM_RX); - cpm_uart_ports[UART_SCC2].sccp->scc_gsmrl &= - ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); - cpm_uart_ports[UART_SCC2].port.uartclk = uart_clock(); - cpm_uart_port_map[cpm_uart_nr++] = UART_SCC2; -#endif - -#ifdef CONFIG_SERIAL_CPM_SCC3 - cpm_uart_ports[UART_SCC3].sccp = (scc_t *) cpm2_map(im_scc[2]); - cpm_uart_ports[UART_SCC3].port.mapbase = - (unsigned long)cpm_uart_ports[UART_SCC3].sccp; - cpm_uart_ports[UART_SCC3].sccup = - (scc_uart_t *) cpm2_map_size(im_dprambase[PROFF_SCC3], PROFF_SCC_SIZE); - - cpm_uart_ports[UART_SCC3].sccp->scc_sccm &= - ~(UART_SCCM_TX | UART_SCCM_RX); - cpm_uart_ports[UART_SCC3].sccp->scc_gsmrl &= - ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); - cpm_uart_ports[UART_SCC3].port.uartclk = uart_clock(); - cpm_uart_port_map[cpm_uart_nr++] = UART_SCC3; -#endif - -#ifdef CONFIG_SERIAL_CPM_SCC4 - cpm_uart_ports[UART_SCC4].sccp = (scc_t *) cpm2_map(im_scc[3]); - cpm_uart_ports[UART_SCC4].port.mapbase = - (unsigned long)cpm_uart_ports[UART_SCC4].sccp; - cpm_uart_ports[UART_SCC4].sccup = - (scc_uart_t *) cpm2_map_size(im_dprambase[PROFF_SCC4], PROFF_SCC_SIZE); - - cpm_uart_ports[UART_SCC4].sccp->scc_sccm &= - ~(UART_SCCM_TX | UART_SCCM_RX); - cpm_uart_ports[UART_SCC4].sccp->scc_gsmrl &= - ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); - cpm_uart_ports[UART_SCC4].port.uartclk = uart_clock(); - cpm_uart_port_map[cpm_uart_nr++] = UART_SCC4; -#endif - - return 0; -} -#endif diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm2.h b/drivers/serial/cpm_uart/cpm_uart_cpm2.h index 40006a7dce4..7194c63dcf5 100644 --- a/drivers/serial/cpm_uart/cpm_uart_cpm2.h +++ b/drivers/serial/cpm_uart/cpm_uart_cpm2.h @@ -2,7 +2,7 @@ * linux/drivers/serial/cpm_uart/cpm_uart_cpm2.h * * Driver for CPM (SCC/SMC) serial ports - * + * * definitions for cpm2 * */ @@ -12,16 +12,6 @@ #include <asm/cpm2.h> -/* defines for IRQs */ -#ifndef CONFIG_PPC_CPM_NEW_BINDING -#define SMC1_IRQ SIU_INT_SMC1 -#define SMC2_IRQ SIU_INT_SMC2 -#define SCC1_IRQ SIU_INT_SCC1 -#define SCC2_IRQ SIU_INT_SCC2 -#define SCC3_IRQ SIU_INT_SCC3 -#define SCC4_IRQ SIU_INT_SCC4 -#endif - static inline void cpm_set_brg(int brg, int baud) { cpm_setbrg(brg, baud); diff --git a/drivers/serial/of_serial.c b/drivers/serial/of_serial.c index 25029c7570b..8fa0ff561e9 100644 --- a/drivers/serial/of_serial.c +++ b/drivers/serial/of_serial.c @@ -13,8 +13,8 @@ #include <linux/module.h> #include <linux/serial_core.h> #include <linux/serial_8250.h> +#include <linux/of_platform.h> -#include <asm/of_platform.h> #include <asm/prom.h> struct of_serial_info { diff --git a/drivers/spi/mpc52xx_psc_spi.c b/drivers/spi/mpc52xx_psc_spi.c index 681d62325d3..604e5f0a2d9 100644 --- a/drivers/spi/mpc52xx_psc_spi.c +++ b/drivers/spi/mpc52xx_psc_spi.c @@ -17,7 +17,7 @@ #include <linux/interrupt.h> #if defined(CONFIG_PPC_MERGE) -#include <asm/of_platform.h> +#include <linux/of_platform.h> #else #include <linux/platform_device.h> #endif diff --git a/drivers/video/platinumfb.c b/drivers/video/platinumfb.c index cbe71a5338d..03b3670130a 100644 --- a/drivers/video/platinumfb.c +++ b/drivers/video/platinumfb.c @@ -31,11 +31,11 @@ #include <linux/fb.h> #include <linux/init.h> #include <linux/nvram.h> +#include <linux/of_device.h> +#include <linux/of_platform.h> #include <asm/io.h> #include <asm/prom.h> #include <asm/pgtable.h> -#include <asm/of_device.h> -#include <asm/of_platform.h> #include "macmodes.h" #include "platinumfb.h" diff --git a/drivers/watchdog/mpc5200_wdt.c b/drivers/watchdog/mpc5200_wdt.c index 80a91d4cea1..77c1c2ae2cc 100644 --- a/drivers/watchdog/mpc5200_wdt.c +++ b/drivers/watchdog/mpc5200_wdt.c @@ -4,7 +4,7 @@ #include <linux/watchdog.h> #include <linux/io.h> #include <linux/spinlock.h> -#include <asm/of_platform.h> +#include <linux/of_platform.h> #include <asm/uaccess.h> #include <asm/mpc52xx.h> |