1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 /* 3 * platform_device.h - generic, centralized driver model 4 * 5 * Copyright (c) 2001-2003 Patrick Mochel <[email protected]> 6 * 7 * See Documentation/driver-api/driver-model/ for more information. 8 */ 9 10 #ifndef _PLATFORM_DEVICE_H_ 11 #define _PLATFORM_DEVICE_H_ 12 13 #include <linux/device.h> 14 15 #define PLATFORM_DEVID_NONE (-1) 16 #define PLATFORM_DEVID_AUTO (-2) 17 18 struct mfd_cell; 19 struct property_entry; 20 struct platform_device_id; 21 22 struct platform_device { 23 const char *name; 24 int id; 25 bool id_auto; 26 struct device dev; 27 u64 dma_mask; 28 u32 num_resources; 29 struct resource *resource; 30 31 const struct platform_device_id *id_entry; 32 char *driver_override; /* Driver name to force a match */ 33 34 /* MFD cell pointer */ 35 struct mfd_cell *mfd_cell; 36 37 /* arch specific additions */ 38 struct pdev_archdata archdata; 39 }; 40 41 #define platform_get_device_id(pdev) ((pdev)->id_entry) 42 43 #define dev_is_platform(dev) ((dev)->bus == &platform_bus_type) 44 #define to_platform_device(x) container_of((x), struct platform_device, dev) 45 46 extern int platform_device_register(struct platform_device *); 47 extern void platform_device_unregister(struct platform_device *); 48 49 extern struct bus_type platform_bus_type; 50 extern struct device platform_bus; 51 52 extern struct resource *platform_get_resource(struct platform_device *, 53 unsigned int, unsigned int); 54 extern struct device * 55 platform_find_device_by_driver(struct device *start, 56 const struct device_driver *drv); 57 extern void __iomem * 58 devm_platform_ioremap_resource(struct platform_device *pdev, 59 unsigned int index); 60 extern void __iomem * 61 devm_platform_ioremap_resource_wc(struct platform_device *pdev, 62 unsigned int index); 63 extern int platform_get_irq(struct platform_device *, unsigned int); 64 extern int platform_get_irq_optional(struct platform_device *, unsigned int); 65 extern int platform_irq_count(struct platform_device *); 66 extern struct resource *platform_get_resource_byname(struct platform_device *, 67 unsigned int, 68 const char *); 69 extern int platform_get_irq_byname(struct platform_device *, const char *); 70 extern int platform_get_irq_byname_optional(struct platform_device *dev, 71 const char *name); 72 extern int platform_add_devices(struct platform_device **, int); 73 74 struct platform_device_info { 75 struct device *parent; 76 struct fwnode_handle *fwnode; 77 bool of_node_reused; 78 79 const char *name; 80 int id; 81 82 const struct resource *res; 83 unsigned int num_res; 84 85 const void *data; 86 size_t size_data; 87 u64 dma_mask; 88 89 struct property_entry *properties; 90 }; 91 extern struct platform_device *platform_device_register_full( 92 const struct platform_device_info *pdevinfo); 93 94 /** 95 * platform_device_register_resndata - add a platform-level device with 96 * resources and platform-specific data 97 * 98 * @parent: parent device for the device we're adding 99 * @name: base name of the device we're adding 100 * @id: instance id 101 * @res: set of resources that needs to be allocated for the device 102 * @num: number of resources 103 * @data: platform specific data for this platform device 104 * @size: size of platform specific data 105 * 106 * Returns &struct platform_device pointer on success, or ERR_PTR() on error. 107 */ 108 static inline struct platform_device *platform_device_register_resndata( 109 struct device *parent, const char *name, int id, 110 const struct resource *res, unsigned int num, 111 const void *data, size_t size) { 112 113 struct platform_device_info pdevinfo = { 114 .parent = parent, 115 .name = name, 116 .id = id, 117 .res = res, 118 .num_res = num, 119 .data = data, 120 .size_data = size, 121 .dma_mask = 0, 122 }; 123 124 return platform_device_register_full(&pdevinfo); 125 } 126 127 /** 128 * platform_device_register_simple - add a platform-level device and its resources 129 * @name: base name of the device we're adding 130 * @id: instance id 131 * @res: set of resources that needs to be allocated for the device 132 * @num: number of resources 133 * 134 * This function creates a simple platform device that requires minimal 135 * resource and memory management. Canned release function freeing memory 136 * allocated for the device allows drivers using such devices to be 137 * unloaded without waiting for the last reference to the device to be 138 * dropped. 139 * 140 * This interface is primarily intended for use with legacy drivers which 141 * probe hardware directly. Because such drivers create sysfs device nodes 142 * themselves, rather than letting system infrastructure handle such device 143 * enumeration tasks, they don't fully conform to the Linux driver model. 144 * In particular, when such drivers are built as modules, they can't be 145 * "hotplugged". 146 * 147 * Returns &struct platform_device pointer on success, or ERR_PTR() on error. 148 */ 149 static inline struct platform_device *platform_device_register_simple( 150 const char *name, int id, 151 const struct resource *res, unsigned int num) 152 { 153 return platform_device_register_resndata(NULL, name, id, 154 res, num, NULL, 0); 155 } 156 157 /** 158 * platform_device_register_data - add a platform-level device with platform-specific data 159 * @parent: parent device for the device we're adding 160 * @name: base name of the device we're adding 161 * @id: instance id 162 * @data: platform specific data for this platform device 163 * @size: size of platform specific data 164 * 165 * This function creates a simple platform device that requires minimal 166 * resource and memory management. Canned release function freeing memory 167 * allocated for the device allows drivers using such devices to be 168 * unloaded without waiting for the last reference to the device to be 169 * dropped. 170 * 171 * Returns &struct platform_device pointer on success, or ERR_PTR() on error. 172 */ 173 static inline struct platform_device *platform_device_register_data( 174 struct device *parent, const char *name, int id, 175 const void *data, size_t size) 176 { 177 return platform_device_register_resndata(parent, name, id, 178 NULL, 0, data, size); 179 } 180 181 extern struct platform_device *platform_device_alloc(const char *name, int id); 182 extern int platform_device_add_resources(struct platform_device *pdev, 183 const struct resource *res, 184 unsigned int num); 185 extern int platform_device_add_data(struct platform_device *pdev, 186 const void *data, size_t size); 187 extern int platform_device_add_properties(struct platform_device *pdev, 188 const struct property_entry *properties); 189 extern int platform_device_add(struct platform_device *pdev); 190 extern void platform_device_del(struct platform_device *pdev); 191 extern void platform_device_put(struct platform_device *pdev); 192 193 struct platform_driver { 194 int (*probe)(struct platform_device *); 195 int (*remove)(struct platform_device *); 196 void (*shutdown)(struct platform_device *); 197 int (*suspend)(struct platform_device *, pm_message_t state); 198 int (*resume)(struct platform_device *); 199 struct device_driver driver; 200 const struct platform_device_id *id_table; 201 bool prevent_deferred_probe; 202 }; 203 204 #define to_platform_driver(drv) (container_of((drv), struct platform_driver, \ 205 driver)) 206 207 /* 208 * use a macro to avoid include chaining to get THIS_MODULE 209 */ 210 #define platform_driver_register(drv) \ 211 __platform_driver_register(drv, THIS_MODULE) 212 extern int __platform_driver_register(struct platform_driver *, 213 struct module *); 214 extern void platform_driver_unregister(struct platform_driver *); 215 216 /* non-hotpluggable platform devices may use this so that probe() and 217 * its support may live in __init sections, conserving runtime memory. 218 */ 219 #define platform_driver_probe(drv, probe) \ 220 __platform_driver_probe(drv, probe, THIS_MODULE) 221 extern int __platform_driver_probe(struct platform_driver *driver, 222 int (*probe)(struct platform_device *), struct module *module); 223 224 static inline void *platform_get_drvdata(const struct platform_device *pdev) 225 { 226 return dev_get_drvdata(&pdev->dev); 227 } 228 229 static inline void platform_set_drvdata(struct platform_device *pdev, 230 void *data) 231 { 232 dev_set_drvdata(&pdev->dev, data); 233 } 234 235 /* module_platform_driver() - Helper macro for drivers that don't do 236 * anything special in module init/exit. This eliminates a lot of 237 * boilerplate. Each module may only use this macro once, and 238 * calling it replaces module_init() and module_exit() 239 */ 240 #define module_platform_driver(__platform_driver) \ 241 module_driver(__platform_driver, platform_driver_register, \ 242 platform_driver_unregister) 243 244 /* builtin_platform_driver() - Helper macro for builtin drivers that 245 * don't do anything special in driver init. This eliminates some 246 * boilerplate. Each driver may only use this macro once, and 247 * calling it replaces device_initcall(). Note this is meant to be 248 * a parallel of module_platform_driver() above, but w/o _exit stuff. 249 */ 250 #define builtin_platform_driver(__platform_driver) \ 251 builtin_driver(__platform_driver, platform_driver_register) 252 253 /* module_platform_driver_probe() - Helper macro for drivers that don't do 254 * anything special in module init/exit. This eliminates a lot of 255 * boilerplate. Each module may only use this macro once, and 256 * calling it replaces module_init() and module_exit() 257 */ 258 #define module_platform_driver_probe(__platform_driver, __platform_probe) \ 259 static int __init __platform_driver##_init(void) \ 260 { \ 261 return platform_driver_probe(&(__platform_driver), \ 262 __platform_probe); \ 263 } \ 264 module_init(__platform_driver##_init); \ 265 static void __exit __platform_driver##_exit(void) \ 266 { \ 267 platform_driver_unregister(&(__platform_driver)); \ 268 } \ 269 module_exit(__platform_driver##_exit); 270 271 /* builtin_platform_driver_probe() - Helper macro for drivers that don't do 272 * anything special in device init. This eliminates some boilerplate. Each 273 * driver may only use this macro once, and using it replaces device_initcall. 274 * This is meant to be a parallel of module_platform_driver_probe above, but 275 * without the __exit parts. 276 */ 277 #define builtin_platform_driver_probe(__platform_driver, __platform_probe) \ 278 static int __init __platform_driver##_init(void) \ 279 { \ 280 return platform_driver_probe(&(__platform_driver), \ 281 __platform_probe); \ 282 } \ 283 device_initcall(__platform_driver##_init); \ 284 285 #define platform_create_bundle(driver, probe, res, n_res, data, size) \ 286 __platform_create_bundle(driver, probe, res, n_res, data, size, THIS_MODULE) 287 extern struct platform_device *__platform_create_bundle( 288 struct platform_driver *driver, int (*probe)(struct platform_device *), 289 struct resource *res, unsigned int n_res, 290 const void *data, size_t size, struct module *module); 291 292 int __platform_register_drivers(struct platform_driver * const *drivers, 293 unsigned int count, struct module *owner); 294 void platform_unregister_drivers(struct platform_driver * const *drivers, 295 unsigned int count); 296 297 #define platform_register_drivers(drivers, count) \ 298 __platform_register_drivers(drivers, count, THIS_MODULE) 299 300 #ifdef CONFIG_SUSPEND 301 extern int platform_pm_suspend(struct device *dev); 302 extern int platform_pm_resume(struct device *dev); 303 #else 304 #define platform_pm_suspend NULL 305 #define platform_pm_resume NULL 306 #endif 307 308 #ifdef CONFIG_HIBERNATE_CALLBACKS 309 extern int platform_pm_freeze(struct device *dev); 310 extern int platform_pm_thaw(struct device *dev); 311 extern int platform_pm_poweroff(struct device *dev); 312 extern int platform_pm_restore(struct device *dev); 313 #else 314 #define platform_pm_freeze NULL 315 #define platform_pm_thaw NULL 316 #define platform_pm_poweroff NULL 317 #define platform_pm_restore NULL 318 #endif 319 320 extern int platform_dma_configure(struct device *dev); 321 322 #ifdef CONFIG_PM_SLEEP 323 #define USE_PLATFORM_PM_SLEEP_OPS \ 324 .suspend = platform_pm_suspend, \ 325 .resume = platform_pm_resume, \ 326 .freeze = platform_pm_freeze, \ 327 .thaw = platform_pm_thaw, \ 328 .poweroff = platform_pm_poweroff, \ 329 .restore = platform_pm_restore, 330 #else 331 #define USE_PLATFORM_PM_SLEEP_OPS 332 #endif 333 334 #ifndef CONFIG_SUPERH 335 /* 336 * REVISIT: This stub is needed for all non-SuperH users of early platform 337 * drivers. It should go away once we introduce the new platform_device-based 338 * early driver framework. 339 */ 340 static inline int is_sh_early_platform_device(struct platform_device *pdev) 341 { 342 return 0; 343 } 344 #endif /* CONFIG_SUPERH */ 345 346 #endif /* _PLATFORM_DEVICE_H_ */ 347