Skip to content

Commit

Permalink
[SPARC64]: Fix of_iounmap() region release.
Browse files Browse the repository at this point in the history
We need to pass in the resource otherwise we cannot
release the region properly.  We must know whether it is
an I/O or MEM resource.

Spotted by Eric Brower.

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Dec 31, 2006
1 parent 6fc5bae commit e3a411a
Show file tree
Hide file tree
Showing 16 changed files with 155 additions and 112 deletions.
2 changes: 1 addition & 1 deletion arch/sparc/kernel/ioport.c
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ void __iomem *of_ioremap(struct resource *res, unsigned long offset,
}
EXPORT_SYMBOL(of_ioremap);

void of_iounmap(void __iomem *base, unsigned long size)
void of_iounmap(struct resource *res, void __iomem *base, unsigned long size)
{
iounmap(base);
}
Expand Down
7 changes: 5 additions & 2 deletions arch/sparc64/kernel/of_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -144,9 +144,12 @@ void __iomem *of_ioremap(struct resource *res, unsigned long offset, unsigned lo
}
EXPORT_SYMBOL(of_ioremap);

void of_iounmap(void __iomem *base, unsigned long size)
void of_iounmap(struct resource *res, void __iomem *base, unsigned long size)
{
release_region((unsigned long) base, size);
if (res->flags & IORESOURCE_MEM)
release_mem_region((unsigned long) base, size);
else
release_region((unsigned long) base, size);
}
EXPORT_SYMBOL(of_iounmap);

Expand Down
6 changes: 4 additions & 2 deletions drivers/input/serio/i8042-sparcio.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ static int i8042_aux_irq = -1;
#define I8042_MUX_PHYS_DESC "sparcps2/serio%d"

static void __iomem *kbd_iobase;
static struct resource *kbd_res;

#define I8042_COMMAND_REG (kbd_iobase + 0x64UL)
#define I8042_DATA_REG (kbd_iobase + 0x60UL)
Expand Down Expand Up @@ -60,6 +61,7 @@ static int __devinit sparc_i8042_probe(struct of_device *op, const struct of_dev
i8042_kbd_irq = irq;
kbd_iobase = of_ioremap(&kbd->resource[0],
0, 8, "kbd");
kbd_res = &kbd->resource[0];
} else if (!strcmp(dp->name, OBP_PS2MS_NAME1) ||
!strcmp(dp->name, OBP_PS2MS_NAME2)) {
struct of_device *ms = of_find_device_by_node(dp);
Expand All @@ -77,7 +79,7 @@ static int __devinit sparc_i8042_probe(struct of_device *op, const struct of_dev

static int __devexit sparc_i8042_remove(struct of_device *op)
{
of_iounmap(kbd_iobase, 8);
of_iounmap(kbd_res, kbd_iobase, 8);

return 0;
}
Expand Down Expand Up @@ -119,7 +121,7 @@ static int __init i8042_platform_init(void)
if (i8042_kbd_irq == -1 ||
i8042_aux_irq == -1) {
if (kbd_iobase) {
of_iounmap(kbd_iobase, 8);
of_iounmap(kbd_res, kbd_iobase, 8);
kbd_iobase = (void __iomem *) NULL;
}
return -ENODEV;
Expand Down
11 changes: 8 additions & 3 deletions drivers/serial/sunsab.c
Original file line number Diff line number Diff line change
Expand Up @@ -1037,7 +1037,8 @@ static int __devinit sunsab_init_one(struct uart_sunsab_port *up,
err = request_irq(up->port.irq, sunsab_interrupt,
IRQF_SHARED, "sab", up);
if (err) {
of_iounmap(up->port.membase,
of_iounmap(&op->resource[0],
up->port.membase,
sizeof(union sab82532_async_regs));
return err;
}
Expand All @@ -1064,7 +1065,8 @@ static int __devinit sab_probe(struct of_device *op, const struct of_device_id *
sizeof(union sab82532_async_regs),
(inst * 2) + 1);
if (err) {
of_iounmap(up[0].port.membase,
of_iounmap(&op->resource[0],
up[0].port.membase,
sizeof(union sab82532_async_regs));
free_irq(up[0].port.irq, &up[0]);
return err;
Expand All @@ -1082,10 +1084,13 @@ static int __devinit sab_probe(struct of_device *op, const struct of_device_id *

static void __devexit sab_remove_one(struct uart_sunsab_port *up)
{
struct of_device *op = to_of_device(up->port.dev);

uart_remove_one_port(&sunsab_reg, &up->port);
if (!(up->port.line & 1))
free_irq(up->port.irq, up);
of_iounmap(up->port.membase,
of_iounmap(&op->resource[0],
up->port.membase,
sizeof(union sab82532_async_regs));
}

Expand Down
10 changes: 5 additions & 5 deletions drivers/serial/sunsu.c
Original file line number Diff line number Diff line change
Expand Up @@ -1480,13 +1480,13 @@ static int __devinit su_probe(struct of_device *op, const struct of_device_id *m
return 0;

out_unmap:
of_iounmap(up->port.membase, up->reg_size);
of_iounmap(&op->resource[0], up->port.membase, up->reg_size);
return err;
}

static int __devexit su_remove(struct of_device *dev)
static int __devexit su_remove(struct of_device *op)
{
struct uart_sunsu_port *up = dev_get_drvdata(&dev->dev);;
struct uart_sunsu_port *up = dev_get_drvdata(&op->dev);

if (up->su_type == SU_PORT_MS ||
up->su_type == SU_PORT_KBD) {
Expand All @@ -1499,9 +1499,9 @@ static int __devexit su_remove(struct of_device *dev)
}

if (up->port.membase)
of_iounmap(up->port.membase, up->reg_size);
of_iounmap(&op->resource[0], up->port.membase, up->reg_size);

dev_set_drvdata(&dev->dev, NULL);
dev_set_drvdata(&op->dev, NULL);

return 0;
}
Expand Down
14 changes: 8 additions & 6 deletions drivers/serial/sunzilog.c
Original file line number Diff line number Diff line change
Expand Up @@ -1379,13 +1379,15 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m
if (!keyboard_mouse) {
err = uart_add_one_port(&sunzilog_reg, &up[0].port);
if (err) {
of_iounmap(rp, sizeof(struct zilog_layout));
of_iounmap(&op->resource[0],
rp, sizeof(struct zilog_layout));
return err;
}
err = uart_add_one_port(&sunzilog_reg, &up[1].port);
if (err) {
uart_remove_one_port(&sunzilog_reg, &up[0].port);
of_iounmap(rp, sizeof(struct zilog_layout));
of_iounmap(&op->resource[0],
rp, sizeof(struct zilog_layout));
return err;
}
} else {
Expand Down Expand Up @@ -1414,18 +1416,18 @@ static void __devexit zs_remove_one(struct uart_sunzilog_port *up)
uart_remove_one_port(&sunzilog_reg, &up->port);
}

static int __devexit zs_remove(struct of_device *dev)
static int __devexit zs_remove(struct of_device *op)
{
struct uart_sunzilog_port *up = dev_get_drvdata(&dev->dev);
struct uart_sunzilog_port *up = dev_get_drvdata(&op->dev);
struct zilog_layout __iomem *regs;

zs_remove_one(&up[0]);
zs_remove_one(&up[1]);

regs = sunzilog_chip_regs[up[0].port.line / 2];
of_iounmap(regs, sizeof(struct zilog_layout));
of_iounmap(&op->resource[0], regs, sizeof(struct zilog_layout));

dev_set_drvdata(&dev->dev, NULL);
dev_set_drvdata(&op->dev, NULL);

return 0;
}
Expand Down
18 changes: 10 additions & 8 deletions drivers/video/bw2.c
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ static int __devinit bw2_init_one(struct of_device *op)
all->info.fbops = &bw2_ops;

all->info.screen_base =
sbus_ioremap(&op->resource[0], 0, all->par.fbsize, "bw2 ram");
of_ioremap(&op->resource[0], 0, all->par.fbsize, "bw2 ram");
all->info.par = &all->par;

bw2_blank(0, &all->info);
Expand All @@ -329,8 +329,10 @@ static int __devinit bw2_init_one(struct of_device *op)

err= register_framebuffer(&all->info);
if (err < 0) {
of_iounmap(all->par.regs, sizeof(struct bw2_regs));
of_iounmap(all->info.screen_base, all->par.fbsize);
of_iounmap(&op->resource[0],
all->par.regs, sizeof(struct bw2_regs));
of_iounmap(&op->resource[0],
all->info.screen_base, all->par.fbsize);
kfree(all);
return err;
}
Expand All @@ -351,18 +353,18 @@ static int __devinit bw2_probe(struct of_device *dev, const struct of_device_id
return bw2_init_one(op);
}

static int __devexit bw2_remove(struct of_device *dev)
static int __devexit bw2_remove(struct of_device *op)
{
struct all_info *all = dev_get_drvdata(&dev->dev);
struct all_info *all = dev_get_drvdata(&op->dev);

unregister_framebuffer(&all->info);

of_iounmap(all->par.regs, sizeof(struct bw2_regs));
of_iounmap(all->info.screen_base, all->par.fbsize);
of_iounmap(&op->resource[0], all->par.regs, sizeof(struct bw2_regs));
of_iounmap(&op->resource[0], all->info.screen_base, all->par.fbsize);

kfree(all);

dev_set_drvdata(&dev->dev, NULL);
dev_set_drvdata(&op->dev, NULL);

return 0;
}
Expand Down
28 changes: 16 additions & 12 deletions drivers/video/cg14.c
Original file line number Diff line number Diff line change
Expand Up @@ -452,16 +452,20 @@ struct all_info {
struct cg14_par par;
};

static void cg14_unmap_regs(struct all_info *all)
static void cg14_unmap_regs(struct of_device *op, struct all_info *all)
{
if (all->par.regs)
of_iounmap(all->par.regs, sizeof(struct cg14_regs));
of_iounmap(&op->resource[0],
all->par.regs, sizeof(struct cg14_regs));
if (all->par.clut)
of_iounmap(all->par.clut, sizeof(struct cg14_clut));
of_iounmap(&op->resource[0],
all->par.clut, sizeof(struct cg14_clut));
if (all->par.cursor)
of_iounmap(all->par.cursor, sizeof(struct cg14_cursor));
of_iounmap(&op->resource[0],
all->par.cursor, sizeof(struct cg14_cursor));
if (all->info.screen_base)
of_iounmap(all->info.screen_base, all->par.fbsize);
of_iounmap(&op->resource[1],
all->info.screen_base, all->par.fbsize);
}

static int __devinit cg14_init_one(struct of_device *op)
Expand Down Expand Up @@ -506,7 +510,7 @@ static int __devinit cg14_init_one(struct of_device *op)

if (!all->par.regs || !all->par.clut || !all->par.cursor ||
!all->info.screen_base)
cg14_unmap_regs(all);
cg14_unmap_regs(op, all);

is_8mb = (((op->resource[1].end - op->resource[1].start) + 1) ==
(8 * 1024 * 1024));
Expand Down Expand Up @@ -541,7 +545,7 @@ static int __devinit cg14_init_one(struct of_device *op)
__cg14_reset(&all->par);

if (fb_alloc_cmap(&all->info.cmap, 256, 0)) {
cg14_unmap_regs(all);
cg14_unmap_regs(op, all);
kfree(all);
return -ENOMEM;
}
Expand All @@ -552,7 +556,7 @@ static int __devinit cg14_init_one(struct of_device *op)
err = register_framebuffer(&all->info);
if (err < 0) {
fb_dealloc_cmap(&all->info.cmap);
cg14_unmap_regs(all);
cg14_unmap_regs(op, all);
kfree(all);
return err;
}
Expand All @@ -574,18 +578,18 @@ static int __devinit cg14_probe(struct of_device *dev, const struct of_device_id
return cg14_init_one(op);
}

static int __devexit cg14_remove(struct of_device *dev)
static int __devexit cg14_remove(struct of_device *op)
{
struct all_info *all = dev_get_drvdata(&dev->dev);
struct all_info *all = dev_get_drvdata(&op->dev);

unregister_framebuffer(&all->info);
fb_dealloc_cmap(&all->info.cmap);

cg14_unmap_regs(all);
cg14_unmap_regs(op, all);

kfree(all);

dev_set_drvdata(&dev->dev, NULL);
dev_set_drvdata(&op->dev, NULL);

return 0;
}
Expand Down
22 changes: 13 additions & 9 deletions drivers/video/cg3.c
Original file line number Diff line number Diff line change
Expand Up @@ -403,8 +403,10 @@ static int __devinit cg3_init_one(struct of_device *op)
cg3_do_default_mode(&all->par);

if (fb_alloc_cmap(&all->info.cmap, 256, 0)) {
of_iounmap(all->par.regs, sizeof(struct cg3_regs));
of_iounmap(all->info.screen_base, all->par.fbsize);
of_iounmap(&op->resource[0],
all->par.regs, sizeof(struct cg3_regs));
of_iounmap(&op->resource[0],
all->info.screen_base, all->par.fbsize);
kfree(all);
return -ENOMEM;
}
Expand All @@ -415,8 +417,10 @@ static int __devinit cg3_init_one(struct of_device *op)
err = register_framebuffer(&all->info);
if (err < 0) {
fb_dealloc_cmap(&all->info.cmap);
of_iounmap(all->par.regs, sizeof(struct cg3_regs));
of_iounmap(all->info.screen_base, all->par.fbsize);
of_iounmap(&op->resource[0],
all->par.regs, sizeof(struct cg3_regs));
of_iounmap(&op->resource[0],
all->info.screen_base, all->par.fbsize);
kfree(all);
return err;
}
Expand All @@ -436,19 +440,19 @@ static int __devinit cg3_probe(struct of_device *dev, const struct of_device_id
return cg3_init_one(op);
}

static int __devexit cg3_remove(struct of_device *dev)
static int __devexit cg3_remove(struct of_device *op)
{
struct all_info *all = dev_get_drvdata(&dev->dev);
struct all_info *all = dev_get_drvdata(&op->dev);

unregister_framebuffer(&all->info);
fb_dealloc_cmap(&all->info.cmap);

of_iounmap(all->par.regs, sizeof(struct cg3_regs));
of_iounmap(all->info.screen_base, all->par.fbsize);
of_iounmap(&op->resource[0], all->par.regs, sizeof(struct cg3_regs));
of_iounmap(&op->resource[0], all->info.screen_base, all->par.fbsize);

kfree(all);

dev_set_drvdata(&dev->dev, NULL);
dev_set_drvdata(&op->dev, NULL);

return 0;
}
Expand Down
Loading

0 comments on commit e3a411a

Please sign in to comment.