1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */ 21f32ca31SBjorn Helgaas /* 31f32ca31SBjorn Helgaas * Copyright (C) 2008 Hewlett-Packard Development Company, L.P. 41f32ca31SBjorn Helgaas * Bjorn Helgaas <bjorn.helgaas@hp.com> 51f32ca31SBjorn Helgaas */ 61f32ca31SBjorn Helgaas 738f6b38dSRafael J. Wysocki extern struct mutex pnp_lock; 82df43901SGreg Kroah-Hartman extern const struct attribute_group *pnp_dev_groups[]; 91da177e4SLinus Torvalds void *pnp_alloc(long size); 1062cfb298SBjorn Helgaas 1162cfb298SBjorn Helgaas int pnp_register_protocol(struct pnp_protocol *protocol); 1262cfb298SBjorn Helgaas void pnp_unregister_protocol(struct pnp_protocol *protocol); 1362cfb298SBjorn Helgaas 1425eb8461SBjorn Helgaas #define PNP_EISA_ID_MASK 0x7fffffff 1525eb8461SBjorn Helgaas void pnp_eisa_id_to_string(u32 id, char *str); 16620e112cSThomas Renninger struct pnp_dev *pnp_alloc_dev(struct pnp_protocol *, int id, 17620e112cSThomas Renninger const char *pnpid); 186bf2aab2SBjorn Helgaas struct pnp_card *pnp_alloc_card(struct pnp_protocol *, int id, char *pnpid); 1962cfb298SBjorn Helgaas 2062cfb298SBjorn Helgaas int pnp_add_device(struct pnp_dev *dev); 21620e112cSThomas Renninger struct pnp_id *pnp_add_id(struct pnp_dev *dev, const char *id); 2262cfb298SBjorn Helgaas 2362cfb298SBjorn Helgaas int pnp_add_card(struct pnp_card *card); 2462cfb298SBjorn Helgaas void pnp_remove_card(struct pnp_card *card); 2562cfb298SBjorn Helgaas int pnp_add_card_device(struct pnp_card *card, struct pnp_dev *dev); 2662cfb298SBjorn Helgaas void pnp_remove_card_device(struct pnp_dev *dev); 2762cfb298SBjorn Helgaas 28a1802c42SBjorn Helgaas struct pnp_port { 29169aaffeSBjorn Helgaas resource_size_t min; /* min base number */ 30169aaffeSBjorn Helgaas resource_size_t max; /* max base number */ 31169aaffeSBjorn Helgaas resource_size_t align; /* align boundary */ 32169aaffeSBjorn Helgaas resource_size_t size; /* size of range */ 33a1802c42SBjorn Helgaas unsigned char flags; /* port flags */ 34a1802c42SBjorn Helgaas }; 35a1802c42SBjorn Helgaas 36a1802c42SBjorn Helgaas #define PNP_IRQ_NR 256 377aefff51SBjorn Helgaas typedef struct { DECLARE_BITMAP(bits, PNP_IRQ_NR); } pnp_irq_mask_t; 387aefff51SBjorn Helgaas 39a1802c42SBjorn Helgaas struct pnp_irq { 407aefff51SBjorn Helgaas pnp_irq_mask_t map; /* bitmap for IRQ lines */ 41a1802c42SBjorn Helgaas unsigned char flags; /* IRQ flags */ 42a1802c42SBjorn Helgaas }; 43a1802c42SBjorn Helgaas 44a1802c42SBjorn Helgaas struct pnp_dma { 45a1802c42SBjorn Helgaas unsigned char map; /* bitmask for DMA channels */ 46a1802c42SBjorn Helgaas unsigned char flags; /* DMA flags */ 47a1802c42SBjorn Helgaas }; 48a1802c42SBjorn Helgaas 49a1802c42SBjorn Helgaas struct pnp_mem { 50169aaffeSBjorn Helgaas resource_size_t min; /* min base number */ 51169aaffeSBjorn Helgaas resource_size_t max; /* max base number */ 52169aaffeSBjorn Helgaas resource_size_t align; /* align boundary */ 53169aaffeSBjorn Helgaas resource_size_t size; /* size of range */ 54a1802c42SBjorn Helgaas unsigned char flags; /* memory flags */ 55a1802c42SBjorn Helgaas }; 56a1802c42SBjorn Helgaas 571f32ca31SBjorn Helgaas #define PNP_OPTION_DEPENDENT 0x80000000 581f32ca31SBjorn Helgaas #define PNP_OPTION_SET_MASK 0xffff 591f32ca31SBjorn Helgaas #define PNP_OPTION_SET_SHIFT 12 601f32ca31SBjorn Helgaas #define PNP_OPTION_PRIORITY_MASK 0xfff 611f32ca31SBjorn Helgaas #define PNP_OPTION_PRIORITY_SHIFT 0 621f32ca31SBjorn Helgaas 63a1802c42SBjorn Helgaas #define PNP_RES_PRIORITY_PREFERRED 0 64a1802c42SBjorn Helgaas #define PNP_RES_PRIORITY_ACCEPTABLE 1 65a1802c42SBjorn Helgaas #define PNP_RES_PRIORITY_FUNCTIONAL 2 661f32ca31SBjorn Helgaas #define PNP_RES_PRIORITY_INVALID PNP_OPTION_PRIORITY_MASK 67a1802c42SBjorn Helgaas 68a1802c42SBjorn Helgaas struct pnp_option { 691f32ca31SBjorn Helgaas struct list_head list; 701f32ca31SBjorn Helgaas unsigned int flags; /* independent/dependent, set, priority */ 711f32ca31SBjorn Helgaas 721f32ca31SBjorn Helgaas unsigned long type; /* IORESOURCE_{IO,MEM,IRQ,DMA} */ 731f32ca31SBjorn Helgaas union { 741f32ca31SBjorn Helgaas struct pnp_port port; 751f32ca31SBjorn Helgaas struct pnp_irq irq; 761f32ca31SBjorn Helgaas struct pnp_dma dma; 771f32ca31SBjorn Helgaas struct pnp_mem mem; 781f32ca31SBjorn Helgaas } u; 79a1802c42SBjorn Helgaas }; 80a1802c42SBjorn Helgaas 811f32ca31SBjorn Helgaas int pnp_register_irq_resource(struct pnp_dev *dev, unsigned int option_flags, 82c227536bSBjorn Helgaas pnp_irq_mask_t *map, unsigned char flags); 831f32ca31SBjorn Helgaas int pnp_register_dma_resource(struct pnp_dev *dev, unsigned int option_flags, 84c227536bSBjorn Helgaas unsigned char map, unsigned char flags); 851f32ca31SBjorn Helgaas int pnp_register_port_resource(struct pnp_dev *dev, unsigned int option_flags, 86c227536bSBjorn Helgaas resource_size_t min, resource_size_t max, 87c227536bSBjorn Helgaas resource_size_t align, resource_size_t size, 88c227536bSBjorn Helgaas unsigned char flags); 891f32ca31SBjorn Helgaas int pnp_register_mem_resource(struct pnp_dev *dev, unsigned int option_flags, 90c227536bSBjorn Helgaas resource_size_t min, resource_size_t max, 91c227536bSBjorn Helgaas resource_size_t align, resource_size_t size, 92c227536bSBjorn Helgaas unsigned char flags); 931f32ca31SBjorn Helgaas 941f32ca31SBjorn Helgaas static inline int pnp_option_is_dependent(struct pnp_option *option) 951f32ca31SBjorn Helgaas { 961f32ca31SBjorn Helgaas return option->flags & PNP_OPTION_DEPENDENT ? 1 : 0; 971f32ca31SBjorn Helgaas } 981f32ca31SBjorn Helgaas 991f32ca31SBjorn Helgaas static inline unsigned int pnp_option_set(struct pnp_option *option) 1001f32ca31SBjorn Helgaas { 1011f32ca31SBjorn Helgaas return (option->flags >> PNP_OPTION_SET_SHIFT) & PNP_OPTION_SET_MASK; 1021f32ca31SBjorn Helgaas } 1031f32ca31SBjorn Helgaas 1041f32ca31SBjorn Helgaas static inline unsigned int pnp_option_priority(struct pnp_option *option) 1051f32ca31SBjorn Helgaas { 1061f32ca31SBjorn Helgaas return (option->flags >> PNP_OPTION_PRIORITY_SHIFT) & 1071f32ca31SBjorn Helgaas PNP_OPTION_PRIORITY_MASK; 1081f32ca31SBjorn Helgaas } 1091f32ca31SBjorn Helgaas 1101f32ca31SBjorn Helgaas static inline unsigned int pnp_new_dependent_set(struct pnp_dev *dev, 1111f32ca31SBjorn Helgaas int priority) 1121f32ca31SBjorn Helgaas { 1131f32ca31SBjorn Helgaas unsigned int flags; 1141f32ca31SBjorn Helgaas 1151f32ca31SBjorn Helgaas if (priority > PNP_RES_PRIORITY_FUNCTIONAL) { 1161f32ca31SBjorn Helgaas dev_warn(&dev->dev, "invalid dependent option priority %d " 1171f32ca31SBjorn Helgaas "clipped to %d", priority, 1181f32ca31SBjorn Helgaas PNP_RES_PRIORITY_INVALID); 1191f32ca31SBjorn Helgaas priority = PNP_RES_PRIORITY_INVALID; 1201f32ca31SBjorn Helgaas } 1211f32ca31SBjorn Helgaas 1221f32ca31SBjorn Helgaas flags = PNP_OPTION_DEPENDENT | 1231f32ca31SBjorn Helgaas ((dev->num_dependent_sets & PNP_OPTION_SET_MASK) << 1241f32ca31SBjorn Helgaas PNP_OPTION_SET_SHIFT) | 1251f32ca31SBjorn Helgaas ((priority & PNP_OPTION_PRIORITY_MASK) << 1261f32ca31SBjorn Helgaas PNP_OPTION_PRIORITY_SHIFT); 1271f32ca31SBjorn Helgaas 1281f32ca31SBjorn Helgaas dev->num_dependent_sets++; 1291f32ca31SBjorn Helgaas 1301f32ca31SBjorn Helgaas return flags; 1311f32ca31SBjorn Helgaas } 1321f32ca31SBjorn Helgaas 1331f32ca31SBjorn Helgaas char *pnp_option_priority_name(struct pnp_option *option); 1341f32ca31SBjorn Helgaas void dbg_pnp_show_option(struct pnp_dev *dev, struct pnp_option *option); 1351f32ca31SBjorn Helgaas 13662cfb298SBjorn Helgaas void pnp_init_resources(struct pnp_dev *dev); 13762cfb298SBjorn Helgaas 1381da177e4SLinus Torvalds void pnp_fixup_device(struct pnp_dev *dev); 1391f32ca31SBjorn Helgaas void pnp_free_options(struct pnp_dev *dev); 1401da177e4SLinus Torvalds int __pnp_add_device(struct pnp_dev *dev); 1411da177e4SLinus Torvalds void __pnp_remove_device(struct pnp_dev *dev); 1421da177e4SLinus Torvalds 143f5d94ff0SBjorn Helgaas int pnp_check_port(struct pnp_dev *dev, struct resource *res); 144f5d94ff0SBjorn Helgaas int pnp_check_mem(struct pnp_dev *dev, struct resource *res); 145f5d94ff0SBjorn Helgaas int pnp_check_irq(struct pnp_dev *dev, struct resource *res); 146586f83e2SDavid Rientjes #ifdef CONFIG_ISA_DMA_API 147f5d94ff0SBjorn Helgaas int pnp_check_dma(struct pnp_dev *dev, struct resource *res); 148586f83e2SDavid Rientjes #endif 14981b5c75fSBjorn Helgaas 1509fdee4e0SBjorn Helgaas char *pnp_resource_type_name(struct resource *res); 15181b5c75fSBjorn Helgaas void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc); 152d948a8daSBjorn Helgaas 153aee3ad81SBjorn Helgaas void pnp_free_resources(struct pnp_dev *dev); 154b563cf59SRene Herman unsigned long pnp_resource_type(struct resource *res); 15502d83b5dSBjorn Helgaas 156784f01d5SBjorn Helgaas struct pnp_resource { 157aee3ad81SBjorn Helgaas struct list_head list; 158784f01d5SBjorn Helgaas struct resource res; 159784f01d5SBjorn Helgaas }; 160784f01d5SBjorn Helgaas 161aee3ad81SBjorn Helgaas void pnp_free_resource(struct pnp_resource *pnp_res); 162dbddd038SBjorn Helgaas 163046d9ce6SRafael J. Wysocki struct pnp_resource *pnp_add_resource(struct pnp_dev *dev, 164046d9ce6SRafael J. Wysocki struct resource *res); 165dbddd038SBjorn Helgaas struct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq, 166dbddd038SBjorn Helgaas int flags); 167dc16f5f2SBjorn Helgaas struct pnp_resource *pnp_add_dma_resource(struct pnp_dev *dev, int dma, 168dc16f5f2SBjorn Helgaas int flags); 169cc8c2e30SBjorn Helgaas struct pnp_resource *pnp_add_io_resource(struct pnp_dev *dev, 170cc8c2e30SBjorn Helgaas resource_size_t start, 171cc8c2e30SBjorn Helgaas resource_size_t end, int flags); 172d6180f36SBjorn Helgaas struct pnp_resource *pnp_add_mem_resource(struct pnp_dev *dev, 173d6180f36SBjorn Helgaas resource_size_t start, 174d6180f36SBjorn Helgaas resource_size_t end, int flags); 1757e0e9c04SBjorn Helgaas struct pnp_resource *pnp_add_bus_resource(struct pnp_dev *dev, 1767e0e9c04SBjorn Helgaas resource_size_t start, 1777e0e9c04SBjorn Helgaas resource_size_t end); 17897ef062bSBjorn Helgaas 17997ef062bSBjorn Helgaas extern int pnp_debug; 18097ef062bSBjorn Helgaas 18197ef062bSBjorn Helgaas #if defined(CONFIG_PNP_DEBUG_MESSAGES) 18297ef062bSBjorn Helgaas #define pnp_dbg(dev, format, arg...) \ 18397ef062bSBjorn Helgaas ({ if (pnp_debug) dev_printk(KERN_DEBUG, dev, format, ## arg); 0; }) 18497ef062bSBjorn Helgaas #else 18597ef062bSBjorn Helgaas #define pnp_dbg(dev, format, arg...) \ 18697ef062bSBjorn Helgaas ({ if (0) dev_printk(KERN_DEBUG, dev, format, ## arg); 0; }) 18797ef062bSBjorn Helgaas #endif 188