Skip to content

Commit

Permalink
[PATCH] sort the devres mess out
Browse files Browse the repository at this point in the history
* Split the implementation-agnostic stuff in separate files.
* Make sure that targets using non-default request_irq() pull
  kernel/irq/devres.o
* Introduce new symbols (HAS_IOPORT and HAS_IOMEM) defaulting to positive;
  allow architectures to turn them off (we needed these symbols anyway for
  dependencies of quite a few drivers).
* protect the ioport-related parts of lib/devres.o with CONFIG_HAS_IOPORT.

Signed-off-by: Al Viro <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
Al Viro authored and Linus Torvalds committed Feb 11, 2007
1 parent 2835fdf commit 5ea8176
Show file tree
Hide file tree
Showing 21 changed files with 442 additions and 397 deletions.
5 changes: 5 additions & 0 deletions arch/arm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ config MMU
bool
default y

config NO_IOPORT
bool
default n

config EISA
bool
---help---
Expand Down Expand Up @@ -298,6 +302,7 @@ config ARCH_RPC
select TIMER_ACORN
select ARCH_MAY_HAVE_PC_FDC
select ISA_DMA_API
select NO_IOPORT
help
On the Acorn Risc-PC, Linux can support the internal IDE disk and
CD-ROM interface, serial and parallel port, and the floppy drive.
Expand Down
3 changes: 3 additions & 0 deletions arch/cris/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ config IRQ_PER_CPU
bool
default y

config NO_IOPORT
def_bool y

config CRIS
bool
default y
Expand Down
3 changes: 3 additions & 0 deletions arch/h8300/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ config TIME_LOW_RES
bool
default y

config NO_IOPORT
def_bool y

config ISA
bool
default y
Expand Down
4 changes: 3 additions & 1 deletion arch/h8300/kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ extra-y := vmlinux.lds

obj-y := process.o traps.o ptrace.o ints.o \
sys_h8300.o time.o semaphore.o signal.o \
setup.o gpio.o init_task.o syscalls.o
setup.o gpio.o init_task.o syscalls.o devres.o

devres-y = ../../../kernel/irq/devres.o

obj-$(CONFIG_MODULES) += module.o h8300_ksyms.o
3 changes: 3 additions & 0 deletions arch/m32r/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ config GENERIC_IRQ_PROBE
bool
default y

config NO_IOPORT
def_bool y

source "init/Kconfig"


Expand Down
3 changes: 3 additions & 0 deletions arch/m68k/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ config ARCH_MAY_HAVE_PC_FDC
depends on Q40 || (BROKEN && SUN3X)
default y

config NO_IOPORT
def_bool y

mainmenu "Linux/68k Kernel Configuration"

source "init/Kconfig"
Expand Down
4 changes: 3 additions & 1 deletion arch/m68k/kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ endif
extra-y += vmlinux.lds

obj-y := entry.o process.o traps.o ints.o signal.o ptrace.o \
sys_m68k.o time.o semaphore.o setup.o m68k_ksyms.o
sys_m68k.o time.o semaphore.o setup.o m68k_ksyms.o devres.o

devres-y = ../../../kernel/irq/devres.o

obj-$(CONFIG_PCI) += bios32.o
obj-$(CONFIG_MODULES) += module.o
Expand Down
3 changes: 3 additions & 0 deletions arch/m68knommu/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ config TIME_LOW_RES
bool
default y

config NO_IOPORT
def_bool y

source "init/Kconfig"

menu "Processor type and features"
Expand Down
3 changes: 3 additions & 0 deletions arch/s390/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ config GENERIC_HWEIGHT
config GENERIC_TIME
def_bool y

config NO_IOPORT
def_bool y

mainmenu "Linux Kernel Configuration"

config S390
Expand Down
4 changes: 3 additions & 1 deletion arch/sparc/kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ obj-y := entry.o wof.o wuf.o etrap.o rtrap.o traps.o $(IRQ_OBJS) \
sys_sparc.o sunos_asm.o systbls.o \
time.o windows.o cpu.o devices.o sclow.o \
tadpole.o tick14.o ptrace.o sys_solaris.o \
unaligned.o muldiv.o semaphore.o prom.o of_device.o
unaligned.o muldiv.o semaphore.o prom.o of_device.o devres.o

devres-y = ../../../kernel/irq/devres.o

obj-$(CONFIG_PCI) += pcic.o
obj-$(CONFIG_SUN4) += sun4setup.o
Expand Down
3 changes: 3 additions & 0 deletions arch/um/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ config MMU
bool
default y

config NO_IOMEM
def_bool y

mainmenu "Linux/Usermode Kernel Configuration"

config ISA
Expand Down
3 changes: 3 additions & 0 deletions arch/xtensa/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ config ARCH_HAS_ILOG2_U64
bool
default n

config NO_IOPORT
def_bool y

source "init/Kconfig"

menu "Processor type and features"
Expand Down
6 changes: 0 additions & 6 deletions include/linux/io.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,6 @@ void __iomem * devm_ioremap_nocache(struct device *dev, unsigned long offset,
unsigned long size);
void devm_iounmap(struct device *dev, void __iomem *addr);

void __iomem * pcim_iomap(struct pci_dev *pdev, int bar, unsigned long maxlen);
void pcim_iounmap(struct pci_dev *pdev, void __iomem *addr);
void __iomem * const * pcim_iomap_table(struct pci_dev *pdev);

int pcim_iomap_regions(struct pci_dev *pdev, u16 mask, const char *name);

/**
* check_signature - find BIOS signatures
* @io_addr: mmio address to check
Expand Down
5 changes: 5 additions & 0 deletions include/linux/pci.h
Original file line number Diff line number Diff line change
Expand Up @@ -840,6 +840,11 @@ enum pci_fixup_pass {

void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev);

void __iomem * pcim_iomap(struct pci_dev *pdev, int bar, unsigned long maxlen);
void pcim_iounmap(struct pci_dev *pdev, void __iomem *addr);
void __iomem * const * pcim_iomap_table(struct pci_dev *pdev);
int pcim_iomap_regions(struct pci_dev *pdev, u16 mask, const char *name);

extern int pci_pci_problems;
#define PCIPCI_FAIL 1 /* No PCI PCI DMA */
#define PCIPCI_TRITON 2
Expand Down
2 changes: 1 addition & 1 deletion kernel/irq/Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

obj-y := handle.o manage.o spurious.o resend.o chip.o
obj-y := handle.o manage.o spurious.o resend.o chip.o devres.o
obj-$(CONFIG_GENERIC_IRQ_PROBE) += autoprobe.o
obj-$(CONFIG_PROC_FS) += proc.o
obj-$(CONFIG_GENERIC_PENDING_IRQ) += migration.o
88 changes: 88 additions & 0 deletions kernel/irq/devres.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#include <linux/module.h>
#include <linux/interrupt.h>

/*
* Device resource management aware IRQ request/free implementation.
*/
struct irq_devres {
unsigned int irq;
void *dev_id;
};

static void devm_irq_release(struct device *dev, void *res)
{
struct irq_devres *this = res;

free_irq(this->irq, this->dev_id);
}

static int devm_irq_match(struct device *dev, void *res, void *data)
{
struct irq_devres *this = res, *match = data;

return this->irq == match->irq && this->dev_id == match->dev_id;
}

/**
* devm_request_irq - allocate an interrupt line for a managed device
* @dev: device to request interrupt for
* @irq: Interrupt line to allocate
* @handler: Function to be called when the IRQ occurs
* @irqflags: Interrupt type flags
* @devname: An ascii name for the claiming device
* @dev_id: A cookie passed back to the handler function
*
* Except for the extra @dev argument, this function takes the
* same arguments and performs the same function as
* request_irq(). IRQs requested with this function will be
* automatically freed on driver detach.
*
* If an IRQ allocated with this function needs to be freed
* separately, dev_free_irq() must be used.
*/
int devm_request_irq(struct device *dev, unsigned int irq,
irq_handler_t handler, unsigned long irqflags,
const char *devname, void *dev_id)
{
struct irq_devres *dr;
int rc;

dr = devres_alloc(devm_irq_release, sizeof(struct irq_devres),
GFP_KERNEL);
if (!dr)
return -ENOMEM;

rc = request_irq(irq, handler, irqflags, devname, dev_id);
if (rc) {
kfree(dr);
return rc;
}

dr->irq = irq;
dr->dev_id = dev_id;
devres_add(dev, dr);

return 0;
}
EXPORT_SYMBOL(devm_request_irq);

/**
* devm_free_irq - free an interrupt
* @dev: device to free interrupt for
* @irq: Interrupt line to free
* @dev_id: Device identity to free
*
* Except for the extra @dev argument, this function takes the
* same arguments and performs the same function as free_irq().
* This function instead of free_irq() should be used to manually
* free IRQs allocated with dev_request_irq().
*/
void devm_free_irq(struct device *dev, unsigned int irq, void *dev_id)
{
struct irq_devres match_data = { irq, dev_id };

free_irq(irq, dev_id);
WARN_ON(devres_destroy(dev, devm_irq_release, devm_irq_match,
&match_data));
}
EXPORT_SYMBOL(devm_free_irq);
86 changes: 0 additions & 86 deletions kernel/irq/manage.c
Original file line number Diff line number Diff line change
Expand Up @@ -482,89 +482,3 @@ int request_irq(unsigned int irq, irq_handler_t handler,
return retval;
}
EXPORT_SYMBOL(request_irq);

/*
* Device resource management aware IRQ request/free implementation.
*/
struct irq_devres {
unsigned int irq;
void *dev_id;
};

static void devm_irq_release(struct device *dev, void *res)
{
struct irq_devres *this = res;

free_irq(this->irq, this->dev_id);
}

static int devm_irq_match(struct device *dev, void *res, void *data)
{
struct irq_devres *this = res, *match = data;

return this->irq == match->irq && this->dev_id == match->dev_id;
}

/**
* devm_request_irq - allocate an interrupt line for a managed device
* @dev: device to request interrupt for
* @irq: Interrupt line to allocate
* @handler: Function to be called when the IRQ occurs
* @irqflags: Interrupt type flags
* @devname: An ascii name for the claiming device
* @dev_id: A cookie passed back to the handler function
*
* Except for the extra @dev argument, this function takes the
* same arguments and performs the same function as
* request_irq(). IRQs requested with this function will be
* automatically freed on driver detach.
*
* If an IRQ allocated with this function needs to be freed
* separately, dev_free_irq() must be used.
*/
int devm_request_irq(struct device *dev, unsigned int irq,
irq_handler_t handler, unsigned long irqflags,
const char *devname, void *dev_id)
{
struct irq_devres *dr;
int rc;

dr = devres_alloc(devm_irq_release, sizeof(struct irq_devres),
GFP_KERNEL);
if (!dr)
return -ENOMEM;

rc = request_irq(irq, handler, irqflags, devname, dev_id);
if (rc) {
kfree(dr);
return rc;
}

dr->irq = irq;
dr->dev_id = dev_id;
devres_add(dev, dr);

return 0;
}
EXPORT_SYMBOL(devm_request_irq);

/**
* devm_free_irq - free an interrupt
* @dev: device to free interrupt for
* @irq: Interrupt line to free
* @dev_id: Device identity to free
*
* Except for the extra @dev argument, this function takes the
* same arguments and performs the same function as free_irq().
* This function instead of free_irq() should be used to manually
* free IRQs allocated with dev_request_irq().
*/
void devm_free_irq(struct device *dev, unsigned int irq, void *dev_id)
{
struct irq_devres match_data = { irq, dev_id };

free_irq(irq, dev_id);
WARN_ON(devres_destroy(dev, devm_irq_release, devm_irq_match,
&match_data));
}
EXPORT_SYMBOL(devm_free_irq);
9 changes: 7 additions & 2 deletions lib/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,14 @@ config TEXTSEARCH_FSM
config PLIST
boolean

config IOMAP_COPY
config HAS_IOMEM
boolean
depends on !UML
depends on !NO_IOMEM
default y

config HAS_IOPORT
boolean
depends on HAS_IOMEM && !NO_IOPORT
default y

endmenu
6 changes: 3 additions & 3 deletions lib/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@ lib-$(CONFIG_SMP) += cpumask.o

lib-y += kobject.o kref.o kobject_uevent.o klist.o

obj-y += sort.o parser.o halfmd4.o debug_locks.o random32.o iomap.o \
bust_spinlocks.o
obj-y += sort.o parser.o halfmd4.o debug_locks.o random32.o bust_spinlocks.o

ifeq ($(CONFIG_DEBUG_KOBJECT),y)
CFLAGS_kobject.o += -DDEBUG
CFLAGS_kobject_uevent.o += -DDEBUG
endif

obj-$(CONFIG_IOMAP_COPY) += iomap_copy.o
obj-$(CONFIG_GENERIC_IOMAP) += iomap.o
obj-$(CONFIG_HAS_IOMEM) += iomap_copy.o devres.o
obj-$(CONFIG_DEBUG_LOCKING_API_SELFTESTS) += locking-selftest.o
obj-$(CONFIG_DEBUG_SPINLOCK) += spinlock_debug.o
lib-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o
Expand Down
Loading

0 comments on commit 5ea8176

Please sign in to comment.