diff options
Diffstat (limited to 'include/driver.h')
-rw-r--r-- | include/driver.h | 426 |
1 files changed, 336 insertions, 90 deletions
diff --git a/include/driver.h b/include/driver.h index 300603fa32..e02815d09b 100644 --- a/include/driver.h +++ b/include/driver.h @@ -1,19 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* * (C) 2007 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de> - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #ifndef DRIVER_H @@ -21,7 +8,10 @@ #include <linux/list.h> #include <linux/ioport.h> +#include <linux/uuid.h> +#include <linux/printk.h> #include <of.h> +#include <init.h> #include <filetype.h> #define FORMAT_DRIVER_NAME_ID "%s%d" @@ -30,14 +20,21 @@ struct filep; struct bus_type; +struct generic_pm_domain; struct platform_device_id { const char *name; unsigned long driver_data; }; +enum dev_dma_coherence { + DEV_DMA_COHERENCE_DEFAULT = 0, + DEV_DMA_COHERENT, + DEV_DMA_NON_COHERENT, +}; + /** @brief Describes a particular device present in the system */ -struct device_d { +struct device { /*! This member (and 'type' described below) is used to match * with a driver. This is a descriptive name and could be * MPC5XXX_ether or imx_serial. Unless absolutely necessary, @@ -56,6 +53,8 @@ struct device_d { * something like eth0 or nor0. */ int id; + enum dev_dma_coherence dma_coherent; + struct resource *resource; int num_resources; @@ -68,7 +67,7 @@ struct device_d { void *type_data; /*! In case this device is a specific device, this pointer * points to the type specific device, i.e. eth_device */ - struct driver_d *driver; /*! The driver for this device */ + struct driver *driver; /*! The driver for this device */ struct list_head list; /* The list of all devices */ struct list_head bus_list; /* our bus */ @@ -76,7 +75,9 @@ struct device_d { struct list_head sibling; struct list_head active; /* The list of all devices which have a driver */ - struct device_d *parent; /* our parent, NULL if not present */ + struct device *parent; /* our parent, NULL if not present */ + + struct generic_pm_domain *pm_domain; /* attached power domain */ struct bus_type *bus; @@ -87,22 +88,39 @@ struct device_d { struct list_head cdevs; const struct platform_device_id *id_entry; - struct device_node *device_node; + union { + struct device_node *device_node; + struct device_node *of_node; + }; const struct of_device_id *of_id_entry; u64 dma_mask; - void (*info) (struct device_d *); + unsigned long dma_offset; + + void (*info) (struct device *); /* * For devices which take longer to probe this is called * when the driver should actually detect client devices */ - int (*detect) (struct device_d *); + int (*detect) (struct device *); + void (*rescan) (struct device *); + + /* + * if a driver probe is deferred, this stores the last error + */ + char *deferred_probe_reason; +}; + +struct device_alias { + struct device *dev; + struct list_head list; + char name[]; }; /** @brief Describes a driver present in the system */ -struct driver_d { +struct driver { /*! The name of this driver. Used to match to * the corresponding device. */ const char *name; @@ -111,21 +129,25 @@ struct driver_d { struct list_head bus_list; /* our bus */ /*! Called if an instance of a device is found */ - int (*probe) (struct device_d *); + int (*probe) (struct device *); /*! Called if an instance of a device is gone. */ - void (*remove)(struct device_d *); + void (*remove)(struct device *); struct bus_type *bus; const struct platform_device_id *id_table; - const struct of_device_id *of_compatible; + union { + const struct of_device_id *of_compatible; + const struct of_device_id *of_match_table; + }; }; /*@}*/ /* do not delete, doxygen relevant */ -#define RW_SIZE(x) (x) -#define RW_SIZE_MASK 0x7 +/* Legacy naming for out-of-tree patches. Will be phased out in future. */ +#define device_d device +#define driver_d driver /* dynamically assign the next free id */ #define DEVICE_ID_DYNAMIC -2 @@ -134,42 +156,70 @@ struct driver_d { /* Register devices and drivers. */ -int register_driver(struct driver_d *); -int register_device(struct device_d *); +int register_driver(struct driver *); +void unregister_driver(struct driver *drv); + +int register_device(struct device *); /* manualy probe a device * the driver need to be specified */ -int device_probe(struct device_d *dev); +int device_probe(struct device *dev); + +/** + * device_remove - Remove a device from its bus and driver + * + * @dev: Device + * + * Returns true if there was any bus or driver specific removal + * code that was executed and false if the function was a no-op. + */ +bool device_remove(struct device *dev); /* detect devices attached to this device (cards, disks,...) */ -int device_detect(struct device_d *dev); +int device_detect(struct device *dev); int device_detect_by_name(const char *devname); void device_detect_all(void); /* Unregister a device. This function can fail, e.g. when the device * has children. */ -int unregister_device(struct device_d *); +int unregister_device(struct device *); + +static inline void put_device(struct device *dev) {} + +void free_device_res(struct device *dev); +void free_device(struct device *dev); + +static inline void device_rescan(struct device *dev) +{ + if (dev->rescan) + dev->rescan(dev); +} /* Iterate over a devices children */ #define device_for_each_child(dev, child) \ - list_for_each_entry(child, &dev->children, sibling) + list_for_each_entry(child, &(dev)->children, sibling) /* Iterate over a devices children - Safe against removal version */ #define device_for_each_child_safe(dev, tmpdev, child) \ - list_for_each_entry_safe(child, tmpdev, &dev->children, sibling) + list_for_each_entry_safe(child, tmpdev, &(dev)->children, sibling) /* Iterate through the devices of a given type. if last is NULL, the * first device of this type is returned. Put this pointer in as * 'last' to get the next device. This functions returns NULL if no * more devices are found. */ -struct device_d *get_device_by_type(ulong type, struct device_d *last); -struct device_d *get_device_by_id(const char *id); -struct device_d *get_device_by_name(const char *name); +struct device *get_device_by_type(ulong type, struct device *last); +struct device *get_device_by_id(const char *id); +struct device *get_device_by_name(const char *name); + +/* Find a device by name and if not found look up by device tree path + * or alias + */ +struct device *find_device(const char *str); /* Find a free device id from the given template. This is archieved by * appending a number to the template. Dynamically created devices should @@ -179,51 +229,69 @@ int get_free_deviceid(const char *name_template); char *deviceid_from_spec_str(const char *str, char **endp); -static inline const char *dev_id(const struct device_d *dev) +static inline const char *dev_id(const struct device *dev) { + if (!dev) + return NULL; return (dev->id != DEVICE_ID_SINGLE) ? dev->unique_name : dev->name; } -static inline const char *dev_name(const struct device_d *dev) +static inline const char *dev_name(const struct device *dev) { - return dev_id(dev); + if (!dev) + return NULL; + return dev_id(dev) ?: dev->name; } -int dev_set_name(struct device_d *dev, const char *fmt, ...); +int dev_set_name(struct device *dev, const char *fmt, ...); +int dev_add_alias(struct device *dev, const char *fmt, ...); /* * get resource 'num' for a device */ -struct resource *dev_get_resource(struct device_d *dev, unsigned long type, +struct resource *dev_get_resource(struct device *dev, unsigned long type, int num); /* * get resource base 'name' for a device */ -struct resource *dev_get_resource_by_name(struct device_d *dev, +struct resource *dev_get_resource_by_name(struct device *dev, unsigned long type, const char *name); +int dev_request_resource(struct device *dev, + const struct resource *res); + /* * exlusively request register base 'name' for a device */ -void __iomem *dev_request_mem_region_by_name(struct device_d *dev, +void __iomem *dev_request_mem_region_by_name(struct device *dev, const char *name); /* * get register base 'num' for a device */ -void *dev_get_mem_region(struct device_d *dev, int num); +void *dev_get_mem_region(struct device *dev, int num); /* * exlusively request register base 'num' for a device * deprecated, use dev_request_mem_resource instead */ -void __iomem *dev_request_mem_region(struct device_d *dev, int num); +void __iomem *dev_request_mem_region(struct device *dev, int num); /* * exlusively request resource 'num' for a device */ -struct resource *dev_request_mem_resource(struct device_d *dev, int num); +struct resource *dev_request_mem_resource(struct device *dev, int num); + +/* + * exlusively request resource 'name' for a device + */ +struct resource *dev_request_mem_resource_by_name(struct device *dev, + const char *name); + +void __iomem *dev_platform_get_and_ioremap_resource(struct device *dev, + int num, + struct resource **out_res); /* * exlusively request register base 'num' for a device @@ -231,43 +299,53 @@ struct resource *dev_request_mem_resource(struct device_d *dev, int num); * only used on platform like at91 where the Ressource address collision with * PTR errno */ -void __iomem *dev_request_mem_region_err_null(struct device_d *dev, int num); +void __iomem *dev_request_mem_region_err_null(struct device *dev, int num); -struct device_d *device_alloc(const char *devname, int id); +struct device *device_alloc(const char *devname, int id); -int device_add_resources(struct device_d *dev, const struct resource *res, int num); +int device_add_resources(struct device *dev, const struct resource *res, + int num); -int device_add_resource(struct device_d *dev, const char *resname, - resource_size_t start, resource_size_t size, unsigned int flags); +int device_add_resource(struct device *dev, const char *resname, + resource_size_t start, resource_size_t size, + unsigned int flags); -int device_add_data(struct device_d *dev, void *data, size_t size); +int device_add_data(struct device *dev, const void *data, size_t size); + +struct device *add_child_device(struct device *parent, + const char* devname, int id, const char *resname, + resource_size_t start, resource_size_t size, unsigned int flags, + void *pdata); /* * register a generic device * with only one resource */ -struct device_d *add_generic_device(const char* devname, int id, const char *resname, +static inline struct device *add_generic_device(const char* devname, int id, const char *resname, resource_size_t start, resource_size_t size, unsigned int flags, - void *pdata); + void *pdata) +{ + return add_child_device(NULL, devname, id, resname, start, size, flags, pdata); +} /* * register a generic device * with multiple resources */ -struct device_d *add_generic_device_res(const char* devname, int id, +struct device *add_generic_device_res(const char* devname, int id, struct resource *res, int nb, void *pdata); /* * register a memory device */ -static inline struct device_d *add_mem_device(const char *name, resource_size_t start, +static inline struct device *add_mem_device(const char *name, resource_size_t start, resource_size_t size, unsigned int flags) { return add_generic_device("mem", DEVICE_ID_DYNAMIC, name, start, size, IORESOURCE_MEM | flags, NULL); } -static inline struct device_d *add_cfi_flash_device(int id, resource_size_t start, +static inline struct device *add_cfi_flash_device(int id, resource_size_t start, resource_size_t size, unsigned int flags) { return add_generic_device("cfi_flash", id, NULL, start, size, @@ -275,7 +353,7 @@ static inline struct device_d *add_cfi_flash_device(int id, resource_size_t star } struct NS16550_plat; -static inline struct device_d *add_ns16550_device(int id, resource_size_t start, +static inline struct device *add_ns16550_device(int id, resource_size_t start, resource_size_t size, int flags, struct NS16550_plat *pdata) { return add_generic_device("ns16550_serial", id, NULL, start, size, @@ -283,10 +361,10 @@ static inline struct device_d *add_ns16550_device(int id, resource_size_t start, } #ifdef CONFIG_DRIVER_NET_DM9K -struct device_d *add_dm9000_device(int id, resource_size_t base, +struct device *add_dm9000_device(int id, resource_size_t base, resource_size_t data, int flags, void *pdata); #else -static inline struct device_d *add_dm9000_device(int id, resource_size_t base, +static inline struct device *add_dm9000_device(int id, resource_size_t base, resource_size_t data, int flags, void *pdata) { return NULL; @@ -294,10 +372,10 @@ static inline struct device_d *add_dm9000_device(int id, resource_size_t base, #endif #ifdef CONFIG_USB_EHCI -struct device_d *add_usb_ehci_device(int id, resource_size_t hccr, +struct device *add_usb_ehci_device(int id, resource_size_t hccr, resource_size_t hcor, void *pdata); #else -static inline struct device_d *add_usb_ehci_device(int id, resource_size_t hccr, +static inline struct device *add_usb_ehci_device(int id, resource_size_t hccr, resource_size_t hcor, void *pdata) { return NULL; @@ -305,23 +383,23 @@ static inline struct device_d *add_usb_ehci_device(int id, resource_size_t hccr, #endif #ifdef CONFIG_DRIVER_NET_KS8851_MLL -struct device_d *add_ks8851_device(int id, resource_size_t addr, +struct device *add_ks8851_device(int id, resource_size_t addr, resource_size_t addr_cmd, int flags, void *pdata); #else -static inline struct device_d *add_ks8851_device(int id, resource_size_t addr, +static inline struct device *add_ks8851_device(int id, resource_size_t addr, resource_size_t addr_cmd, int flags, void *pdata) { return NULL; } #endif -static inline struct device_d *add_generic_usb_ehci_device(int id, +static inline struct device *add_generic_usb_ehci_device(int id, resource_size_t base, void *pdata) { return add_usb_ehci_device(id, base + 0x100, base + 0x140, pdata); } -static inline struct device_d *add_gpio_keys_device(int id, void *pdata) +static inline struct device *add_gpio_keys_device(int id, void *pdata) { return add_generic_device_res("gpio_keys", id, 0, 0, pdata); } @@ -334,6 +412,10 @@ extern struct list_head device_list; */ extern struct list_head driver_list; +/* linear list over all active devices + */ +extern struct list_head active_device_list; + /* Iterate over all devices */ #define for_each_device(dev) list_for_each_entry(dev, &device_list, list) @@ -346,34 +428,37 @@ extern struct list_head driver_list; * uses this to get the driver from the name the user specifies with the * mount command */ -struct driver_d *get_driver_by_name(const char *name); +struct driver *get_driver_by_name(const char *name); struct cdev; /* These are used by drivers which work with direct memory accesses */ ssize_t mem_read(struct cdev *cdev, void *buf, size_t count, loff_t offset, ulong flags); ssize_t mem_write(struct cdev *cdev, const void *buf, size_t count, loff_t offset, ulong flags); +ssize_t mem_copy(struct device *dev, void *dst, const void *src, + resource_size_t count, resource_size_t offset, + unsigned long flags); int generic_memmap_ro(struct cdev *dev, void **map, int flags); int generic_memmap_rw(struct cdev *dev, void **map, int flags); -static inline int dev_open_default(struct device_d *dev, struct filep *f) +static inline int dev_open_default(struct device *dev, struct filep *f) { return 0; } -static inline int dev_close_default(struct device_d *dev, struct filep *f) +static inline int dev_close_default(struct device *dev, struct filep *f) { return 0; } struct bus_type { char *name; - int (*match)(struct device_d *dev, struct driver_d *drv); - int (*probe)(struct device_d *dev); - void (*remove)(struct device_d *dev); + int (*match)(struct device *dev, struct driver *drv); + int (*probe)(struct device *dev); + void (*remove)(struct device *dev); - struct device_d *dev; + struct device *dev; struct list_head list; struct list_head device_list; @@ -381,7 +466,7 @@ struct bus_type { }; int bus_register(struct bus_type *bus); -int device_match(struct device_d *dev, struct driver_d *drv); +int device_match(struct device *dev, struct driver *drv); extern struct list_head bus_list; @@ -399,7 +484,7 @@ extern struct list_head bus_list; extern struct bus_type platform_bus; -int platform_driver_register(struct driver_d *drv); +int platform_driver_register(struct driver *drv); /* register_driver_macro() - Helper macro for drivers that don't do * anything special in module registration. This eliminates a lot of @@ -412,6 +497,8 @@ int platform_driver_register(struct driver_d *drv); } \ level##_initcall(drv##_register) +#define core_platform_driver(drv) \ + register_driver_macro(core,platform,drv) #define postcore_platform_driver(drv) \ register_driver_macro(postcore,platform,drv) #define coredevice_platform_driver(drv) \ @@ -420,10 +507,23 @@ int platform_driver_register(struct driver_d *drv); register_driver_macro(device,platform,drv) #define console_platform_driver(drv) \ register_driver_macro(console,platform,drv) +#define fs_platform_driver(drv) \ + register_driver_macro(fs,platform,drv) #define late_platform_driver(drv) \ register_driver_macro(late,platform,drv) -int platform_device_register(struct device_d *new_device); +#define mem_platform_driver(drv) \ + static int __init drv##_init(void) \ + { \ + int ret; \ + ret = platform_driver_register(&drv); \ + if (ret) \ + return ret; \ + return of_devices_ensure_probed_by_dev_id(drv.of_compatible); \ + } \ + mem_initcall(drv##_init); + +int platform_device_register(struct device *new_device); struct cdev_operations { /*! Called in response of reading from this device. Required */ @@ -439,16 +539,17 @@ struct cdev_operations { int (*flush)(struct cdev*); int (*erase)(struct cdev*, loff_t count, loff_t offset); int (*protect)(struct cdev*, size_t count, loff_t offset, int prot); + int (*discard_range)(struct cdev*, loff_t count, loff_t offset); int (*memmap)(struct cdev*, void **map, int flags); int (*truncate)(struct cdev*, size_t size); }; -#define MAX_PARTUUID_STR sizeof("00112233-4455-6677-8899-AABBCCDDEEFF") +#define MAX_UUID_STR sizeof("00112233-4455-6677-8899-AABBCCDDEEFF") struct cdev { const struct cdev_operations *ops; void *priv; - struct device_d *dev; + struct device *dev; struct device_node *device_node; struct list_head list; struct list_head devices_list; @@ -456,49 +557,127 @@ struct cdev { char *partname; /* the partition name, usually the above without the * device part, i.e. name = "nand0.barebox" -> partname = "barebox" */ - char partuuid[MAX_PARTUUID_STR]; + union { + char diskuuid[MAX_UUID_STR]; /* GPT Header DiskGUID or + * MBR Header NT Disk Signature + */ + char partuuid[MAX_UUID_STR]; /* GPT Partition Entry UniquePartitionGUID or + * MBR Partition Entry "${nt_signature}-${partno}" + */ + }; + loff_t offset; loff_t size; unsigned int flags; + u16 typeflags; /* GPT type-specific attributes */ int open; struct mtd_info *mtd; - u8 dos_partition_type; struct cdev *link; struct list_head link_entry, links; struct list_head partition_entry, partitions; struct cdev *master; enum filetype filetype; + union { + u8 dos_partition_type; + guid_t typeuuid; + }; }; +static inline struct device_node *cdev_of_node(const struct cdev *cdev) +{ + return IS_ENABLED(CONFIG_OFDEVICE) ? cdev->device_node : NULL; +} + +static inline void cdev_set_of_node(struct cdev *cdev, struct device_node *np) +{ + if (IS_ENABLED(CONFIG_OFDEVICE)) + cdev->device_node = np; +} + +static inline const char *cdev_name(struct cdev *cdev) +{ + return cdev ? cdev->name : NULL; +} + int devfs_create(struct cdev *); int devfs_create_link(struct cdev *, const char *name); int devfs_remove(struct cdev *); int cdev_find_free_index(const char *); -struct cdev *device_find_partition(struct device_d *dev, const char *name); +struct cdev *device_find_partition(struct device *dev, const char *name); struct cdev *cdev_by_name(const char *filename); struct cdev *lcdev_by_name(const char *filename); struct cdev *cdev_readlink(struct cdev *cdev); struct cdev *cdev_by_device_node(struct device_node *node); struct cdev *cdev_by_partuuid(const char *partuuid); -struct cdev *cdev_open(const char *name, unsigned long flags); +struct cdev *cdev_by_diskuuid(const char *partuuid); +struct cdev *cdev_open_by_name(const char *name, unsigned long flags); struct cdev *cdev_create_loop(const char *path, ulong flags, loff_t offset); void cdev_remove_loop(struct cdev *cdev); -int cdev_do_open(struct cdev *, unsigned long flags); +int cdev_open(struct cdev *, unsigned long flags); +int cdev_fdopen(struct cdev *cdev, unsigned long flags); void cdev_close(struct cdev *cdev); int cdev_flush(struct cdev *cdev); ssize_t cdev_read(struct cdev *cdev, void *buf, size_t count, loff_t offset, ulong flags); ssize_t cdev_write(struct cdev *cdev, const void *buf, size_t count, loff_t offset, ulong flags); int cdev_ioctl(struct cdev *cdev, int cmd, void *buf); int cdev_erase(struct cdev *cdev, loff_t count, loff_t offset); +int cdev_lseek(struct cdev*, loff_t); +int cdev_protect(struct cdev*, size_t count, loff_t offset, int prot); +int cdev_discard_range(struct cdev*, loff_t count, loff_t offset); +int cdev_memmap(struct cdev*, void **map, int flags); +int cdev_truncate(struct cdev*, size_t size); +loff_t cdev_unallocated_space(struct cdev *cdev); +static inline bool cdev_is_partition(const struct cdev *cdev) +{ + return cdev->master != NULL; +} + +extern struct list_head cdev_list; +#define for_each_cdev(cdev) \ + list_for_each_entry((cdev), &cdev_list, list) + +#define for_each_cdev_partition(partcdev, cdev) \ + list_for_each_entry((partcdev), &(cdev)->partitions, partition_entry) #define DEVFS_PARTITION_FIXED (1U << 0) #define DEVFS_PARTITION_READONLY (1U << 1) #define DEVFS_IS_CHARACTER_DEV (1U << 3) -#define DEVFS_PARTITION_FROM_TABLE (1U << 4) +#define DEVFS_IS_MCI_MAIN_PART_DEV (1U << 4) +#define DEVFS_PARTITION_FROM_OF (1U << 5) +#define DEVFS_PARTITION_FROM_TABLE (1U << 6) +#define DEVFS_IS_MBR_PARTITIONED (1U << 7) +#define DEVFS_IS_GPT_PARTITIONED (1U << 8) +#define DEVFS_PARTITION_REQUIRED (1U << 9) +#define DEVFS_PARTITION_NO_EXPORT (1U << 10) +#define DEVFS_PARTITION_BOOTABLE_LEGACY (1U << 11) +#define DEVFS_PARTITION_BOOTABLE_ESP (1U << 12) +#define DEVFS_PARTITION_FOR_FIXUP (1U << 13) + +static inline bool cdev_is_mbr_partitioned(const struct cdev *master) +{ + return master && (master->flags & DEVFS_IS_MBR_PARTITIONED); +} -struct cdev *devfs_add_partition(const char *devname, loff_t offset, - loff_t size, unsigned int flags, const char *name); -int devfs_del_partition(const char *name); +static inline bool cdev_is_gpt_partitioned(const struct cdev *master) +{ + return master && (master->flags & DEVFS_IS_GPT_PARTITIONED); +} + +static inline struct cdev * +cdev_find_child_by_gpt_typeuuid(struct cdev *cdev, guid_t *typeuuid) +{ + struct cdev *partcdev; + + if (!cdev_is_gpt_partitioned(cdev)) + return ERR_PTR(-EINVAL); + + for_each_cdev_partition(partcdev, cdev) { + if (guid_equal(&partcdev->typeuuid, typeuuid)) + return partcdev; + } + + return ERR_PTR(-ENOENT); +} #ifdef CONFIG_FS_AUTOMOUNT void cdev_create_default_automount(struct cdev *cdev); @@ -508,6 +687,11 @@ static inline void cdev_create_default_automount(struct cdev *cdev) } #endif +static inline bool cdev_is_mci_main_part_dev(struct cdev *cdev) +{ + return cdev->flags & DEVFS_IS_MCI_MAIN_PART_DEV; +} + #define DEVFS_PARTITION_APPEND 0 /** @@ -541,11 +725,73 @@ struct devfs_partition { int devfs_create_partitions(const char *devname, const struct devfs_partition partinfo[]); -#define DRV_OF_COMPAT(compat) \ +struct cdev *devfs_add_partition(const char *devname, loff_t offset, + loff_t size, unsigned int flags, const char *name); +int devfs_del_partition(const char *name); + +struct cdev *cdevfs_add_partition(struct cdev *cdev, + const struct devfs_partition *partinfo); +int cdevfs_del_partition(struct cdev *cdev); + +#define of_match_ptr(compat) \ IS_ENABLED(CONFIG_OFDEVICE) ? (compat) : NULL -int dev_get_drvdata(struct device_d *dev, const void **data); +#define DRV_OF_COMPAT(compat) of_match_ptr(compat) + +/** + * dev_get_drvdata - get driver match data associated with device + * @dev: device instance + * @data: pointer to void *, where match data is stored + * + * Returns 0 on success and error code otherwise. + * + * DEPRECATED: use device_get_match_data instead, which avoids + * common pitfalls due to explicit pointer casts + */ +int dev_get_drvdata(struct device *dev, const void **data); + +/** + * device_get_match_data - get driver match data associated with device + * @dev: device instance + * + * Returns match data on success and NULL otherwise + */ +const void *device_get_match_data(struct device *dev); + +int device_match_of_modalias(struct device *dev, struct driver *drv); -int device_match_of_modalias(struct device_d *dev, struct driver_d *drv); +struct device *device_find_child(struct device *parent, void *data, + int (*match)(struct device *dev, void *data)); + +static inline struct device_node *dev_of_node(struct device *dev) +{ + return IS_ENABLED(CONFIG_OFDEVICE) ? dev->of_node : NULL; +} + +static inline bool dev_is_dma_coherent(struct device *dev) +{ + if (dev) { + switch (dev->dma_coherent) { + case DEV_DMA_NON_COHERENT: + return false; + case DEV_DMA_COHERENT: + return true; + case DEV_DMA_COHERENCE_DEFAULT: + break; + } + } + + return IS_ENABLED(CONFIG_ARCH_DMA_DEFAULT_COHERENT); +} + +static inline void *dev_get_priv(const struct device *dev) +{ + return dev->priv; +} + +static inline bool dev_is_probed(const struct device *dev) +{ + return dev->driver ? true : false; +} #endif /* DRIVER_H */ |