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