1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 3 * Copyright (C) 2008 Hewlett-Packard Development Company, L.P. 4 * Bjorn Helgaas <bjorn.helgaas@hp.com> 5 */ 6 7 extern struct mutex pnp_lock; 8 extern const struct attribute_group *pnp_dev_groups[]; 9 10 int pnp_register_protocol(struct pnp_protocol *protocol); 11 void pnp_unregister_protocol(struct pnp_protocol *protocol); 12 13 #define PNP_EISA_ID_MASK 0x7fffffff 14 void pnp_eisa_id_to_string(u32 id, char *str); 15 struct pnp_dev *pnp_alloc_dev(struct pnp_protocol *, int id, 16 const char *pnpid); 17 struct pnp_card *pnp_alloc_card(struct pnp_protocol *, int id, char *pnpid); 18 19 int pnp_add_device(struct pnp_dev *dev); 20 struct pnp_id *pnp_add_id(struct pnp_dev *dev, const char *id); 21 22 int pnp_add_card(struct pnp_card *card); 23 void pnp_remove_card(struct pnp_card *card); 24 int pnp_add_card_device(struct pnp_card *card, struct pnp_dev *dev); 25 void pnp_remove_card_device(struct pnp_dev *dev); 26 27 struct pnp_port { 28 resource_size_t min; /* min base number */ 29 resource_size_t max; /* max base number */ 30 resource_size_t align; /* align boundary */ 31 resource_size_t size; /* size of range */ 32 unsigned char flags; /* port flags */ 33 }; 34 35 #define PNP_IRQ_NR 256 36 typedef struct { DECLARE_BITMAP(bits, PNP_IRQ_NR); } pnp_irq_mask_t; 37 38 struct pnp_irq { 39 pnp_irq_mask_t map; /* bitmap for IRQ lines */ 40 unsigned char flags; /* IRQ flags */ 41 }; 42 43 struct pnp_dma { 44 unsigned char map; /* bitmask for DMA channels */ 45 unsigned char flags; /* DMA flags */ 46 }; 47 48 struct pnp_mem { 49 resource_size_t min; /* min base number */ 50 resource_size_t max; /* max base number */ 51 resource_size_t align; /* align boundary */ 52 resource_size_t size; /* size of range */ 53 unsigned char flags; /* memory flags */ 54 }; 55 56 #define PNP_OPTION_DEPENDENT 0x80000000 57 #define PNP_OPTION_SET_MASK 0xffff 58 #define PNP_OPTION_SET_SHIFT 12 59 #define PNP_OPTION_PRIORITY_MASK 0xfff 60 #define PNP_OPTION_PRIORITY_SHIFT 0 61 62 #define PNP_RES_PRIORITY_PREFERRED 0 63 #define PNP_RES_PRIORITY_ACCEPTABLE 1 64 #define PNP_RES_PRIORITY_FUNCTIONAL 2 65 #define PNP_RES_PRIORITY_INVALID PNP_OPTION_PRIORITY_MASK 66 67 struct pnp_option { 68 struct list_head list; 69 unsigned int flags; /* independent/dependent, set, priority */ 70 71 unsigned long type; /* IORESOURCE_{IO,MEM,IRQ,DMA} */ 72 union { 73 struct pnp_port port; 74 struct pnp_irq irq; 75 struct pnp_dma dma; 76 struct pnp_mem mem; 77 } u; 78 }; 79 80 int pnp_register_irq_resource(struct pnp_dev *dev, unsigned int option_flags, 81 pnp_irq_mask_t *map, unsigned char flags); 82 int pnp_register_dma_resource(struct pnp_dev *dev, unsigned int option_flags, 83 unsigned char map, unsigned char flags); 84 int pnp_register_port_resource(struct pnp_dev *dev, unsigned int option_flags, 85 resource_size_t min, resource_size_t max, 86 resource_size_t align, resource_size_t size, 87 unsigned char flags); 88 int pnp_register_mem_resource(struct pnp_dev *dev, unsigned int option_flags, 89 resource_size_t min, resource_size_t max, 90 resource_size_t align, resource_size_t size, 91 unsigned char flags); 92 93 static inline int pnp_option_is_dependent(struct pnp_option *option) 94 { 95 return option->flags & PNP_OPTION_DEPENDENT ? 1 : 0; 96 } 97 98 static inline unsigned int pnp_option_set(struct pnp_option *option) 99 { 100 return (option->flags >> PNP_OPTION_SET_SHIFT) & PNP_OPTION_SET_MASK; 101 } 102 103 static inline unsigned int pnp_option_priority(struct pnp_option *option) 104 { 105 return (option->flags >> PNP_OPTION_PRIORITY_SHIFT) & 106 PNP_OPTION_PRIORITY_MASK; 107 } 108 109 static inline unsigned int pnp_new_dependent_set(struct pnp_dev *dev, 110 int priority) 111 { 112 unsigned int flags; 113 114 if (priority > PNP_RES_PRIORITY_FUNCTIONAL) { 115 dev_warn(&dev->dev, "invalid dependent option priority %d " 116 "clipped to %d", priority, 117 PNP_RES_PRIORITY_INVALID); 118 priority = PNP_RES_PRIORITY_INVALID; 119 } 120 121 flags = PNP_OPTION_DEPENDENT | 122 ((dev->num_dependent_sets & PNP_OPTION_SET_MASK) << 123 PNP_OPTION_SET_SHIFT) | 124 ((priority & PNP_OPTION_PRIORITY_MASK) << 125 PNP_OPTION_PRIORITY_SHIFT); 126 127 dev->num_dependent_sets++; 128 129 return flags; 130 } 131 132 char *pnp_option_priority_name(struct pnp_option *option); 133 void dbg_pnp_show_option(struct pnp_dev *dev, struct pnp_option *option); 134 135 void pnp_init_resources(struct pnp_dev *dev); 136 137 void pnp_fixup_device(struct pnp_dev *dev); 138 void pnp_free_options(struct pnp_dev *dev); 139 int __pnp_add_device(struct pnp_dev *dev); 140 void __pnp_remove_device(struct pnp_dev *dev); 141 142 int pnp_check_port(struct pnp_dev *dev, struct resource *res); 143 int pnp_check_mem(struct pnp_dev *dev, struct resource *res); 144 int pnp_check_irq(struct pnp_dev *dev, struct resource *res); 145 #ifdef CONFIG_ISA_DMA_API 146 int pnp_check_dma(struct pnp_dev *dev, struct resource *res); 147 #endif 148 149 char *pnp_resource_type_name(struct resource *res); 150 void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc); 151 152 void pnp_free_resources(struct pnp_dev *dev); 153 unsigned long pnp_resource_type(struct resource *res); 154 155 struct pnp_resource { 156 struct list_head list; 157 struct resource res; 158 }; 159 160 void pnp_free_resource(struct pnp_resource *pnp_res); 161 162 struct pnp_resource *pnp_add_resource(struct pnp_dev *dev, 163 struct resource *res); 164 struct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq, 165 int flags); 166 struct pnp_resource *pnp_add_dma_resource(struct pnp_dev *dev, int dma, 167 int flags); 168 struct pnp_resource *pnp_add_io_resource(struct pnp_dev *dev, 169 resource_size_t start, 170 resource_size_t end, int flags); 171 struct pnp_resource *pnp_add_mem_resource(struct pnp_dev *dev, 172 resource_size_t start, 173 resource_size_t end, int flags); 174 struct pnp_resource *pnp_add_bus_resource(struct pnp_dev *dev, 175 resource_size_t start, 176 resource_size_t end); 177 178 extern int pnp_debug; 179 180 #if defined(CONFIG_PNP_DEBUG_MESSAGES) 181 #define pnp_dbg(dev, format, arg...) \ 182 ({ if (pnp_debug) dev_printk(KERN_DEBUG, dev, format, ## arg); 0; }) 183 #else 184 #define pnp_dbg(dev, format, arg...) \ 185 ({ if (0) dev_printk(KERN_DEBUG, dev, format, ## arg); 0; }) 186 #endif 187