diff options
Diffstat (limited to 'include/linux')
-rw-r--r-- | include/linux/device.h | 38 | ||||
-rw-r--r-- | include/linux/dma-mapping.h | 29 | ||||
-rw-r--r-- | include/linux/dmapool.h | 7 | ||||
-rw-r--r-- | include/linux/interrupt.h | 6 | ||||
-rw-r--r-- | include/linux/io.h | 17 | ||||
-rw-r--r-- | include/linux/ioport.h | 20 | ||||
-rw-r--r-- | include/linux/pci.h | 9 |
7 files changed, 125 insertions, 1 deletions
diff --git a/include/linux/device.h b/include/linux/device.h index 5ca1cdba563..26e4692f2d1 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -354,6 +354,41 @@ extern int __must_check device_create_bin_file(struct device *dev, struct bin_attribute *attr); extern void device_remove_bin_file(struct device *dev, struct bin_attribute *attr); + +/* device resource management */ +typedef void (*dr_release_t)(struct device *dev, void *res); +typedef int (*dr_match_t)(struct device *dev, void *res, void *match_data); + +#ifdef CONFIG_DEBUG_DEVRES +extern void * __devres_alloc(dr_release_t release, size_t size, gfp_t gfp, + const char *name); +#define devres_alloc(release, size, gfp) \ + __devres_alloc(release, size, gfp, #release) +#else +extern void * devres_alloc(dr_release_t release, size_t size, gfp_t gfp); +#endif +extern void devres_free(void *res); +extern void devres_add(struct device *dev, void *res); +extern void * devres_find(struct device *dev, dr_release_t release, + dr_match_t match, void *match_data); +extern void * devres_get(struct device *dev, void *new_res, + dr_match_t match, void *match_data); +extern void * devres_remove(struct device *dev, dr_release_t release, + dr_match_t match, void *match_data); +extern int devres_destroy(struct device *dev, dr_release_t release, + dr_match_t match, void *match_data); + +/* devres group */ +extern void * __must_check devres_open_group(struct device *dev, void *id, + gfp_t gfp); +extern void devres_close_group(struct device *dev, void *id); +extern void devres_remove_group(struct device *dev, void *id); +extern int devres_release_group(struct device *dev, void *id); + +/* managed kzalloc/kfree for device drivers, no kmalloc, always use kzalloc */ +extern void *devm_kzalloc(struct device *dev, size_t size, gfp_t gfp); +extern void devm_kfree(struct device *dev, void *p); + struct device { struct klist klist_children; struct klist_node knode_parent; /* node in sibling list */ @@ -397,6 +432,9 @@ struct device { /* arch specific additions */ struct dev_archdata archdata; + spinlock_t devres_lock; + struct list_head devres_head; + /* class_device migration path */ struct list_head node; struct class *class; diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h index ff203c465fe..9a663c6db16 100644 --- a/include/linux/dma-mapping.h +++ b/include/linux/dma-mapping.h @@ -66,6 +66,33 @@ dma_mark_declared_memory_occupied(struct device *dev, } #endif -#endif +/* + * Managed DMA API + */ +extern void *dmam_alloc_coherent(struct device *dev, size_t size, + dma_addr_t *dma_handle, gfp_t gfp); +extern void dmam_free_coherent(struct device *dev, size_t size, void *vaddr, + dma_addr_t dma_handle); +extern void *dmam_alloc_noncoherent(struct device *dev, size_t size, + dma_addr_t *dma_handle, gfp_t gfp); +extern void dmam_free_noncoherent(struct device *dev, size_t size, void *vaddr, + dma_addr_t dma_handle); +#ifdef ARCH_HAS_DMA_DECLARE_COHERENT_MEMORY +extern int dmam_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr, + dma_addr_t device_addr, size_t size, + int flags); +extern void dmam_release_declared_memory(struct device *dev); +#else /* ARCH_HAS_DMA_DECLARE_COHERENT_MEMORY */ +static inline int dmam_declare_coherent_memory(struct device *dev, + dma_addr_t bus_addr, dma_addr_t device_addr, + size_t size, gfp_t gfp) +{ + return 0; +} +static inline void dmam_release_declared_memory(struct device *dev) +{ +} +#endif /* ARCH_HAS_DMA_DECLARE_COHERENT_MEMORY */ +#endif diff --git a/include/linux/dmapool.h b/include/linux/dmapool.h index 76f12f46db7..022e34fcbd1 100644 --- a/include/linux/dmapool.h +++ b/include/linux/dmapool.h @@ -24,5 +24,12 @@ void *dma_pool_alloc(struct dma_pool *pool, gfp_t mem_flags, void dma_pool_free(struct dma_pool *pool, void *vaddr, dma_addr_t addr); +/* + * Managed DMA pool + */ +struct dma_pool *dmam_pool_create(const char *name, struct device *dev, + size_t size, size_t align, size_t allocation); +void dmam_pool_destroy(struct dma_pool *pool); + #endif diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index e36e86c869f..5a8ba0b8ccb 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h @@ -12,6 +12,7 @@ #include <linux/sched.h> #include <linux/irqflags.h> #include <linux/bottom_half.h> +#include <linux/device.h> #include <asm/atomic.h> #include <asm/ptrace.h> #include <asm/system.h> @@ -83,6 +84,11 @@ extern int request_irq(unsigned int, irq_handler_t handler, unsigned long, const char *, void *); extern void free_irq(unsigned int, void *); +extern int devm_request_irq(struct device *dev, unsigned int irq, + irq_handler_t handler, unsigned long irqflags, + const char *devname, void *dev_id); +extern void devm_free_irq(struct device *dev, unsigned int irq, void *dev_id); + /* * On lockdep we dont want to enable hardirqs in hardirq * context. Use local_irq_enable_in_hardirq() to annotate diff --git a/include/linux/io.h b/include/linux/io.h index 81877ea3930..f5edf9c5de0 100644 --- a/include/linux/io.h +++ b/include/linux/io.h @@ -28,6 +28,23 @@ void __iowrite64_copy(void __iomem *to, const void *from, size_t count); int ioremap_page_range(unsigned long addr, unsigned long end, unsigned long phys_addr, pgprot_t prot); +/* + * Managed iomap interface + */ +void __iomem * devm_ioport_map(struct device *dev, unsigned long port, + unsigned int nr); +void devm_ioport_unmap(struct device *dev, void __iomem *addr); + +void __iomem * devm_ioremap(struct device *dev, unsigned long offset, + unsigned long size); +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); + /** * check_signature - find BIOS signatures * @io_addr: mmio address to check diff --git a/include/linux/ioport.h b/include/linux/ioport.h index 15228d79c5b..6859a3b1408 100644 --- a/include/linux/ioport.h +++ b/include/linux/ioport.h @@ -137,4 +137,24 @@ static inline int __deprecated check_region(resource_size_t s, { return __check_region(&ioport_resource, s, n); } + +/* Wrappers for managed devices */ +struct device; +#define devm_request_region(dev,start,n,name) \ + __devm_request_region(dev, &ioport_resource, (start), (n), (name)) +#define devm_request_mem_region(dev,start,n,name) \ + __devm_request_region(dev, &iomem_resource, (start), (n), (name)) + +extern struct resource * __devm_request_region(struct device *dev, + struct resource *parent, resource_size_t start, + resource_size_t n, const char *name); + +#define devm_release_region(start,n) \ + __devm_release_region(dev, &ioport_resource, (start), (n)) +#define devm_release_mem_region(start,n) \ + __devm_release_region(dev, &iomem_resource, (start), (n)) + +extern void __devm_release_region(struct device *dev, struct resource *parent, + resource_size_t start, resource_size_t n); + #endif /* _LINUX_IOPORT_H */ diff --git a/include/linux/pci.h b/include/linux/pci.h index 805412cc687..9e3042e7e1c 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -167,6 +167,7 @@ struct pci_dev { unsigned int broken_parity_status:1; /* Device generates false positive parity */ unsigned int msi_enabled:1; unsigned int msix_enabled:1; + unsigned int is_managed:1; atomic_t enable_cnt; /* pci_enable_device has been called */ u32 saved_config_space[16]; /* config space saved at suspend time */ @@ -528,6 +529,14 @@ static inline int pci_write_config_dword(struct pci_dev *dev, int where, u32 val int __must_check pci_enable_device(struct pci_dev *dev); int __must_check pci_enable_device_bars(struct pci_dev *dev, int mask); +int __must_check pcim_enable_device(struct pci_dev *pdev); +void pcim_pin_device(struct pci_dev *pdev); + +static inline int pci_is_managed(struct pci_dev *pdev) +{ + return pdev->is_managed; +} + void pci_disable_device(struct pci_dev *dev); void pci_set_master(struct pci_dev *dev); #define HAVE_PCI_SET_MWI |