/*
* @file hv_drv_UsbCoreDevice.h
* @brief Header file of usb device.
*
* @author HiView SoC Software Team
* @version 1.0.0
* @date 2022-06-15
*/

#ifndef __HV_DRV_USB_CORE_DEVICE_H
#define __HV_DRV_USB_CORE_DEVICE_H

#include "hv_drv_UsbPortingOsLinuxList.h"
#include "hv_drv_UsbPortingOsLinuxApi.h"

struct device_driver;
struct device;
struct bus_type;



struct device_type {
    const char *name;
    void (*release) (struct device *dev);
};

struct bus_type {
    const char      *name;
    unsigned char   auto_probe;
    /* match device to driver */
    int (*match) (struct device *dev, const struct device_driver *drv);
    struct list_head    bus_drivers;
    struct list_head    bus_devices;
};

struct device_driver {
    const char *name;
    struct bus_type *bus;       /* belongs to which bus type */
    struct list_head bus_drv;   /* a node linked on the bus */
    int (*probe) (struct device *dev);
    int (*remove) (struct device *dev);
};

struct device {
    struct device *parent;
    atomic_t    ref;

    void *priv_data;            /* device private data */
    int priv_len;               /* device private data length */
    struct device_type *type;   /* own device type */
    struct bus_type *bus;       /* belongs to which bus type */
    struct list_head bus_dev;   /* a node linked on the bus */
    struct device_driver *driver;    /* my matched driver */

    void *drvdata;              /* driver data */
};

/* controller side device and driver */
struct platform_device {
    struct device dev;
    void *platform_data;
    void *driver_data;
};
#define to_platform_device(_d)  container_of(_d, struct platform_device, dev)

#define platdev_get_platdata(_pdev) (_pdev->platform_data)

INLINE void platdev_set_platdata(struct platform_device *platdev, void *data) {
    platdev->platform_data = data;
}

INLINE void *dev_get_platdata(struct device *dev) {
    return (to_platform_device(dev))->platform_data;
}

struct platform_driver {
    const char *name;
    int (*probe) (struct platform_device *pdev);
    int (*remove) (struct platform_device *pdev);
    int (*shutdown) (struct platform_device *pdev);
};

INLINE void dev_set_drvdata(struct device *dev, void *data) {
    dev->drvdata = data;
}

INLINE void *dev_get_drvdata(struct device *dev) {
    return dev->drvdata;
}

void device_initialize(struct device *dev);
int bus_register(struct bus_type *bus);
int device_is_registered(struct device *dev);
int device_attach(struct device *dev);
int device_add(struct device *dev);
void device_del(struct device *dev);
int device_register(struct device *dev);
void device_unregister(struct device *dev);
int driver_register(struct device_driver *drv);
void device_release_driver(struct device *dev);
struct device *get_device(struct device *);
void put_device(struct device *);

#endif
