11f32ca31SBjorn Helgaas /* 21f32ca31SBjorn Helgaas * Copyright (C) 2008 Hewlett-Packard Development Company, L.P. 31f32ca31SBjorn Helgaas * Bjorn Helgaas <bjorn.helgaas@hp.com> 41f32ca31SBjorn Helgaas */ 51f32ca31SBjorn Helgaas 61da177e4SLinus Torvalds extern spinlock_t pnp_lock; 71da177e4SLinus Torvalds void *pnp_alloc(long size); 862cfb298SBjorn Helgaas 962cfb298SBjorn Helgaas int pnp_register_protocol(struct pnp_protocol *protocol); 1062cfb298SBjorn Helgaas void pnp_unregister_protocol(struct pnp_protocol *protocol); 1162cfb298SBjorn Helgaas 1225eb8461SBjorn Helgaas #define PNP_EISA_ID_MASK 0x7fffffff 1325eb8461SBjorn Helgaas void pnp_eisa_id_to_string(u32 id, char *str); 14bda1e4e5SBjorn Helgaas struct pnp_dev *pnp_alloc_dev(struct pnp_protocol *, int id, char *pnpid); 156bf2aab2SBjorn Helgaas struct pnp_card *pnp_alloc_card(struct pnp_protocol *, int id, char *pnpid); 1662cfb298SBjorn Helgaas 1762cfb298SBjorn Helgaas int pnp_add_device(struct pnp_dev *dev); 18772defc6SBjorn Helgaas struct pnp_id *pnp_add_id(struct pnp_dev *dev, char *id); 191da177e4SLinus Torvalds int pnp_interface_attach_device(struct pnp_dev *dev); 2062cfb298SBjorn Helgaas 2162cfb298SBjorn Helgaas int pnp_add_card(struct pnp_card *card); 2262cfb298SBjorn Helgaas void pnp_remove_card(struct pnp_card *card); 2362cfb298SBjorn Helgaas int pnp_add_card_device(struct pnp_card *card, struct pnp_dev *dev); 2462cfb298SBjorn Helgaas void pnp_remove_card_device(struct pnp_dev *dev); 2562cfb298SBjorn Helgaas 26a1802c42SBjorn Helgaas struct pnp_port { 27169aaffeSBjorn Helgaas resource_size_t min; /* min base number */ 28169aaffeSBjorn Helgaas resource_size_t max; /* max base number */ 29169aaffeSBjorn Helgaas resource_size_t align; /* align boundary */ 30169aaffeSBjorn Helgaas resource_size_t size; /* size of range */ 31a1802c42SBjorn Helgaas unsigned char flags; /* port flags */ 32a1802c42SBjorn Helgaas }; 33a1802c42SBjorn Helgaas 34a1802c42SBjorn Helgaas #define PNP_IRQ_NR 256 357aefff51SBjorn Helgaas typedef struct { DECLARE_BITMAP(bits, PNP_IRQ_NR); } pnp_irq_mask_t; 367aefff51SBjorn Helgaas 37a1802c42SBjorn Helgaas struct pnp_irq { 387aefff51SBjorn Helgaas pnp_irq_mask_t map; /* bitmap for IRQ lines */ 39a1802c42SBjorn Helgaas unsigned char flags; /* IRQ flags */ 40a1802c42SBjorn Helgaas }; 41a1802c42SBjorn Helgaas 42a1802c42SBjorn Helgaas struct pnp_dma { 43a1802c42SBjorn Helgaas unsigned char map; /* bitmask for DMA channels */ 44a1802c42SBjorn Helgaas unsigned char flags; /* DMA flags */ 45a1802c42SBjorn Helgaas }; 46a1802c42SBjorn Helgaas 47a1802c42SBjorn Helgaas struct pnp_mem { 48169aaffeSBjorn Helgaas resource_size_t min; /* min base number */ 49169aaffeSBjorn Helgaas resource_size_t max; /* max base number */ 50169aaffeSBjorn Helgaas resource_size_t align; /* align boundary */ 51169aaffeSBjorn Helgaas resource_size_t size; /* size of range */ 52a1802c42SBjorn Helgaas unsigned char flags; /* memory flags */ 53a1802c42SBjorn Helgaas }; 54a1802c42SBjorn Helgaas 551f32ca31SBjorn Helgaas #define PNP_OPTION_DEPENDENT 0x80000000 561f32ca31SBjorn Helgaas #define PNP_OPTION_SET_MASK 0xffff 571f32ca31SBjorn Helgaas #define PNP_OPTION_SET_SHIFT 12 581f32ca31SBjorn Helgaas #define PNP_OPTION_PRIORITY_MASK 0xfff 591f32ca31SBjorn Helgaas #define PNP_OPTION_PRIORITY_SHIFT 0 601f32ca31SBjorn Helgaas 61a1802c42SBjorn Helgaas #define PNP_RES_PRIORITY_PREFERRED 0 62a1802c42SBjorn Helgaas #define PNP_RES_PRIORITY_ACCEPTABLE 1 63a1802c42SBjorn Helgaas #define PNP_RES_PRIORITY_FUNCTIONAL 2 641f32ca31SBjorn Helgaas #define PNP_RES_PRIORITY_INVALID PNP_OPTION_PRIORITY_MASK 65a1802c42SBjorn Helgaas 66a1802c42SBjorn Helgaas struct pnp_option { 671f32ca31SBjorn Helgaas struct list_head list; 681f32ca31SBjorn Helgaas unsigned int flags; /* independent/dependent, set, priority */ 691f32ca31SBjorn Helgaas 701f32ca31SBjorn Helgaas unsigned long type; /* IORESOURCE_{IO,MEM,IRQ,DMA} */ 711f32ca31SBjorn Helgaas union { 721f32ca31SBjorn Helgaas struct pnp_port port; 731f32ca31SBjorn Helgaas struct pnp_irq irq; 741f32ca31SBjorn Helgaas struct pnp_dma dma; 751f32ca31SBjorn Helgaas struct pnp_mem mem; 761f32ca31SBjorn Helgaas } u; 77a1802c42SBjorn Helgaas }; 78a1802c42SBjorn Helgaas 791f32ca31SBjorn Helgaas int pnp_register_irq_resource(struct pnp_dev *dev, unsigned int option_flags, 80c227536bSBjorn Helgaas pnp_irq_mask_t *map, unsigned char flags); 811f32ca31SBjorn Helgaas int pnp_register_dma_resource(struct pnp_dev *dev, unsigned int option_flags, 82c227536bSBjorn Helgaas unsigned char map, unsigned char flags); 831f32ca31SBjorn Helgaas int pnp_register_port_resource(struct pnp_dev *dev, unsigned int option_flags, 84c227536bSBjorn Helgaas resource_size_t min, resource_size_t max, 85c227536bSBjorn Helgaas resource_size_t align, resource_size_t size, 86c227536bSBjorn Helgaas unsigned char flags); 871f32ca31SBjorn Helgaas int pnp_register_mem_resource(struct pnp_dev *dev, unsigned int option_flags, 88c227536bSBjorn Helgaas resource_size_t min, resource_size_t max, 89c227536bSBjorn Helgaas resource_size_t align, resource_size_t size, 90c227536bSBjorn Helgaas unsigned char flags); 911f32ca31SBjorn Helgaas 921f32ca31SBjorn Helgaas static inline int pnp_option_is_dependent(struct pnp_option *option) 931f32ca31SBjorn Helgaas { 941f32ca31SBjorn Helgaas return option->flags & PNP_OPTION_DEPENDENT ? 1 : 0; 951f32ca31SBjorn Helgaas } 961f32ca31SBjorn Helgaas 971f32ca31SBjorn Helgaas static inline unsigned int pnp_option_set(struct pnp_option *option) 981f32ca31SBjorn Helgaas { 991f32ca31SBjorn Helgaas return (option->flags >> PNP_OPTION_SET_SHIFT) & PNP_OPTION_SET_MASK; 1001f32ca31SBjorn Helgaas } 1011f32ca31SBjorn Helgaas 1021f32ca31SBjorn Helgaas static inline unsigned int pnp_option_priority(struct pnp_option *option) 1031f32ca31SBjorn Helgaas { 1041f32ca31SBjorn Helgaas return (option->flags >> PNP_OPTION_PRIORITY_SHIFT) & 1051f32ca31SBjorn Helgaas PNP_OPTION_PRIORITY_MASK; 1061f32ca31SBjorn Helgaas } 1071f32ca31SBjorn Helgaas 1081f32ca31SBjorn Helgaas static inline unsigned int pnp_new_dependent_set(struct pnp_dev *dev, 1091f32ca31SBjorn Helgaas int priority) 1101f32ca31SBjorn Helgaas { 1111f32ca31SBjorn Helgaas unsigned int flags; 1121f32ca31SBjorn Helgaas 1131f32ca31SBjorn Helgaas if (priority > PNP_RES_PRIORITY_FUNCTIONAL) { 1141f32ca31SBjorn Helgaas dev_warn(&dev->dev, "invalid dependent option priority %d " 1151f32ca31SBjorn Helgaas "clipped to %d", priority, 1161f32ca31SBjorn Helgaas PNP_RES_PRIORITY_INVALID); 1171f32ca31SBjorn Helgaas priority = PNP_RES_PRIORITY_INVALID; 1181f32ca31SBjorn Helgaas } 1191f32ca31SBjorn Helgaas 1201f32ca31SBjorn Helgaas flags = PNP_OPTION_DEPENDENT | 1211f32ca31SBjorn Helgaas ((dev->num_dependent_sets & PNP_OPTION_SET_MASK) << 1221f32ca31SBjorn Helgaas PNP_OPTION_SET_SHIFT) | 1231f32ca31SBjorn Helgaas ((priority & PNP_OPTION_PRIORITY_MASK) << 1241f32ca31SBjorn Helgaas PNP_OPTION_PRIORITY_SHIFT); 1251f32ca31SBjorn Helgaas 1261f32ca31SBjorn Helgaas dev->num_dependent_sets++; 1271f32ca31SBjorn Helgaas 1281f32ca31SBjorn Helgaas return flags; 1291f32ca31SBjorn Helgaas } 1301f32ca31SBjorn Helgaas 1311f32ca31SBjorn Helgaas char *pnp_option_priority_name(struct pnp_option *option); 1321f32ca31SBjorn Helgaas void dbg_pnp_show_option(struct pnp_dev *dev, struct pnp_option *option); 1331f32ca31SBjorn Helgaas 13462cfb298SBjorn Helgaas void pnp_init_resources(struct pnp_dev *dev); 13562cfb298SBjorn Helgaas 1361da177e4SLinus Torvalds void pnp_fixup_device(struct pnp_dev *dev); 1371f32ca31SBjorn Helgaas void pnp_free_options(struct pnp_dev *dev); 1381da177e4SLinus Torvalds int __pnp_add_device(struct pnp_dev *dev); 1391da177e4SLinus Torvalds void __pnp_remove_device(struct pnp_dev *dev); 1401da177e4SLinus Torvalds 141f5d94ff0SBjorn Helgaas int pnp_check_port(struct pnp_dev *dev, struct resource *res); 142f5d94ff0SBjorn Helgaas int pnp_check_mem(struct pnp_dev *dev, struct resource *res); 143f5d94ff0SBjorn Helgaas int pnp_check_irq(struct pnp_dev *dev, struct resource *res); 144f5d94ff0SBjorn Helgaas int pnp_check_dma(struct pnp_dev *dev, struct resource *res); 14581b5c75fSBjorn Helgaas 1469fdee4e0SBjorn Helgaas char *pnp_resource_type_name(struct resource *res); 14781b5c75fSBjorn Helgaas void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc); 148d948a8daSBjorn Helgaas 149aee3ad81SBjorn Helgaas void pnp_free_resources(struct pnp_dev *dev); 150940e98dbSBjorn Helgaas int pnp_resource_type(struct resource *res); 15102d83b5dSBjorn Helgaas 152784f01d5SBjorn Helgaas struct pnp_resource { 153aee3ad81SBjorn Helgaas struct list_head list; 154784f01d5SBjorn Helgaas struct resource res; 155784f01d5SBjorn Helgaas }; 156784f01d5SBjorn Helgaas 157aee3ad81SBjorn Helgaas void pnp_free_resource(struct pnp_resource *pnp_res); 158dbddd038SBjorn Helgaas 159dbddd038SBjorn Helgaas struct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq, 160dbddd038SBjorn Helgaas int flags); 161dc16f5f2SBjorn Helgaas struct pnp_resource *pnp_add_dma_resource(struct pnp_dev *dev, int dma, 162dc16f5f2SBjorn Helgaas int flags); 163cc8c2e30SBjorn Helgaas struct pnp_resource *pnp_add_io_resource(struct pnp_dev *dev, 164cc8c2e30SBjorn Helgaas resource_size_t start, 165cc8c2e30SBjorn Helgaas resource_size_t end, int flags); 166d6180f36SBjorn Helgaas struct pnp_resource *pnp_add_mem_resource(struct pnp_dev *dev, 167d6180f36SBjorn Helgaas resource_size_t start, 168d6180f36SBjorn Helgaas resource_size_t end, int flags); 16997ef062bSBjorn Helgaas 17097ef062bSBjorn Helgaas extern int pnp_debug; 17197ef062bSBjorn Helgaas 17297ef062bSBjorn Helgaas #if defined(CONFIG_PNP_DEBUG_MESSAGES) 17397ef062bSBjorn Helgaas #define pnp_dbg(dev, format, arg...) \ 17497ef062bSBjorn Helgaas ({ if (pnp_debug) dev_printk(KERN_DEBUG, dev, format, ## arg); 0; }) 17597ef062bSBjorn Helgaas #else 17697ef062bSBjorn Helgaas #define pnp_dbg(dev, format, arg...) \ 17797ef062bSBjorn Helgaas ({ if (0) dev_printk(KERN_DEBUG, dev, format, ## arg); 0; }) 17897ef062bSBjorn Helgaas #endif 179