From 70c14ff0e9f5e1f5456587b827620e636ba70a09 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 20 Jul 2007 02:07:26 +0100 Subject: [ARM] 4495/1: iop: combined watchdog timer driver for iop3xx and iop13xx In order for this driver to be shared across the iop architectures the iop3xx and iop13xx header files are modified to present a common interface for the iop_wdt driver. Details: * iop13xx supports disabling the timer while iop3xx does not. This requires a few 'compatibility' definitions in include/asm-arm/hardware/iop3xx.h to preclude adding #ifdef CONFIG_ARCH_IOP13XX blocks to the driver code. * The heartbeat interval is derived from the internal bus clock rate, so this this patch also exports the tick rate to the iop_wdt driver. Cc: Curt Bruns Cc: Peter Milne Signed-off-by: Dan Williams Acked-by: Wim Van Sebroeck Signed-off-by: Russell King --- drivers/char/watchdog/Kconfig | 16 +++ drivers/char/watchdog/Makefile | 1 + drivers/char/watchdog/iop_wdt.c | 262 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 279 insertions(+) create mode 100644 drivers/char/watchdog/iop_wdt.c (limited to 'drivers') diff --git a/drivers/char/watchdog/Kconfig b/drivers/char/watchdog/Kconfig index 2f48ba32996..a4d81cda479 100644 --- a/drivers/char/watchdog/Kconfig +++ b/drivers/char/watchdog/Kconfig @@ -187,6 +187,22 @@ config PNX4008_WATCHDOG Say N if you are unsure. +config IOP_WATCHDOG + tristate "IOP Watchdog" + depends on WATCHDOG && PLAT_IOP + select WATCHDOG_NOWAYOUT if (ARCH_IOP32X || ARCH_IOP33X) + help + Say Y here if to include support for the watchdog timer + in the Intel IOP3XX & IOP13XX I/O Processors. This driver can + be built as a module by choosing M. The module will + be called iop_wdt. + + Note: The IOP13XX watchdog does an Internal Bus Reset which will + affect both cores and the peripherals of the IOP. The ATU-X + and/or ATUe configuration registers will remain intact, but if + operating as an Root Complex and/or Central Resource, the PCI-X + and/or PCIe busses will also be reset. THIS IS A VERY BIG HAMMER. + # AVR32 Architecture config AT32AP700X_WDT diff --git a/drivers/char/watchdog/Makefile b/drivers/char/watchdog/Makefile index 3907ec04a4e..bdb9d5e3bb4 100644 --- a/drivers/char/watchdog/Makefile +++ b/drivers/char/watchdog/Makefile @@ -35,6 +35,7 @@ obj-$(CONFIG_SA1100_WATCHDOG) += sa1100_wdt.o obj-$(CONFIG_MPCORE_WATCHDOG) += mpcore_wdt.o obj-$(CONFIG_EP93XX_WATCHDOG) += ep93xx_wdt.o obj-$(CONFIG_PNX4008_WATCHDOG) += pnx4008_wdt.o +obj-$(CONFIG_IOP_WATCHDOG) += iop_wdt.o # AVR32 Architecture obj-$(CONFIG_AT32AP700X_WDT) += at32ap700x_wdt.o diff --git a/drivers/char/watchdog/iop_wdt.c b/drivers/char/watchdog/iop_wdt.c new file mode 100644 index 00000000000..bbbd91af754 --- /dev/null +++ b/drivers/char/watchdog/iop_wdt.c @@ -0,0 +1,262 @@ +/* + * drivers/char/watchdog/iop_wdt.c + * + * WDT driver for Intel I/O Processors + * Copyright (C) 2005, Intel Corporation. + * + * Based on ixp4xx driver, Copyright 2004 (c) MontaVista, Software, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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. + * + * Curt E Bruns + * Peter Milne + * Dan Williams + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int nowayout = WATCHDOG_NOWAYOUT; +static unsigned long wdt_status; +static unsigned long boot_status; + +#define WDT_IN_USE 0 +#define WDT_OK_TO_CLOSE 1 +#define WDT_ENABLED 2 + +static unsigned long iop_watchdog_timeout(void) +{ + return (0xffffffffUL / get_iop_tick_rate()); +} + +/** + * wdt_supports_disable - determine if we are accessing a iop13xx watchdog + * or iop3xx by whether it has a disable command + */ +static int wdt_supports_disable(void) +{ + int can_disable; + + if (IOP_WDTCR_EN_ARM != IOP_WDTCR_DIS_ARM) + can_disable = 1; + else + can_disable = 0; + + return can_disable; +} + +static void wdt_enable(void) +{ + /* Arm and enable the Timer to starting counting down from 0xFFFF.FFFF + * Takes approx. 10.7s to timeout + */ + write_wdtcr(IOP_WDTCR_EN_ARM); + write_wdtcr(IOP_WDTCR_EN); +} + +/* returns 0 if the timer was successfully disabled */ +static int wdt_disable(void) +{ + /* Stop Counting */ + if (wdt_supports_disable()) { + write_wdtcr(IOP_WDTCR_DIS_ARM); + write_wdtcr(IOP_WDTCR_DIS); + clear_bit(WDT_ENABLED, &wdt_status); + printk(KERN_INFO "WATCHDOG: Disabled\n"); + return 0; + } else + return 1; +} + +static int iop_wdt_open(struct inode *inode, struct file *file) +{ + if (test_and_set_bit(WDT_IN_USE, &wdt_status)) + return -EBUSY; + + clear_bit(WDT_OK_TO_CLOSE, &wdt_status); + + wdt_enable(); + + set_bit(WDT_ENABLED, &wdt_status); + + return nonseekable_open(inode, file); +} + +static ssize_t +iop_wdt_write(struct file *file, const char *data, size_t len, + loff_t *ppos) +{ + if (len) { + if (!nowayout) { + size_t i; + + clear_bit(WDT_OK_TO_CLOSE, &wdt_status); + + for (i = 0; i != len; i++) { + char c; + + if (get_user(c, data + i)) + return -EFAULT; + if (c == 'V') + set_bit(WDT_OK_TO_CLOSE, &wdt_status); + } + } + wdt_enable(); + } + + return len; +} + +static struct watchdog_info ident = { + .options = WDIOF_CARDRESET | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING, + .identity = "iop watchdog", +}; + +static int +iop_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, + unsigned long arg) +{ + int options; + int ret = -ENOTTY; + + switch (cmd) { + case WDIOC_GETSUPPORT: + if (copy_to_user + ((struct watchdog_info *)arg, &ident, sizeof ident)) + ret = -EFAULT; + else + ret = 0; + break; + + case WDIOC_GETSTATUS: + ret = put_user(0, (int *)arg); + break; + + case WDIOC_GETBOOTSTATUS: + ret = put_user(boot_status, (int *)arg); + break; + + case WDIOC_GETTIMEOUT: + ret = put_user(iop_watchdog_timeout(), (int *)arg); + break; + + case WDIOC_KEEPALIVE: + wdt_enable(); + ret = 0; + break; + + case WDIOC_SETOPTIONS: + if (get_user(options, (int *)arg)) + return -EFAULT; + + if (options & WDIOS_DISABLECARD) { + if (!nowayout) { + if (wdt_disable() == 0) { + set_bit(WDT_OK_TO_CLOSE, &wdt_status); + ret = 0; + } else + ret = -ENXIO; + } else + ret = 0; + } + + if (options & WDIOS_ENABLECARD) { + wdt_enable(); + ret = 0; + } + break; + } + + return ret; +} + +static int iop_wdt_release(struct inode *inode, struct file *file) +{ + int state = 1; + if (test_bit(WDT_OK_TO_CLOSE, &wdt_status)) + if (test_bit(WDT_ENABLED, &wdt_status)) + state = wdt_disable(); + + /* if the timer is not disbaled reload and notify that we are still + * going down + */ + if (state != 0) { + wdt_enable(); + printk(KERN_CRIT "WATCHDOG: Device closed unexpectedly - " + "reset in %lu seconds\n", iop_watchdog_timeout()); + } + + clear_bit(WDT_IN_USE, &wdt_status); + clear_bit(WDT_OK_TO_CLOSE, &wdt_status); + + return 0; +} + +static const struct file_operations iop_wdt_fops = { + .owner = THIS_MODULE, + .llseek = no_llseek, + .write = iop_wdt_write, + .ioctl = iop_wdt_ioctl, + .open = iop_wdt_open, + .release = iop_wdt_release, +}; + +static struct miscdevice iop_wdt_miscdev = { + .minor = WATCHDOG_MINOR, + .name = "watchdog", + .fops = &iop_wdt_fops, +}; + +static int __init iop_wdt_init(void) +{ + int ret; + + ret = misc_register(&iop_wdt_miscdev); + if (ret == 0) + printk("iop watchdog timer: timeout %lu sec\n", + iop_watchdog_timeout()); + + /* check if the reset was caused by the watchdog timer */ + boot_status = (read_rcsr() & IOP_RCSR_WDT) ? WDIOF_CARDRESET : 0; + + /* Configure Watchdog Timeout to cause an Internal Bus (IB) Reset + * NOTE: An IB Reset will Reset both cores in the IOP342 + */ + write_wdtsr(IOP13XX_WDTCR_IB_RESET); + + return ret; +} + +static void __exit iop_wdt_exit(void) +{ + misc_deregister(&iop_wdt_miscdev); +} + +module_init(iop_wdt_init); +module_exit(iop_wdt_exit); + +module_param(nowayout, int, 0); +MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started"); + +MODULE_AUTHOR("Curt E Bruns "); +MODULE_DESCRIPTION("iop watchdog timer driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); -- cgit v1.2.3 From 6accc0575c6b2105bf9b00bfc8cfee2cead3df6d Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 15 Jul 2007 12:33:16 +0100 Subject: [ARM] rpc: remove linux/ptrace.h from ARM ether?.c drivers Signed-off-by: Russell King --- drivers/net/arm/ether1.c | 1 - drivers/net/arm/ether3.c | 1 - drivers/net/arm/etherh.c | 1 - 3 files changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/arm/ether1.c b/drivers/net/arm/ether1.c index f21148e7b57..d1f2f684b70 100644 --- a/drivers/net/arm/ether1.c +++ b/drivers/net/arm/ether1.c @@ -36,7 +36,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/arm/ether3.c b/drivers/net/arm/ether3.c index a7cac695a9b..32630493a4e 100644 --- a/drivers/net/arm/ether3.c +++ b/drivers/net/arm/ether3.c @@ -51,7 +51,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/arm/etherh.c b/drivers/net/arm/etherh.c index 769ba69451f..0d37d9d1fd7 100644 --- a/drivers/net/arm/etherh.c +++ b/drivers/net/arm/etherh.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include -- cgit v1.2.3 From 07ed31319422e82d50dfae7aebf88514d258b8f3 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 15 Jul 2007 12:51:41 +0100 Subject: [ARM] rpc: silence two section mismatch warnings WARNING: drivers/built-in.o(.text+0x3fd54): Section mismatch: reference to .init.data: (between 'ether3_probe' and 'ether1_setmulticastlist') WARNING: drivers/built-in.o(.text+0x40380): Section mismatch: reference to .init.data: (between 'ether1_probe' and 'ether1_interrupt') Signed-off-by: Russell King --- drivers/net/arm/ether1.c | 2 +- drivers/net/arm/ether3.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/arm/ether1.c b/drivers/net/arm/ether1.c index d1f2f684b70..80f33b6d571 100644 --- a/drivers/net/arm/ether1.c +++ b/drivers/net/arm/ether1.c @@ -74,7 +74,7 @@ static void ether1_timeout(struct net_device *dev); /* ------------------------------------------------------------------------- */ -static char version[] __initdata = "ether1 ethernet driver (c) 2000 Russell King v1.07\n"; +static char version[] __devinitdata = "ether1 ethernet driver (c) 2000 Russell King v1.07\n"; #define BUS_16 16 #define BUS_8 8 diff --git a/drivers/net/arm/ether3.c b/drivers/net/arm/ether3.c index 32630493a4e..3805506a3ab 100644 --- a/drivers/net/arm/ether3.c +++ b/drivers/net/arm/ether3.c @@ -68,7 +68,7 @@ #include #include -static char version[] __initdata = "ether3 ethernet driver (c) 1995-2000 R.M.King v1.17\n"; +static char version[] __devinitdata = "ether3 ethernet driver (c) 1995-2000 R.M.King v1.17\n"; #include "ether3.h" -- cgit v1.2.3 From 4b300c362d690c8e0788f69ed91c22a0a76f7ce2 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Tue, 17 Jul 2007 13:35:46 +0100 Subject: [ARM] 4481/1: Fix a bug when i.MX is compiled as a module Fix the unregistration order in the i.MX serial driver Signed-off-by: Sreekrishnan Venkateswaran Acked-by: Sascha Hauer Signed-off-by: Russell King --- drivers/serial/imx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c index e42faa4e428..dc1967176fe 100644 --- a/drivers/serial/imx.c +++ b/drivers/serial/imx.c @@ -1114,8 +1114,8 @@ static int __init imx_serial_init(void) static void __exit imx_serial_exit(void) { - uart_unregister_driver(&imx_reg); platform_driver_unregister(&serial_imx_driver); + uart_unregister_driver(&imx_reg); } module_init(imx_serial_init); -- cgit v1.2.3 From 8b801ead3d7ab3cce991ea3a2d00c7336215fc7d Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 20 Jul 2007 10:38:54 +0100 Subject: [ARM] rpc: update Acorn SCSI drivers to modern ecard interfaces Signed-off-by: Russell King --- drivers/scsi/arm/cumana_1.c | 207 +++++++++++++++++++++----------------------- drivers/scsi/arm/ecoscsi.c | 152 +++++++++----------------------- drivers/scsi/arm/oak.c | 74 +++++++++------- 3 files changed, 185 insertions(+), 248 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/arm/cumana_1.c b/drivers/scsi/arm/cumana_1.c index cf9a21cea6d..49d838e90a2 100644 --- a/drivers/scsi/arm/cumana_1.c +++ b/drivers/scsi/arm/cumana_1.c @@ -24,7 +24,7 @@ #define CUMANASCSI_PUBLIC_RELEASE 1 -#define NCR5380_implementation_fields int port, ctrl +#define priv(host) ((struct NCR5380_hostdata *)(host)->hostdata) #define NCR5380_local_declare() struct Scsi_Host *_instance #define NCR5380_setup(instance) _instance = instance #define NCR5380_read(reg) cumanascsi_read(_instance, reg) @@ -33,6 +33,11 @@ #define NCR5380_queue_command cumanascsi_queue_command #define NCR5380_proc_info cumanascsi_proc_info +#define NCR5380_implementation_fields \ + unsigned ctrl; \ + void __iomem *base; \ + void __iomem *dma + #define BOARD_NORMAL 0 #define BOARD_NCR53C400 1 @@ -47,192 +52,162 @@ const char *cumanascsi_info(struct Scsi_Host *spnt) return ""; } -#ifdef NOT_EFFICIENT -#define CTRL(p,v) outb(*ctrl = (v), (p) - 577) -#define STAT(p) inb((p)+1) -#define IN(p) inb((p)) -#define OUT(v,p) outb((v), (p)) -#else -#define CTRL(p,v) (p[-2308] = (*ctrl = (v))) -#define STAT(p) (p[4]) -#define IN(p) (*(p)) -#define IN2(p) ((unsigned short)(*(volatile unsigned long *)(p))) -#define OUT(v,p) (*(p) = (v)) -#define OUT2(v,p) (*((volatile unsigned long *)(p)) = (v)) -#endif -#define L(v) (((v)<<16)|((v) & 0x0000ffff)) -#define H(v) (((v)>>16)|((v) & 0xffff0000)) +#define CTRL 0x16fc +#define STAT 0x2004 +#define L(v) (((v)<<16)|((v) & 0x0000ffff)) +#define H(v) (((v)>>16)|((v) & 0xffff0000)) static inline int -NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *addr, int len) +NCR5380_pwrite(struct Scsi_Host *host, unsigned char *addr, int len) { - int *ctrl = &((struct NCR5380_hostdata *)instance->hostdata)->ctrl; - int oldctrl = *ctrl; unsigned long *laddr; -#ifdef NOT_EFFICIENT - int iobase = instance->io_port; - int dma_io = iobase & ~(0x3C0000>>2); -#else - volatile unsigned char *iobase = (unsigned char *)ioaddr(instance->io_port); - volatile unsigned char *dma_io = (unsigned char *)((int)iobase & ~0x3C0000); -#endif + void __iomem *dma = priv(host)->dma + 0x2000; if(!len) return 0; - CTRL(iobase, 0x02); + writeb(0x02, priv(host)->base + CTRL); laddr = (unsigned long *)addr; while(len >= 32) { - int status; + unsigned int status; unsigned long v; - status = STAT(iobase); + status = readb(priv(host)->base + STAT); if(status & 0x80) goto end; if(!(status & 0x40)) continue; - v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io); - v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io); - v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io); - v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io); - v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io); - v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io); - v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io); - v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io); + v=*laddr++; writew(L(v), dma); writew(H(v), dma); + v=*laddr++; writew(L(v), dma); writew(H(v), dma); + v=*laddr++; writew(L(v), dma); writew(H(v), dma); + v=*laddr++; writew(L(v), dma); writew(H(v), dma); + v=*laddr++; writew(L(v), dma); writew(H(v), dma); + v=*laddr++; writew(L(v), dma); writew(H(v), dma); + v=*laddr++; writew(L(v), dma); writew(H(v), dma); + v=*laddr++; writew(L(v), dma); writew(H(v), dma); len -= 32; if(len == 0) break; } addr = (unsigned char *)laddr; - CTRL(iobase, 0x12); + writeb(0x12, priv(host)->base + CTRL); + while(len > 0) { - int status; - status = STAT(iobase); + unsigned int status; + status = readb(priv(host)->base + STAT); if(status & 0x80) goto end; if(status & 0x40) { - OUT(*addr++, dma_io); + writeb(*addr++, dma); if(--len == 0) break; } - status = STAT(iobase); + status = readb(priv(host)->base + STAT); if(status & 0x80) goto end; if(status & 0x40) { - OUT(*addr++, dma_io); + writeb(*addr++, dma); if(--len == 0) break; } } end: - CTRL(iobase, oldctrl|0x40); + writeb(priv(host)->ctrl | 0x40, priv(host)->base + CTRL); return len; } static inline int -NCR5380_pread(struct Scsi_Host *instance, unsigned char *addr, int len) +NCR5380_pread(struct Scsi_Host *host, unsigned char *addr, int len) { - int *ctrl = &((struct NCR5380_hostdata *)instance->hostdata)->ctrl; - int oldctrl = *ctrl; unsigned long *laddr; -#ifdef NOT_EFFICIENT - int iobase = instance->io_port; - int dma_io = iobase & ~(0x3C0000>>2); -#else - volatile unsigned char *iobase = (unsigned char *)ioaddr(instance->io_port); - volatile unsigned char *dma_io = (unsigned char *)((int)iobase & ~0x3C0000); -#endif + void __iomem *dma = priv(host)->dma + 0x2000; if(!len) return 0; - CTRL(iobase, 0x00); + writeb(0x00, priv(host)->base + CTRL); laddr = (unsigned long *)addr; while(len >= 32) { - int status; - status = STAT(iobase); + unsigned int status; + status = readb(priv(host)->base + STAT); if(status & 0x80) goto end; if(!(status & 0x40)) continue; - *laddr++ = IN2(dma_io)|(IN2(dma_io)<<16); - *laddr++ = IN2(dma_io)|(IN2(dma_io)<<16); - *laddr++ = IN2(dma_io)|(IN2(dma_io)<<16); - *laddr++ = IN2(dma_io)|(IN2(dma_io)<<16); - *laddr++ = IN2(dma_io)|(IN2(dma_io)<<16); - *laddr++ = IN2(dma_io)|(IN2(dma_io)<<16); - *laddr++ = IN2(dma_io)|(IN2(dma_io)<<16); - *laddr++ = IN2(dma_io)|(IN2(dma_io)<<16); + *laddr++ = readw(dma) | (readw(dma) << 16); + *laddr++ = readw(dma) | (readw(dma) << 16); + *laddr++ = readw(dma) | (readw(dma) << 16); + *laddr++ = readw(dma) | (readw(dma) << 16); + *laddr++ = readw(dma) | (readw(dma) << 16); + *laddr++ = readw(dma) | (readw(dma) << 16); + *laddr++ = readw(dma) | (readw(dma) << 16); + *laddr++ = readw(dma) | (readw(dma) << 16); len -= 32; if(len == 0) break; } addr = (unsigned char *)laddr; - CTRL(iobase, 0x10); + writeb(0x10, priv(host)->base + CTRL); + while(len > 0) { - int status; - status = STAT(iobase); + unsigned int status; + status = readb(priv(host)->base + STAT); if(status & 0x80) goto end; if(status & 0x40) { - *addr++ = IN(dma_io); + *addr++ = readb(dma); if(--len == 0) break; } - status = STAT(iobase); + status = readb(priv(host)->base + STAT); if(status & 0x80) goto end; if(status & 0x40) { - *addr++ = IN(dma_io); + *addr++ = readb(dma); if(--len == 0) break; } } end: - CTRL(iobase, oldctrl|0x40); + writeb(priv(host)->ctrl | 0x40, priv(host)->base + CTRL); return len; } -#undef STAT -#undef CTRL -#undef IN -#undef OUT +static unsigned char cumanascsi_read(struct Scsi_Host *host, unsigned int reg) +{ + void __iomem *base = priv(host)->base; + unsigned char val; -#define CTRL(p,v) outb(*ctrl = (v), (p) - 577) + writeb(0, base + CTRL); -static char cumanascsi_read(struct Scsi_Host *instance, int reg) -{ - unsigned int iobase = instance->io_port; - int i; - int *ctrl = &((struct NCR5380_hostdata *)instance->hostdata)->ctrl; + val = readb(base + 0x2100 + (reg << 2)); - CTRL(iobase, 0); - i = inb(iobase + 64 + reg); - CTRL(iobase, 0x40); + priv(host)->ctrl = 0x40; + writeb(0x40, base + CTRL); - return i; + return val; } -static void cumanascsi_write(struct Scsi_Host *instance, int reg, int value) +static void cumanascsi_write(struct Scsi_Host *host, unsigned int reg, unsigned int value) { - int iobase = instance->io_port; - int *ctrl = &((struct NCR5380_hostdata *)instance->hostdata)->ctrl; + void __iomem *base = priv(host)->base; - CTRL(iobase, 0); - outb(value, iobase + 64 + reg); - CTRL(iobase, 0x40); -} + writeb(0, base + CTRL); -#undef CTRL + writeb(value, base + 0x2100 + (reg << 2)); + + priv(host)->ctrl = 0x40; + writeb(0x40, base + CTRL); +} #include "../NCR5380.c" @@ -256,32 +231,46 @@ static int __devinit cumanascsi1_probe(struct expansion_card *ec, const struct ecard_id *id) { struct Scsi_Host *host; - int ret = -ENOMEM; + int ret; - host = scsi_host_alloc(&cumanascsi_template, sizeof(struct NCR5380_hostdata)); - if (!host) + ret = ecard_request_resources(ec); + if (ret) goto out; - host->io_port = ecard_address(ec, ECARD_IOC, ECARD_SLOW) + 0x800; + host = scsi_host_alloc(&cumanascsi_template, sizeof(struct NCR5380_hostdata)); + if (!host) { + ret = -ENOMEM; + goto out_release; + } + + priv(host)->base = ioremap(ecard_resource_start(ec, ECARD_RES_IOCSLOW), + ecard_resource_len(ec, ECARD_RES_IOCSLOW)); + priv(host)->dma = ioremap(ecard_resource_start(ec, ECARD_RES_MEMC), + ecard_resource_len(ec, ECARD_RES_MEMC)); + if (!priv(host)->base || !priv(host)->dma) { + ret = -ENOMEM; + goto out_unmap; + } + host->irq = ec->irq; NCR5380_init(host, 0); + priv(host)->ctrl = 0; + writeb(0, priv(host)->base + CTRL); + host->n_io_port = 255; if (!(request_region(host->io_port, host->n_io_port, "CumanaSCSI-1"))) { ret = -EBUSY; - goto out_free; + goto out_unmap; } - ((struct NCR5380_hostdata *)host->hostdata)->ctrl = 0; - outb(0x00, host->io_port - 577); - ret = request_irq(host->irq, cumanascsi_intr, IRQF_DISABLED, "CumanaSCSI-1", host); if (ret) { printk("scsi%d: IRQ%d not free: %d\n", host->host_no, host->irq, ret); - goto out_release; + goto out_unmap; } printk("scsi%d: at port 0x%08lx irq %d", @@ -301,10 +290,12 @@ cumanascsi1_probe(struct expansion_card *ec, const struct ecard_id *id) out_free_irq: free_irq(host->irq, host); - out_release: - release_region(host->io_port, host->n_io_port); - out_free: + out_unmap: + iounmap(priv(host)->base); + iounmap(priv(host)->dma); scsi_host_put(host); + out_release: + ecard_release_resources(ec); out: return ret; } @@ -318,8 +309,10 @@ static void __devexit cumanascsi1_remove(struct expansion_card *ec) scsi_remove_host(host); free_irq(host->irq, host); NCR5380_exit(host); - release_region(host->io_port, host->n_io_port); + iounmap(priv(host)->base); + iounmap(priv(host)->dma); scsi_host_put(host); + ecard_release_resources(ec); } static const struct ecard_id cumanascsi1_cids[] = { diff --git a/drivers/scsi/arm/ecoscsi.c b/drivers/scsi/arm/ecoscsi.c index 378e7af0c5d..5265a988433 100644 --- a/drivers/scsi/arm/ecoscsi.c +++ b/drivers/scsi/arm/ecoscsi.c @@ -34,35 +34,25 @@ #include "../scsi.h" #include -#define NCR5380_implementation_fields int port, ctrl -#define NCR5380_local_declare() struct Scsi_Host *_instance -#define NCR5380_setup(instance) _instance = instance +#define priv(host) ((struct NCR5380_hostdata *)(host)->hostdata) -#define NCR5380_read(reg) ecoscsi_read(_instance, reg) -#define NCR5380_write(reg, value) ecoscsi_write(_instance, reg, value) +#define NCR5380_local_declare() void __iomem *_base +#define NCR5380_setup(host) _base = priv(host)->base + +#define NCR5380_read(reg) ({ writeb(reg | 8, _base); readb(_base + 4); }) +#define NCR5380_write(reg, value) ({ writeb(reg | 8, _base); writeb(value, _base + 4); }) #define NCR5380_intr ecoscsi_intr #define NCR5380_queue_command ecoscsi_queue_command #define NCR5380_proc_info ecoscsi_proc_info +#define NCR5380_implementation_fields \ + void __iomem *base + #include "../NCR5380.h" #define ECOSCSI_PUBLIC_RELEASE 1 -static char ecoscsi_read(struct Scsi_Host *instance, int reg) -{ - int iobase = instance->io_port; - outb(reg | 8, iobase); - return inb(iobase + 1); -} - -static void ecoscsi_write(struct Scsi_Host *instance, int reg, int value) -{ - int iobase = instance->io_port; - outb(reg | 8, iobase); - outb(value, iobase + 1); -} - /* * Function : ecoscsi_setup(char *str, int *ints) * @@ -82,73 +72,6 @@ const char * ecoscsi_info (struct Scsi_Host *spnt) return ""; } -#if 0 -#define STAT(p) inw(p + 144) - -static inline int NCR5380_pwrite(struct Scsi_Host *host, unsigned char *addr, - int len) -{ - int iobase = host->io_port; -printk("writing %p len %d\n",addr, len); - if(!len) return -1; - - while(1) - { - int status; - while(((status = STAT(iobase)) & 0x100)==0); - } -} - -static inline int NCR5380_pread(struct Scsi_Host *host, unsigned char *addr, - int len) -{ - int iobase = host->io_port; - int iobase2= host->io_port + 0x100; - unsigned char *start = addr; - int s; -printk("reading %p len %d\n",addr, len); - outb(inb(iobase + 128), iobase + 135); - while(len > 0) - { - int status,b,i, timeout; - timeout = 0x07FFFFFF; - while(((status = STAT(iobase)) & 0x100)==0) - { - timeout--; - if(status & 0x200 || !timeout) - { - printk("status = %p\n",status); - outb(0, iobase + 135); - return 1; - } - } - if(len >= 128) - { - for(i=0; i<64; i++) - { - b = inw(iobase + 136); - *addr++ = b; - *addr++ = b>>8; - } - len -= 128; - } - else - { - b = inw(iobase + 136); - *addr ++ = b; - len -= 1; - if(len) - *addr ++ = b>>8; - len -= 1; - } - } - outb(0, iobase + 135); - printk("first bytes = %02X %02X %02X %20X %02X %02X %02X\n",*start, start[1], start[2], start[3], start[4], start[5], start[6]); - return 1; -} -#endif -#undef STAT - #define BOARD_NORMAL 0 #define BOARD_NCR53C400 1 @@ -173,25 +96,36 @@ static struct Scsi_Host *host; static int __init ecoscsi_init(void) { + void __iomem *_base; + int ret; - host = scsi_host_alloc(tpnt, sizeof(struct NCR5380_hostdata)); - if (!host) - return 0; + if (!request_mem_region(0x33a0000, 4096, "ecoscsi")) { + ret = -EBUSY; + goto out; + } - host->io_port = 0x80ce8000; - host->n_io_port = 144; - host->irq = IRQ_NONE; + _base = ioremap(0x33a0000, 4096); + if (!_base) { + ret = -ENOMEM; + goto out_release; + } - if (!(request_region(host->io_port, host->n_io_port, "ecoscsi")) ) - goto unregister_scsi; + NCR5380_write(MODE_REG, 0x20); /* Is it really SCSI? */ + if (NCR5380_read(MODE_REG) != 0x20) /* Write to a reg. */ + goto out_unmap; - ecoscsi_write(host, MODE_REG, 0x20); /* Is it really SCSI? */ - if (ecoscsi_read(host, MODE_REG) != 0x20) /* Write to a reg. */ - goto release_reg; + NCR5380_write(MODE_REG, 0x00); /* it back. */ + if (NCR5380_read(MODE_REG) != 0x00) + goto out_unmap; - ecoscsi_write(host, MODE_REG, 0x00 ); /* it back. */ - if (ecoscsi_read(host, MODE_REG) != 0x00) - goto release_reg; + host = scsi_host_alloc(tpnt, sizeof(struct NCR5380_hostdata)); + if (!host) { + ret = -ENOMEM; + goto out_unmap; + } + + priv(host)->base = _base; + host->irq = IRQ_NONE; NCR5380_init(host, 0); @@ -206,24 +140,20 @@ static int __init ecoscsi_init(void) scsi_scan_host(host); return 0; -release_reg: - release_region(host->io_port, host->n_io_port); -unregister_scsi: - scsi_host_put(host); - return -ENODEV; + out_unmap: + iounmap(_base); + out_release: + release_mem_region(0x33a0000, 4096); + out: + return ret; } static void __exit ecoscsi_exit(void) { scsi_remove_host(host); - - if (shpnt->irq != IRQ_NONE) - free_irq(shpnt->irq, NULL); NCR5380_exit(host); - if (shpnt->io_port) - release_region(shpnt->io_port, shpnt->n_io_port); - scsi_host_put(host); + release_mem_region(0x33a0000, 4096); return 0; } diff --git a/drivers/scsi/arm/oak.c b/drivers/scsi/arm/oak.c index c21b8392c92..849cdf89f7b 100644 --- a/drivers/scsi/arm/oak.c +++ b/drivers/scsi/arm/oak.c @@ -23,15 +23,18 @@ #define OAKSCSI_PUBLIC_RELEASE 1 -#define NCR5380_read(reg) oakscsi_read(_instance, reg) -#define NCR5380_write(reg, value) oakscsi_write(_instance, reg, value) +#define priv(host) ((struct NCR5380_hostdata *)(host)->hostdata) +#define NCR5380_local_declare() void __iomem *_base +#define NCR5380_setup(host) _base = priv(host)->base + +#define NCR5380_read(reg) readb(_base + ((reg) << 2)) +#define NCR5380_write(reg, value) writeb(value, _base + ((reg) << 2)) #define NCR5380_intr oakscsi_intr #define NCR5380_queue_command oakscsi_queue_command #define NCR5380_proc_info oakscsi_proc_info -#define NCR5380_implementation_fields int port, ctrl -#define NCR5380_local_declare() struct Scsi_Host *_instance -#define NCR5380_setup(instance) _instance = instance +#define NCR5380_implementation_fields \ + void __iomem *base #define BOARD_NORMAL 0 #define BOARD_NCR53C400 1 @@ -39,60 +42,62 @@ #include "../NCR5380.h" #undef START_DMA_INITIATOR_RECEIVE_REG -#define START_DMA_INITIATOR_RECEIVE_REG (7 + 128) +#define START_DMA_INITIATOR_RECEIVE_REG (128 + 7) const char * oakscsi_info (struct Scsi_Host *spnt) { return ""; } -#define STAT(p) inw(p + 144) -extern void inswb(int from, void *to, int len); +#define STAT ((128 + 16) << 2) +#define DATA ((128 + 8) << 2) static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *addr, int len) { - int iobase = instance->io_port; + void __iomem *base = priv(instance)->base; + printk("writing %p len %d\n",addr, len); if(!len) return -1; while(1) { int status; - while(((status = STAT(iobase)) & 0x100)==0); + while (((status = readw(base + STAT)) & 0x100)==0); } } static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *addr, int len) { - int iobase = instance->io_port; + void __iomem *base = priv(instance)->base; printk("reading %p len %d\n", addr, len); while(len > 0) { - int status, timeout; + unsigned int status, timeout; unsigned long b; timeout = 0x01FFFFFF; - while(((status = STAT(iobase)) & 0x100)==0) + while (((status = readw(base + STAT)) & 0x100)==0) { timeout--; if(status & 0x200 || !timeout) { - printk("status = %08X\n",status); + printk("status = %08X\n", status); return 1; } } + if(len >= 128) { - inswb(iobase + 136, addr, 128); + readsw(base + DATA, addr, 128); addr += 128; len -= 128; } else { - b = (unsigned long) inw(iobase + 136); + b = (unsigned long) readw(base + DATA); *addr ++ = b; len -= 1; if(len) @@ -103,10 +108,8 @@ printk("reading %p len %d\n", addr, len); return 0; } -#define oakscsi_read(instance,reg) (inb((instance)->io_port + (reg))) -#define oakscsi_write(instance,reg,val) (outb((val), (instance)->io_port + (reg))) - #undef STAT +#undef DATA #include "../NCR5380.c" @@ -132,18 +135,26 @@ oakscsi_probe(struct expansion_card *ec, const struct ecard_id *id) struct Scsi_Host *host; int ret = -ENOMEM; - host = scsi_host_alloc(&oakscsi_template, sizeof(struct NCR5380_hostdata)); - if (!host) + ret = ecard_request_resources(ec); + if (ret) goto out; - host->io_port = ecard_address(ec, ECARD_MEMC, 0); + host = scsi_host_alloc(&oakscsi_template, sizeof(struct NCR5380_hostdata)); + if (!host) { + ret = -ENOMEM; + goto release; + } + + priv(host)->base = ioremap(ecard_resource_start(ec, ECARD_RES_MEMC), + ecard_resource_len(ec, ECARD_RES_MEMC)); + if (!priv(host)->base) { + ret = -ENOMEM; + goto unreg; + } + host->irq = IRQ_NONE; host->n_io_port = 255; - ret = -EBUSY; - if (!request_region (host->io_port, host->n_io_port, "Oak SCSI")) - goto unreg; - NCR5380_init(host, 0); printk("scsi%d: at port 0x%08lx irqs disabled", @@ -156,15 +167,17 @@ oakscsi_probe(struct expansion_card *ec, const struct ecard_id *id) ret = scsi_add_host(host, &ec->dev); if (ret) - goto out_release; + goto out_unmap; scsi_scan_host(host); goto out; - out_release: - release_region(host->io_port, host->n_io_port); + out_unmap: + iounmap(priv(host)->base); unreg: scsi_host_put(host); + release: + ecard_release_resources(ec); out: return ret; } @@ -177,8 +190,9 @@ static void __devexit oakscsi_remove(struct expansion_card *ec) scsi_remove_host(host); NCR5380_exit(host); - release_region(host->io_port, host->n_io_port); + iounmap(priv(host)->base); scsi_host_put(host); + ecard_release_resources(ec); } static const struct ecard_id oakscsi_cids[] = { -- cgit v1.2.3 From 531b617c71e780b14af5931428e0611f930c2134 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Sun, 22 Jul 2007 16:05:25 +0100 Subject: [ARM] 4508/1: S3C: Move items to include/asm-arm/plat-s3c This patch moves items of the s3c24xx support into a new plat-s3c directory for items that use the s3c24xx support but are not directly s3c24xx compatible, such as the s3c2400 and s3c6400. git mv commands: git mv include/asm-arm/arch-s3c2410/iic.h include/asm-arm/plat-s3c/iic.h git mv include/asm-arm/arch-s3c2410/nand.h include/asm-arm/plat-s3c/nand.h git mv include/asm-arm/arch-s3c2410/regs-iic.h include/asm-arm/plat-s3c/regs-iic.h git mv include/asm-arm/arch-s3c2410/regs-nand.h include/asm-arm/plat-s3c/regs-nand.h git mv include/asm-arm/arch-s3c2410/regs-rtc.h include/asm-arm/plat-s3c/regs-rtc.h git mv include/asm-arm/arch-s3c2410/regs-serial.h include/asm-arm/plat-s3c/regs-serial.h git mv include/asm-arm/arch-s3c2410/regs-timer.h include/asm-arm/plat-s3c/regs-timer.h git mv include/asm-arm/arch-s3c2410/regs-watchdog.h include/asm-arm/plat-s3c/regs-watchdog.h Signed-off-by: Ben Dooks Signed-off-by: Russell King --- drivers/serial/s3c2410.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c index 10bc0209cd6..3f26c4b2f32 100644 --- a/drivers/serial/s3c2410.c +++ b/drivers/serial/s3c2410.c @@ -78,7 +78,7 @@ #include -#include +#include #include /* structures */ -- cgit v1.2.3