Commit 808235d0 authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://bk.arm.linux.org.uk/linux-2.6-rmk

into ppc970.osdl.org:/home/torvalds/v2.6/linux
parents 95cadf99 353c291b
......@@ -503,27 +503,33 @@ void ecard_disablefiq(unsigned int fiqnr)
}
}
static void
ecard_dump_irq_state(ecard_t *ec)
static void ecard_dump_irq_state(void)
{
printk(" %d: %sclaimed, ",
ec->slot_no,
ec->claimed ? "" : "not ");
if (ec->ops && ec->ops->irqpending &&
ec->ops != &ecard_default_ops)
printk("irq %spending\n",
ec->ops->irqpending(ec) ? "" : "not ");
else
printk("irqaddr %p, mask = %02X, status = %02X\n",
ec->irqaddr, ec->irqmask, *ec->irqaddr);
ecard_t *ec;
printk("Expansion card IRQ state:\n");
for (ec = cards; ec; ec = ec->next) {
if (ec->slot_no == 8)
continue;
printk(" %d: %sclaimed, ",
ec->slot_no, ec->claimed ? "" : "not ");
if (ec->ops && ec->ops->irqpending &&
ec->ops != &ecard_default_ops)
printk("irq %spending\n",
ec->ops->irqpending(ec) ? "" : "not ");
else
printk("irqaddr %p, mask = %02X, status = %02X\n",
ec->irqaddr, ec->irqmask, *ec->irqaddr);
}
}
static void ecard_check_lockup(struct irqdesc *desc)
{
static unsigned long last;
static int lockup;
ecard_t *ec;
/*
* If the timer interrupt has not run since the last million
......@@ -541,11 +547,7 @@ static void ecard_check_lockup(struct irqdesc *desc)
"disabling all expansion card interrupts\n");
desc->chip->mask(IRQ_EXPANSIONCARD);
printk("Expansion card IRQ state:\n");
for (ec = cards; ec; ec = ec->next)
ecard_dump_irq_state(ec);
ecard_dump_irq_state();
}
} else
lockup = 0;
......@@ -557,6 +559,7 @@ static void ecard_check_lockup(struct irqdesc *desc)
if (!last || time_after(jiffies, last + 5*HZ)) {
last = jiffies;
printk(KERN_WARNING "Unrecognised interrupt from backplane\n");
ecard_dump_irq_state();
}
}
......
......@@ -32,6 +32,7 @@
#include <linux/list.h>
#include <linux/errno.h>
#include <linux/err.h>
#include <linux/device.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
......@@ -99,17 +100,35 @@ struct clk *clk_get(struct device *dev, const char *id)
{
struct clk *p;
struct clk *clk = ERR_PTR(-ENOENT);
int idno;
idno = (dev == NULL) ? -1 : to_platform_device(dev)->id;
down(&clocks_sem);
list_for_each_entry(p, &clocks, list) {
if (strcmp(id, p->name) == 0 &&
if (p->id == idno &&
strcmp(id, p->name) == 0 &&
try_module_get(p->owner)) {
clk = p;
break;
}
}
up(&clocks_sem);
/* check for the case where a device was supplied, but the
* clock that was being searched for is not device specific */
if (IS_ERR(clk)) {
list_for_each_entry(p, &clocks, list) {
if (p->id == -1 && strcmp(id, p->name) == 0 &&
try_module_get(p->owner)) {
clk = p;
break;
}
}
}
up(&clocks_sem);
return clk;
}
......@@ -147,6 +166,9 @@ void clk_unuse(struct clk *clk)
unsigned long clk_get_rate(struct clk *clk)
{
if (IS_ERR(clk))
return 0;
if (clk->rate != 0)
return clk->rate;
......@@ -185,46 +207,54 @@ EXPORT_SYMBOL(clk_get_parent);
/* base clocks */
static struct clk clk_f = {
.name = "fclk",
.rate = 0,
.parent = NULL,
.ctrlbit = 0
.name = "fclk",
.id = -1,
.rate = 0,
.parent = NULL,
.ctrlbit = 0,
};
static struct clk clk_h = {
.name = "hclk",
.rate = 0,
.parent = NULL,
.ctrlbit = 0
.name = "hclk",
.id = -1,
.rate = 0,
.parent = NULL,
.ctrlbit = 0,
};
static struct clk clk_p = {
.name = "pclk",
.rate = 0,
.parent = NULL,
.ctrlbit = 0
.name = "pclk",
.id = -1,
.rate = 0,
.parent = NULL,
.ctrlbit = 0,
};
/* clocks that could be registered by external code */
struct clk s3c24xx_dclk0 = {
.name = "dclk0",
.id = -1,
};
struct clk s3c24xx_dclk1 = {
.name = "dclk1",
.id = -1,
};
struct clk s3c24xx_clkout0 = {
.name = "clkout1",
.id = -1,
};
struct clk s3c24xx_clkout1 = {
.name = "clkout1",
.id = -1,
};
struct clk s3c24xx_uclk = {
.name = "uclk",
.id = -1,
};
......@@ -232,21 +262,25 @@ struct clk s3c24xx_uclk = {
static struct clk init_clocks[] = {
{ .name = "nand",
.id = -1,
.parent = &clk_h,
.enable = s3c2410_clkcon_enable,
.ctrlbit = S3C2410_CLKCON_NAND
},
{ .name = "lcd",
.id = -1,
.parent = &clk_h,
.enable = s3c2410_clkcon_enable,
.ctrlbit = S3C2410_CLKCON_LCDC
},
{ .name = "usb-host",
.id = -1,
.parent = &clk_h,
.enable = s3c2410_clkcon_enable,
.ctrlbit = S3C2410_CLKCON_USBH
.ctrlbit = S3C2410_CLKCON_USBH
},
{ .name = "usb-device",
.id = -1,
.parent = &clk_h,
.enable = s3c2410_clkcon_enable,
.ctrlbit = S3C2410_CLKCON_USBD
......@@ -257,56 +291,67 @@ static struct clk init_clocks[] = {
.ctrlbit = S3C2410_CLKCON_PWMT
},
{ .name = "sdi",
.id = -1,
.parent = &clk_p,
.enable = s3c2410_clkcon_enable,
.ctrlbit = S3C2410_CLKCON_SDI
},
{ .name = "uart0",
{ .name = "uart",
.id = 0,
.parent = &clk_p,
.enable = s3c2410_clkcon_enable,
.ctrlbit = S3C2410_CLKCON_UART0
},
{ .name = "uart1",
{ .name = "uart",
.id = 1,
.parent = &clk_p,
.enable = s3c2410_clkcon_enable,
.ctrlbit = S3C2410_CLKCON_UART1
},
{ .name = "uart2",
{ .name = "uart",
.id = 2,
.parent = &clk_p,
.enable = s3c2410_clkcon_enable,
.ctrlbit = S3C2410_CLKCON_UART2
},
{ .name = "gpio",
.id = -1,
.parent = &clk_p,
.enable = s3c2410_clkcon_enable,
.ctrlbit = S3C2410_CLKCON_GPIO
},
{ .name = "rtc",
.id = -1,
.parent = &clk_p,
.enable = s3c2410_clkcon_enable,
.ctrlbit = S3C2410_CLKCON_RTC
},
{ .name = "adc",
.id = -1,
.parent = &clk_p,
.enable = s3c2410_clkcon_enable,
.ctrlbit = S3C2410_CLKCON_ADC
},
{ .name = "i2c",
.id = -1,
.parent = &clk_p,
.enable = s3c2410_clkcon_enable,
.ctrlbit = S3C2410_CLKCON_IIC
},
{ .name = "iis",
.id = -1,
.parent = &clk_p,
.enable = s3c2410_clkcon_enable,
.ctrlbit = S3C2410_CLKCON_IIS
},
{ .name = "spi",
.id = -1,
.parent = &clk_p,
.enable = s3c2410_clkcon_enable,
.ctrlbit = S3C2410_CLKCON_SPI
},
{ .name = "watchdog",
.id = -1,
.parent = &clk_p,
.ctrlbit = 0
}
......
......@@ -14,6 +14,7 @@ struct clk {
struct module *owner;
struct clk *parent;
const char *name;
int id;
atomic_t used;
unsigned long rate;
unsigned long ctrlbit;
......
......@@ -32,8 +32,14 @@
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/arch/regs-serial.h>
#include "devs.h"
/* Serial port registrations */
struct platform_device *s3c24xx_uart_devs[3];
/* USB Host Controller */
static struct resource s3c_usb_resource[] = {
......
......@@ -19,6 +19,7 @@
* 06-Jan-2003 BJD Updates for <arch/map.h>
* 18-Jan-2003 BJD Added serial port configuration
* 05-Oct-2004 BJD Power management code
* 04-Nov-2004 BJD Updated serial port clocks
*/
#include <linux/kernel.h>
......@@ -47,6 +48,7 @@
#include <asm/arch/regs-mem.h>
#include "s3c2410.h"
#include "clock.h"
#include "devs.h"
#include "cpu.h"
#include "usb-simtec.h"
......@@ -153,35 +155,50 @@ static struct map_desc bast_iodesc[] __initdata = {
#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
/* base baud rate for all our UARTs */
static unsigned long bast_serial_clock = 24*1000*1000;
static struct s3c24xx_uart_clksrc bast_serial_clocks[] = {
[0] = {
.name = "uclk",
.divisor = 1,
.min_baud = 0,
.max_baud = 0,
},
[1] = {
.name = "pclk",
.divisor = 1,
.min_baud = 0,
.max_baud = 0.
}
};
static struct s3c2410_uartcfg bast_uartcfgs[] = {
[0] = {
.hwport = 0,
.flags = 0,
.clock = &bast_serial_clock,
.ucon = UCON,
.ulcon = ULCON,
.ufcon = UFCON,
.clocks = bast_serial_clocks,
.clocks_size = ARRAY_SIZE(bast_serial_clocks)
},
[1] = {
.hwport = 1,
.flags = 0,
.clock = &bast_serial_clock,
.ucon = UCON,
.ulcon = ULCON,
.ufcon = UFCON,
.clocks = bast_serial_clocks,
.clocks_size = ARRAY_SIZE(bast_serial_clocks)
},
/* port 2 is not actually used */
[2] = {
.hwport = 2,
.flags = 0,
.clock = &bast_serial_clock,
.ucon = UCON,
.ulcon = ULCON,
.ufcon = UFCON,
.clocks = bast_serial_clocks,
.clocks_size = ARRAY_SIZE(bast_serial_clocks)
}
};
......@@ -214,13 +231,36 @@ static struct platform_device *bast_devices[] __initdata = {
&bast_device_nor
};
static struct clk *bast_clocks[] = {
&s3c24xx_dclk0,
&s3c24xx_dclk1,
&s3c24xx_clkout0,
&s3c24xx_clkout1,
&s3c24xx_uclk,
};
static struct s3c24xx_board bast_board __initdata = {
.devices = bast_devices,
.devices_count = ARRAY_SIZE(bast_devices)
.devices_count = ARRAY_SIZE(bast_devices),
.clocks = bast_clocks,
.clocks_count = ARRAY_SIZE(bast_clocks)
};
void __init bast_map_io(void)
{
/* initialise the clocks */
s3c24xx_dclk0.parent = NULL;
s3c24xx_dclk0.rate = 12*1000*1000;
s3c24xx_dclk1.parent = NULL;
s3c24xx_dclk1.rate = 24*1000*1000;
s3c24xx_clkout0.parent = &s3c24xx_dclk0;
s3c24xx_clkout1.parent = &s3c24xx_dclk1;
s3c24xx_uclk.parent = &s3c24xx_clkout1;
s3c24xx_init_io(bast_iodesc, ARRAY_SIZE(bast_iodesc));
s3c2410_init_uarts(bast_uartcfgs, ARRAY_SIZE(bast_uartcfgs));
s3c24xx_set_board(&bast_board);
......
......@@ -19,6 +19,7 @@
* 21-Aug-2004 BJD Added struct s3c2410_board
* 04-Sep-2004 BJD Changed uart init, renamed ipaq_ -> h1940_
* 18-Oct-2004 BJD Updated new board structure name
* 04-Nov-2004 BJD Change for new serial clock
*/
#include <linux/kernel.h>
......@@ -41,6 +42,8 @@
//#include <asm/debug-ll.h>
#include <asm/arch/regs-serial.h>
#include <linux/serial_core.h>
#include "s3c2410.h"
#include "clock.h"
#include "devs.h"
......@@ -58,7 +61,6 @@ static struct s3c2410_uartcfg h1940_uartcfgs[] = {
[0] = {
.hwport = 0,
.flags = 0,
.clock = &s3c24xx_pclk,
.ucon = 0x3c5,
.ulcon = 0x03,
.ufcon = 0x51,
......@@ -66,7 +68,6 @@ static struct s3c2410_uartcfg h1940_uartcfgs[] = {
[1] = {
.hwport = 1,
.flags = 0,
.clock = &s3c24xx_pclk,
.ucon = 0x245,
.ulcon = 0x03,
.ufcon = 0x00,
......@@ -75,7 +76,7 @@ static struct s3c2410_uartcfg h1940_uartcfgs[] = {
[2] = {
.hwport = 2,
.flags = 0,
.clock = &s3c24xx_pclk,
.uart_flags = UPF_CONS_FLOW,
.ucon = 0x3c5,
.ulcon = 0x43,
.ufcon = 0x51,
......
......@@ -58,14 +58,10 @@ static struct map_desc smdk2410_iodesc[] __initdata = {
#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
/* base baud rate for all our UARTs */
static unsigned long smdk2410_serial_clock = 24*1000*1000;
static struct s3c2410_uartcfg smdk2410_uartcfgs[] = {
[0] = {
.hwport = 0,
.flags = 0,
.clock = &smdk2410_serial_clock,
.ucon = UCON,
.ulcon = ULCON,
.ufcon = UFCON,
......@@ -73,7 +69,6 @@ static struct s3c2410_uartcfg smdk2410_uartcfgs[] = {
[1] = {
.hwport = 1,
.flags = 0,
.clock = &smdk2410_serial_clock,
.ucon = UCON,
.ulcon = ULCON,
.ufcon = UFCON,
......@@ -81,7 +76,6 @@ static struct s3c2410_uartcfg smdk2410_uartcfgs[] = {
[2] = {
.hwport = 2,
.flags = 0,
.clock = &smdk2410_serial_clock,
.ucon = UCON,
.ulcon = ULCON,
.ufcon = UFCON,
......
......@@ -17,6 +17,7 @@
* 06-Aug-2004 BJD Fixed call to time initialisation
* 05-Apr-2004 BJD Copied to make mach-vr1000.c
* 18-Oct-2004 BJD Updated board struct
* 04-Nov-2004 BJD Clock and serial configuration update
*/
#include <linux/kernel.h>
......@@ -42,6 +43,7 @@
#include <asm/arch/regs-serial.h>
#include "s3c2410.h"
#include "clock.h"
#include "devs.h"
#include "cpu.h"
#include "usb-simtec.h"
......@@ -113,34 +115,52 @@ static struct map_desc vr1000_iodesc[] __initdata = {
#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
/* base baud rate for all our UARTs */
static unsigned long vr1000_serial_clock = 3692307;
/* uart clock source(s) */
static struct s3c24xx_uart_clksrc vr1000_serial_clocks[] = {
[0] = {
.name = "uclk",
.divisor = 1,
.min_baud = 0,
.max_baud = 0,
},
[1] = {
.name = "pclk",
.divisor = 1,
.min_baud = 0,
.max_baud = 0.
}
};
static struct s3c2410_uartcfg vr1000_uartcfgs[] = {
[0] = {
.hwport = 0,
.flags = 0,
.clock = &vr1000_serial_clock,
.ucon = UCON,
.ulcon = ULCON,
.ufcon = UFCON,
.clocks = vr1000_serial_clocks,
.clocks_size = ARRAY_SIZE(vr1000_serial_clocks),
},
[1] = {
.hwport = 1,
.flags = 0,
.clock = &vr1000_serial_clock,
.ucon = UCON,
.ulcon = ULCON,
.ufcon = UFCON,
.clocks = vr1000_serial_clocks,
.clocks_size = ARRAY_SIZE(vr1000_serial_clocks),
},
/* port 2 is not actually used */
[2] = {
.hwport = 2,
.flags = 0,
.clock = &vr1000_serial_clock,
.ucon = UCON,
.ulcon = ULCON,
.ufcon = UFCON,
.clocks = vr1000_serial_clocks,
.clocks_size = ARRAY_SIZE(vr1000_serial_clocks),
}
};
......@@ -152,14 +172,37 @@ static struct platform_device *vr1000_devices[] __initdata = {
&s3c_device_iis,
};
static struct clk *vr1000_clocks[] = {
&s3c24xx_dclk0,
&s3c24xx_dclk1,
&s3c24xx_clkout0,
&s3c24xx_clkout1,
&s3c24xx_uclk,
};
static struct s3c24xx_board vr1000_board __initdata = {
.devices = vr1000_devices,
.devices_count = ARRAY_SIZE(vr1000_devices)
.devices_count = ARRAY_SIZE(vr1000_devices),
.clocks = vr1000_clocks,
.clocks_count = ARRAY_SIZE(vr1000_clocks),
};
void __init vr1000_map_io(void)
{
/* initialise clock sources */
s3c24xx_dclk0.parent = NULL;
s3c24xx_dclk0.rate = 12*1000*1000;
s3c24xx_dclk1.parent = NULL;
s3c24xx_dclk1.rate = 3692307;
s3c24xx_clkout0.parent = &s3c24xx_dclk0;
s3c24xx_clkout1.parent = &s3c24xx_dclk1;
s3c24xx_uclk.parent = &s3c24xx_clkout1;
s3c24xx_init_io(vr1000_iodesc, ARRAY_SIZE(vr1000_iodesc));
s3c2410_init_uarts(vr1000_uartcfgs, ARRAY_SIZE(vr1000_uartcfgs));
s3c24xx_set_board(&vr1000_board);
......
/* linux/arch/arm/mach-s3c2410/s3c2410.c
*
* Copyright (c) 2003,2004 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* Ben Dooks <ben@simtec.co.uk>
*
* http://www.simtec.co.uk/products/EB2410ITX/
*
......@@ -16,6 +16,7 @@
* 18-Jan-2004 BJD Added serial port configuration
* 21-Aug-2004 BJD Added new struct s3c2410_board handler
* 28-Sep-2004 BJD Updates for new serial port bits
* 04-Nov-2004 BJD Updated UART configuration process
*/
#include <linux/kernel.h>
......@@ -43,10 +44,6 @@
int s3c2410_clock_tick_rate = 12*1000*1000; /* current timers at 12MHz */
/* serial port setup */
struct s3c2410_uartcfg *s3c2410_uartcfgs;
/* Initial IO mappings */
static struct map_desc s3c2410_iodesc[] __initdata = {
......@@ -141,12 +138,10 @@ void __init s3c2410_init_uarts(struct s3c2410_uartcfg *cfg, int no)
struct platform_device *platdev;
int uart;
s3c2410_uartcfgs = cfg; /* compatibility */
for (uart = 0; uart < no; uart++, cfg++) {
platdev = uart_devices[cfg->hwport];
s3c2410_uart_devices[uart] = platdev;
s3c24xx_uart_devs[uart] = platdev;
platdev->dev.platform_data = cfg;
}
......@@ -199,10 +194,7 @@ void __init s3c2410_map_io(struct map_desc *mach_desc, int mach_size)
int __init s3c2410_init(void)
{
int ret;
printk("S3C2410: Initialising architecture\n");
ret = platform_add_devices(uart_devices, ARRAY_SIZE(uart_devices));
return ret;
return platform_add_devices(s3c24xx_uart_devs, s3c2410_uart_count);
}
......@@ -14,6 +14,7 @@
* 12-Oct-2004 BJD Moved clock info out to clock.c
* 01-Nov-2004 BJD Fixed clock build code
* 09-Nov-2004 BJD Added sysdev for power management
* 04-Nov-2004 BJD New serial registration
*/
#include <linux/kernel.h>
......@@ -129,6 +130,25 @@ static struct platform_device *uart_devices[] __initdata = {
&s3c_uart2
};
/* uart initialisation */
static int __initdata s3c2440_uart_count;
void __init s3c2440_init_uarts(struct s3c2410_uartcfg *cfg, int no)
{
struct platform_device *platdev;
int uart;
for (uart = 0; uart < no; uart++, cfg++) {
platdev = uart_devices[cfg->hwport];
s3c24xx_uart_devs[uart] = platdev;
platdev->dev.platform_data = cfg;
}
s3c2440_uart_count = uart;
}
/* s3c2440 specific clock sources */
static struct clk s3c2440_clk_cam = {
......@@ -259,9 +279,8 @@ int __init s3c2440_init(void)
if (ret != 0)
printk(KERN_ERR "failed to register sysdev for s3c2440\n");
if (ret != 0)
ret = platform_add_devices(uart_devices,
ARRAY_SIZE(uart_devices));
if (ret == 0)
ret = platform_add_devices(s3c24xx_uart_devs, s3c2440_uart_count);
return ret;
}
......@@ -10,9 +10,14 @@
* published by the Free Software Foundation.
*
* Modifications:
* 24-Aug-2004 BJD Start of S3C2440 CPU support
* 24-Aug-2004 BJD Start of S3C2440 CPU support
* 04-Nov-2004 BJD Added s3c2440_init_uarts()
*/
struct s3c2410_uartcfg;
extern void s3c2440_init_irq(void);
extern void s3c2440_init_time(void);
extern void s3c2440_init_uarts(struct s3c2410_uartcfg *cfg, int no);
/*
* linux/drivers/ide/arm/icside.c
*
* Copyright (c) 1996-2003 Russell King.
* Copyright (c) 1996-2004 Russell King.
*
* Please note that this platform does not support 32-bit IDE IO.
*/
#include <linux/config.h>
......@@ -24,21 +26,21 @@
#define ICS_IDENT_OFFSET 0x2280
#define ICS_ARCIN_V5_INTRSTAT 0x000
#define ICS_ARCIN_V5_INTROFFSET 0x001
#define ICS_ARCIN_V5_IDEOFFSET 0xa00
#define ICS_ARCIN_V5_IDEALTOFFSET 0xae0
#define ICS_ARCIN_V5_IDESTEPPING 4
#define ICS_ARCIN_V6_IDEOFFSET_1 0x800
#define ICS_ARCIN_V6_INTROFFSET_1 0x880
#define ICS_ARCIN_V6_INTRSTAT_1 0x8a4
#define ICS_ARCIN_V6_IDEALTOFFSET_1 0x8e0
#define ICS_ARCIN_V6_IDEOFFSET_2 0xc00
#define ICS_ARCIN_V6_INTROFFSET_2 0xc80
#define ICS_ARCIN_V6_INTRSTAT_2 0xca4
#define ICS_ARCIN_V6_IDEALTOFFSET_2 0xce0
#define ICS_ARCIN_V6_IDESTEPPING 4
#define ICS_ARCIN_V5_INTRSTAT 0x0000
#define ICS_ARCIN_V5_INTROFFSET 0x0004
#define ICS_ARCIN_V5_IDEOFFSET 0x2800
#define ICS_ARCIN_V5_IDEALTOFFSET 0x2b80
#define ICS_ARCIN_V5_IDESTEPPING 6
#define ICS_ARCIN_V6_IDEOFFSET_1 0x2000
#define ICS_ARCIN_V6_INTROFFSET_1 0x2200
#define ICS_ARCIN_V6_INTRSTAT_1 0x2290
#define ICS_ARCIN_V6_IDEALTOFFSET_1 0x2380
#define ICS_ARCIN_V6_IDEOFFSET_2 0x3000
#define ICS_ARCIN_V6_INTROFFSET_2 0x3200
#define ICS_ARCIN_V6_INTRSTAT_2 0x3290
#define ICS_ARCIN_V6_IDEALTOFFSET_2 0x3380
#define ICS_ARCIN_V6_IDESTEPPING 6
struct cardinfo {
unsigned int dataoffset;
......@@ -47,28 +49,28 @@ struct cardinfo {
};
static struct cardinfo icside_cardinfo_v5 = {
ICS_ARCIN_V5_IDEOFFSET,
ICS_ARCIN_V5_IDEALTOFFSET,
ICS_ARCIN_V5_IDESTEPPING
.dataoffset = ICS_ARCIN_V5_IDEOFFSET,
.ctrloffset = ICS_ARCIN_V5_IDEALTOFFSET,
.stepping = ICS_ARCIN_V5_IDESTEPPING,
};
static struct cardinfo icside_cardinfo_v6_1 = {
ICS_ARCIN_V6_IDEOFFSET_1,
ICS_ARCIN_V6_IDEALTOFFSET_1,
ICS_ARCIN_V6_IDESTEPPING
.dataoffset = ICS_ARCIN_V6_IDEOFFSET_1,
.ctrloffset = ICS_ARCIN_V6_IDEALTOFFSET_1,
.stepping = ICS_ARCIN_V6_IDESTEPPING,
};
static struct cardinfo icside_cardinfo_v6_2 = {
ICS_ARCIN_V6_IDEOFFSET_2,
ICS_ARCIN_V6_IDEALTOFFSET_2,
ICS_ARCIN_V6_IDESTEPPING
.dataoffset = ICS_ARCIN_V6_IDEOFFSET_2,
.ctrloffset = ICS_ARCIN_V6_IDEALTOFFSET_2,
.stepping = ICS_ARCIN_V6_IDESTEPPING,
};
struct icside_state {
unsigned int channel;
unsigned int enabled;
unsigned long irq_port;
unsigned long slot_port;
void __iomem *irq_port;
void __iomem *ioc_base;
unsigned int type;
/* parent device... until the IDE core gets one of its own */
struct device *dev;
......@@ -88,9 +90,8 @@ struct icside_state {
static void icside_irqenable_arcin_v5 (struct expansion_card *ec, int irqnr)
{
struct icside_state *state = ec->irq_data;
unsigned int base = state->irq_port;
outb(0, base + ICS_ARCIN_V5_INTROFFSET);
writeb(0, state->irq_port + ICS_ARCIN_V5_INTROFFSET);
}
/* Prototype: icside_irqdisable_arcin_v5 (struct expansion_card *ec, int irqnr)
......@@ -99,9 +100,8 @@ static void icside_irqenable_arcin_v5 (struct expansion_card *ec, int irqnr)
static void icside_irqdisable_arcin_v5 (struct expansion_card *ec, int irqnr)
{
struct icside_state *state = ec->irq_data;
unsigned int base = state->irq_port;
inb(base + ICS_ARCIN_V5_INTROFFSET);
readb(state->irq_port + ICS_ARCIN_V5_INTROFFSET);
}
static const expansioncard_ops_t icside_ops_arcin_v5 = {
......@@ -117,18 +117,18 @@ static const expansioncard_ops_t icside_ops_arcin_v5 = {
static void icside_irqenable_arcin_v6 (struct expansion_card *ec, int irqnr)
{
struct icside_state *state = ec->irq_data;
unsigned int base = state->irq_port;
void __iomem *base = state->irq_port;
state->enabled = 1;
switch (state->channel) {
case 0:
outb(0, base + ICS_ARCIN_V6_INTROFFSET_1);
inb(base + ICS_ARCIN_V6_INTROFFSET_2);
writeb(0, base + ICS_ARCIN_V6_INTROFFSET_1);
readb(base + ICS_ARCIN_V6_INTROFFSET_2);
break;
case 1:
outb(0, base + ICS_ARCIN_V6_INTROFFSET_2);
inb(base + ICS_ARCIN_V6_INTROFFSET_1);
writeb(0, base + ICS_ARCIN_V6_INTROFFSET_2);
readb(base + ICS_ARCIN_V6_INTROFFSET_1);
break;
}
}
......@@ -142,8 +142,8 @@ static void icside_irqdisable_arcin_v6 (struct expansion_card *ec, int irqnr)
state->enabled = 0;
inb (state->irq_port + ICS_ARCIN_V6_INTROFFSET_1);
inb (state->irq_port + ICS_ARCIN_V6_INTROFFSET_2);
readb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_1);
readb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_2);
}
/* Prototype: icside_irqprobe(struct expansion_card *ec)
......@@ -153,8 +153,8 @@ static int icside_irqpending_arcin_v6(struct expansion_card *ec)
{
struct icside_state *state = ec->irq_data;
return inb(state->irq_port + ICS_ARCIN_V6_INTRSTAT_1) & 1 ||
inb(state->irq_port + ICS_ARCIN_V6_INTRSTAT_2) & 1;
return readb(state->irq_port + ICS_ARCIN_V6_INTRSTAT_1) & 1 ||
readb(state->irq_port + ICS_ARCIN_V6_INTRSTAT_2) & 1;
}
static const expansioncard_ops_t icside_ops_arcin_v6 = {
......@@ -180,17 +180,17 @@ static void icside_maskproc(ide_drive_t *drive, int mask)
if (state->enabled && !mask) {
switch (hwif->channel) {
case 0:
outb(0, state->irq_port + ICS_ARCIN_V6_INTROFFSET_1);
inb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_2);
writeb(0, state->irq_port + ICS_ARCIN_V6_INTROFFSET_1);
readb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_2);
break;
case 1:
outb(0, state->irq_port + ICS_ARCIN_V6_INTROFFSET_2);
inb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_1);
writeb(0, state->irq_port + ICS_ARCIN_V6_INTROFFSET_2);
readb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_1);
break;
}
} else {
inb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_2);
inb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_1);
readb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_2);
readb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_1);
}
local_irq_restore(flags);
......@@ -452,7 +452,7 @@ static int icside_dma_setup(ide_drive_t *drive)
/*
* Route the DMA signals to the correct interface.
*/
outb(hwif->select_data, hwif->config_data);
writeb(hwif->select_data, hwif->config_data);
/*
* Select the correct timing for this drive.
......@@ -482,8 +482,8 @@ static int icside_dma_test_irq(ide_drive_t *drive)
ide_hwif_t *hwif = HWIF(drive);
struct icside_state *state = hwif->hwif_data;
return inb(state->irq_port +
(hwif->channel ?
return readb(state->irq_port +
(hwif->channel ?
ICS_ARCIN_V6_INTRSTAT_2 :
ICS_ARCIN_V6_INTRSTAT_1)) & 1;
}
......@@ -571,24 +571,30 @@ static ide_hwif_t *icside_find_hwif(unsigned long dataport)
}
static ide_hwif_t *
icside_setup(unsigned long base, struct cardinfo *info, struct expansion_card *ec)
icside_setup(void __iomem *base, struct cardinfo *info, struct expansion_card *ec)
{
unsigned long port = base + info->dataoffset;
unsigned long port = (unsigned long)base + info->dataoffset;
ide_hwif_t *hwif;
hwif = icside_find_hwif(base);
hwif = icside_find_hwif(port);
if (hwif) {
int i;
memset(&hwif->hw, 0, sizeof(hw_regs_t));
/*
* Ensure we're using MMIO
*/
default_hwif_mmiops(hwif);
hwif->mmio = 2;
for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
hwif->hw.io_ports[i] = port;
hwif->io_ports[i] = port;
port += 1 << info->stepping;
}
hwif->hw.io_ports[IDE_CONTROL_OFFSET] = base + info->ctrloffset;
hwif->io_ports[IDE_CONTROL_OFFSET] = base + info->ctrloffset;
hwif->hw.io_ports[IDE_CONTROL_OFFSET] = (unsigned long)base + info->ctrloffset;
hwif->io_ports[IDE_CONTROL_OFFSET] = (unsigned long)base + info->ctrloffset;
hwif->hw.irq = ec->irq;
hwif->irq = ec->irq;
hwif->noprobe = 0;
......@@ -602,14 +608,17 @@ icside_setup(unsigned long base, struct cardinfo *info, struct expansion_card *e
static int __init
icside_register_v5(struct icside_state *state, struct expansion_card *ec)
{
unsigned long slot_port;
ide_hwif_t *hwif;
void __iomem *base;
slot_port = ecard_address(ec, ECARD_MEMC, 0);
base = ioremap(ecard_resource_start(ec, ECARD_RES_MEMC),
ecard_resource_len(ec, ECARD_RES_MEMC));
if (!base)
return -ENOMEM;
state->irq_port = slot_port;
state->irq_port = base;
ec->irqaddr = (unsigned char *)ioaddr(slot_port + ICS_ARCIN_V5_INTRSTAT);
ec->irqaddr = base + ICS_ARCIN_V5_INTRSTAT;
ec->irqmask = 1;
ec->irq_data = state;
ec->ops = &icside_ops_arcin_v5;
......@@ -617,61 +626,83 @@ icside_register_v5(struct icside_state *state, struct expansion_card *ec)
/*
* Be on the safe side - disable interrupts
*/
inb(slot_port + ICS_ARCIN_V5_INTROFFSET);
icside_irqdisable_arcin_v5(ec, 0);
hwif = icside_setup(slot_port, &icside_cardinfo_v5, ec);
hwif = icside_setup(base, &icside_cardinfo_v5, ec);
if (!hwif) {
iounmap(base);
return -ENODEV;
}
state->hwif[0] = hwif;
return hwif ? 0 : -ENODEV;
return 0;
}
static int __init
icside_register_v6(struct icside_state *state, struct expansion_card *ec)
{
unsigned long slot_port, port;
ide_hwif_t *hwif, *mate;
void __iomem *ioc_base, *easi_base;
unsigned int sel = 0;
int ret;
ioc_base = ioremap(ecard_resource_start(ec, ECARD_RES_IOCFAST),
ecard_resource_len(ec, ECARD_RES_IOCFAST));
if (!ioc_base) {
ret = -ENOMEM;
goto out;
}
slot_port = ecard_address(ec, ECARD_IOC, ECARD_FAST);
port = ecard_address(ec, ECARD_EASI, ECARD_FAST);
easi_base = ioc_base;
if (port == 0)
port = slot_port;
else
if (ecard_resource_flags(ec, ECARD_RES_EASI)) {
easi_base = ioremap(ecard_resource_start(ec, ECARD_RES_EASI),
ecard_resource_len(ec, ECARD_RES_EASI));
if (!easi_base) {
ret = -ENOMEM;
goto unmap_slot;
}
/*
* Enable access to the EASI region.
*/
sel = 1 << 5;
}
outb(sel, slot_port);
writeb(sel, ioc_base);
ec->irq_data = state;
ec->ops = &icside_ops_arcin_v6;
state->irq_port = easi_base;
state->ioc_base = ioc_base;
/*
* Be on the safe side - disable interrupts
*/
inb(port + ICS_ARCIN_V6_INTROFFSET_1);
inb(port + ICS_ARCIN_V6_INTROFFSET_2);
icside_irqdisable_arcin_v6(ec, 0);
/*
* Find and register the interfaces.
*/
hwif = icside_setup(port, &icside_cardinfo_v6_1, ec);
mate = icside_setup(port, &icside_cardinfo_v6_2, ec);
hwif = icside_setup(easi_base, &icside_cardinfo_v6_1, ec);
mate = icside_setup(easi_base, &icside_cardinfo_v6_2, ec);
if (!hwif || !mate)
return -ENODEV;
if (!hwif || !mate) {
ret = -ENODEV;
goto unmap_port;
}
state->irq_port = port;
state->slot_port = slot_port;
state->hwif[0] = hwif;
state->hwif[1] = mate;
ec->irq_data = state;
ec->ops = &icside_ops_arcin_v6;
hwif->maskproc = icside_maskproc;
hwif->channel = 0;
hwif->hwif_data = state;
hwif->mate = mate;
hwif->serialized = 1;
hwif->config_data = slot_port;
hwif->config_data = (unsigned long)ioc_base;
hwif->select_data = sel;
hwif->hw.dma = ec->dma;
......@@ -680,7 +711,7 @@ icside_register_v6(struct icside_state *state, struct expansion_card *ec)
mate->hwif_data = state;
mate->mate = hwif;
mate->serialized = 1;
mate->config_data = slot_port;
mate->config_data = (unsigned long)ioc_base;
mate->select_data = sel | 1;
mate->hw.dma = ec->dma;
......@@ -690,6 +721,14 @@ icside_register_v6(struct icside_state *state, struct expansion_card *ec)
}
return 0;
unmap_port:
if (easi_base != ioc_base)
iounmap(easi_base);
unmap_slot:
iounmap(ioc_base);
out:
return ret;
}
static int __devinit
......@@ -699,10 +738,14 @@ icside_probe(struct expansion_card *ec, const struct ecard_id *id)
void *idmem;
int ret;
ret = ecard_request_resources(ec);
if (ret)
goto out;
state = kmalloc(sizeof(struct icside_state), GFP_KERNEL);
if (!state) {
ret = -ENOMEM;
goto out;
goto release;
}
memset(state, 0, sizeof(state));
......@@ -725,12 +768,12 @@ icside_probe(struct expansion_card *ec, const struct ecard_id *id)
switch (state->type) {
case ICS_TYPE_A3IN:
printk(KERN_WARNING "icside: A3IN unsupported\n");
dev_warn(&ec->dev, "A3IN unsupported\n");
ret = -ENODEV;
break;
case ICS_TYPE_A3USER:
printk(KERN_WARNING "icside: A3USER unsupported\n");
dev_warn(&ec->dev, "A3USER unsupported\n");
ret = -ENODEV;
break;
......@@ -743,15 +786,19 @@ icside_probe(struct expansion_card *ec, const struct ecard_id *id)
break;
default:
printk(KERN_WARNING "icside: unknown interface type\n");
dev_warn(&ec->dev, "unknown interface type\n");
ret = -ENODEV;
break;
}
if (ret == 0)
if (ret == 0) {
ecard_set_drvdata(ec, state);
else
kfree(state);
goto out;
}
kfree(state);
release:
ecard_release_resources(ec);
out:
return ret;
}
......@@ -765,7 +812,7 @@ static void __devexit icside_remove(struct expansion_card *ec)
/* FIXME: tell IDE to stop using the interface */
/* Disable interrupts */
inb(state->slot_port + ICS_ARCIN_V5_INTROFFSET);
icside_irqdisable_arcin_v5(ec, 0);
break;
case ICS_TYPE_V6:
......@@ -774,11 +821,10 @@ static void __devexit icside_remove(struct expansion_card *ec)
free_dma(ec->dma);
/* Disable interrupts */
inb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_1);
inb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_2);
icside_irqdisable_arcin_v6(ec, 0);
/* Reset the ROM pointer/EASI selection */
outb(0, state->slot_port);
writeb(0, state->ioc_base);
break;
}
......@@ -786,28 +832,36 @@ static void __devexit icside_remove(struct expansion_card *ec)
ec->ops = NULL;
ec->irq_data = NULL;
if (state->ioc_base)
iounmap(state->ioc_base);
if (state->ioc_base != state->irq_port)
iounmap(state->irq_port);
kfree(state);
ecard_release_resources(ec);
}
static void icside_shutdown(struct expansion_card *ec)
{
struct icside_state *state = ecard_get_drvdata(ec);
unsigned long flags;
switch (state->type) {
case ICS_TYPE_V5:
/* Disable interrupts */
inb(state->slot_port + ICS_ARCIN_V5_INTROFFSET);
break;
case ICS_TYPE_V6:
/* Disable interrupts */
inb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_1);
inb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_2);
/*
* Disable interrupts from this card. We need to do
* this before disabling EASI since we may be accessing
* this register via that region.
*/
local_irq_save(flags);
ec->ops->irqdisable(ec, 0);
local_irq_restore(flags);
/* Reset the ROM pointer/EASI selection */
outb(0, state->slot_port);
break;
}
/*
* Reset the ROM pointer so that we can read the ROM
* after a soft reboot. This also disables access to
* the IDE taskfile via the EASI region.
*/
if (state->ioc_base)
writeb(0, state->ioc_base);
}
static const struct ecard_id icside_ids[] = {
......
......@@ -13,32 +13,91 @@
#include <asm/ecard.h>
static int __devinit
rapide_probe(struct expansion_card *ec, const struct ecard_id *id)
/*
* Something like this really should be in generic code, but isn't.
*/
static ide_hwif_t *
rapide_locate_hwif(void __iomem *base, void *ctrl, unsigned int sz, int irq)
{
unsigned long port = ecard_address (ec, ECARD_MEMC, 0);
hw_regs_t hw;
int i, ret;
unsigned long port = (unsigned long)base;
ide_hwif_t *hwif;
int index, i;
for (index = 0; index < MAX_HWIFS; ++index) {
hwif = ide_hwifs + index;
if (hwif->io_ports[IDE_DATA_OFFSET] == port)
goto found;
}
for (index = 0; index < MAX_HWIFS; ++index) {
hwif = ide_hwifs + index;
if (hwif->io_ports[IDE_DATA_OFFSET] == 0)
goto found;
}
memset(&hw, 0, sizeof(hw));
return NULL;
found:
for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
hw.io_ports[i] = port;
port += 1 << 4;
hwif->hw.io_ports[i] = port;
hwif->io_ports[i] = port;
port += sz;
}
hw.io_ports[IDE_CONTROL_OFFSET] = port + 0x206;
hw.irq = ec->irq;
hwif->hw.io_ports[IDE_CONTROL_OFFSET] = (unsigned long)ctrl;
hwif->io_ports[IDE_CONTROL_OFFSET] = (unsigned long)ctrl;
hwif->hw.irq = hwif->irq = irq;
hwif->mmio = 2;
default_hwif_mmiops(hwif);
return hwif;
}
ret = ide_register_hw(&hw, NULL);
static int __devinit
rapide_probe(struct expansion_card *ec, const struct ecard_id *id)
{
ide_hwif_t *hwif;
void __iomem *base;
int ret;
ret = ecard_request_resources(ec);
if (ret)
ecard_release(ec);
goto out;
base = ioremap(ecard_resource_start(ec, ECARD_RES_MEMC),
ecard_resource_len(ec, ECARD_RES_MEMC));
if (!base) {
ret = -ENOMEM;
goto release;
}
hwif = rapide_locate_hwif(base, base + 0x818, 1 << 6, ec->irq);
if (hwif) {
hwif->hwif_data = base;
hwif->gendev.parent = &ec->dev;
hwif->noprobe = 0;
probe_hwif_init(hwif);
create_proc_ide_interfaces();
ecard_set_drvdata(ec, hwif);
goto out;
}
iounmap(base);
release:
ecard_release_resources(ec);
out:
return ret;
}
static void __devexit rapide_remove(struct expansion_card *ec)
{
/* need to do more */
ide_hwif_t *hwif = ecard_get_drvdata(ec);
ecard_set_drvdata(ec, NULL);
/* there must be a better way */
ide_unregister(hwif - ide_hwifs);
iounmap(hwif->hwif_data);
ecard_release_resources(ec);
}
static struct ecard_id rapide_ids[] = {
......
......@@ -286,14 +286,12 @@ arxescsi_probe(struct expansion_card *ec, const struct ecard_id *id)
unsigned char *base;
int ret;
resbase = ecard_resource_start(ec, ECARD_RES_MEMC);
reslen = ecard_resource_len(ec, ECARD_RES_MEMC);
if (!request_mem_region(resbase, reslen, "arxescsi")) {
ret = -EBUSY;
ret = ecard_request_resources(ec);
if (ret)
goto out;
}
resbase = ecard_resource_start(ec, ECARD_RES_MEMC);
reslen = ecard_resource_len(ec, ECARD_RES_MEMC);
base = ioremap(resbase, reslen);
if (!base) {
ret = -ENOMEM;
......@@ -345,7 +343,7 @@ arxescsi_probe(struct expansion_card *ec, const struct ecard_id *id)
out_unmap:
iounmap(base);
out_region:
release_mem_region(resbase, reslen);
ecard_release_resources(ec);
out:
return ret;
}
......@@ -353,20 +351,15 @@ arxescsi_probe(struct expansion_card *ec, const struct ecard_id *id)
static void __devexit arxescsi_remove(struct expansion_card *ec)
{
struct Scsi_Host *host = ecard_get_drvdata(ec);
unsigned long resbase, reslen;
ecard_set_drvdata(ec, NULL);
fas216_remove(host);
iounmap((void *)host->base);
resbase = ecard_resource_start(ec, ECARD_RES_MEMC);
reslen = ecard_resource_len(ec, ECARD_RES_MEMC);
release_mem_region(resbase, reslen);
fas216_release(host);
scsi_host_put(host);
ecard_release_resources(ec);
}
static const struct ecard_id arxescsi_cids[] = {
......
......@@ -408,14 +408,12 @@ cumanascsi2_probe(struct expansion_card *ec, const struct ecard_id *id)
unsigned char *base;
int ret;
resbase = ecard_resource_start(ec, ECARD_RES_MEMC);
reslen = ecard_resource_len(ec, ECARD_RES_MEMC);
if (!request_mem_region(resbase, reslen, "cumanascsi2")) {
ret = -EBUSY;
ret = ecard_request_resources(ec);
if (ret)
goto out;
}
resbase = ecard_resource_start(ec, ECARD_RES_MEMC);
reslen = ecard_resource_len(ec, ECARD_RES_MEMC);
base = ioremap(resbase, reslen);
if (!base) {
ret = -ENOMEM;
......@@ -504,7 +502,7 @@ cumanascsi2_probe(struct expansion_card *ec, const struct ecard_id *id)
iounmap(base);
out_region:
release_mem_region(resbase, reslen);
ecard_release_resources(ec);
out:
return ret;
......@@ -514,7 +512,6 @@ static void __devexit cumanascsi2_remove(struct expansion_card *ec)
{
struct Scsi_Host *host = ecard_get_drvdata(ec);
struct cumanascsi2_info *info = (struct cumanascsi2_info *)host->hostdata;
unsigned long resbase, reslen;
ecard_set_drvdata(ec, NULL);
fas216_remove(host);
......@@ -525,13 +522,9 @@ static void __devexit cumanascsi2_remove(struct expansion_card *ec)
iounmap((void *)host->base);
resbase = ecard_resource_start(ec, ECARD_RES_MEMC);
reslen = ecard_resource_len(ec, ECARD_RES_MEMC);
release_mem_region(resbase, reslen);
fas216_release(host);
scsi_host_put(host);
ecard_release_resources(ec);
}
static const struct ecard_id cumanascsi2_cids[] = {
......
......@@ -525,14 +525,12 @@ eesoxscsi_probe(struct expansion_card *ec, const struct ecard_id *id)
unsigned char *base;
int ret;
resbase = ecard_resource_start(ec, ECARD_RES_IOCFAST);
reslen = ecard_resource_len(ec, ECARD_RES_IOCFAST);
if (!request_mem_region(resbase, reslen, "eesoxscsi")) {
ret = -EBUSY;
ret = ecard_request_resources(ec);
if (ret)
goto out;
}
resbase = ecard_resource_start(ec, ECARD_RES_IOCFAST);
reslen = ecard_resource_len(ec, ECARD_RES_IOCFAST);
base = ioremap(resbase, reslen);
if (!base) {
ret = -ENOMEM;
......@@ -622,7 +620,7 @@ eesoxscsi_probe(struct expansion_card *ec, const struct ecard_id *id)
iounmap(base);
out_region:
release_mem_region(resbase, reslen);
ecard_release_resources(ec);
out:
return ret;
......@@ -632,7 +630,6 @@ static void __devexit eesoxscsi_remove(struct expansion_card *ec)
{
struct Scsi_Host *host = ecard_get_drvdata(ec);
struct eesoxscsi_info *info = (struct eesoxscsi_info *)host->hostdata;
unsigned long resbase, reslen;
ecard_set_drvdata(ec, NULL);
fas216_remove(host);
......@@ -645,13 +642,9 @@ static void __devexit eesoxscsi_remove(struct expansion_card *ec)
iounmap((void *)host->base);
resbase = ecard_resource_start(ec, ECARD_RES_IOCFAST);
reslen = ecard_resource_len(ec, ECARD_RES_IOCFAST);
release_mem_region(resbase, reslen);
fas216_release(host);
scsi_host_put(host);
ecard_release_resources(ec);
}
static const struct ecard_id eesoxscsi_cids[] = {
......
......@@ -318,14 +318,12 @@ powertecscsi_probe(struct expansion_card *ec, const struct ecard_id *id)
unsigned char *base;
int ret;
resbase = ecard_resource_start(ec, ECARD_RES_IOCFAST);
reslen = ecard_resource_len(ec, ECARD_RES_IOCFAST);
if (!request_mem_region(resbase, reslen, "powertecscsi")) {
ret = -EBUSY;
ret = ecard_request_resources(ec);
if (ret)
goto out;
}
resbase = ecard_resource_start(ec, ECARD_RES_IOCFAST);
reslen = ecard_resource_len(ec, ECARD_RES_IOCFAST);
base = ioremap(resbase, reslen);
if (!base) {
ret = -ENOMEM;
......@@ -413,7 +411,7 @@ powertecscsi_probe(struct expansion_card *ec, const struct ecard_id *id)
iounmap(base);
out_region:
release_mem_region(resbase, reslen);
ecard_release_resources(ec);
out:
return ret;
......@@ -423,7 +421,6 @@ static void __devexit powertecscsi_remove(struct expansion_card *ec)
{
struct Scsi_Host *host = ecard_get_drvdata(ec);
struct powertecscsi_info *info = (struct powertecscsi_info *)host->hostdata;
unsigned long resbase, reslen;
ecard_set_drvdata(ec, NULL);
fas216_remove(host);
......@@ -436,13 +433,9 @@ static void __devexit powertecscsi_remove(struct expansion_card *ec)
iounmap((void *)host->base);
resbase = ecard_resource_start(ec, ECARD_RES_IOCFAST);
reslen = ecard_resource_len(ec, ECARD_RES_IOCFAST);
release_mem_region(resbase, reslen);
fas216_release(host);
scsi_host_put(host);
ecard_release_resources(ec);
}
static const struct ecard_id powertecscsi_cids[] = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment