/*
* @file hv_drv_UsbCompat.h
* @brief This file contains some compatibility definitions. 
*        Because the code is ported from uboot, some adaptations have been made here.
*
* @author HiView SoC Software Team
* @version 1.0.0
* @date 2022-06-15
*/

#ifndef __HV_DRV_USB_COMPAT_H_
#define __HV_DRV_USB_COMPAT_H_

#include "hv_drv_UsbDefaultConfig.h"
#include "hv_drv_UsbPortingTypes.h"
#include "hv_drv_UsbDefines.h"
#include "hv_vos_Comm.h"



struct unused {};
typedef struct unused unused_t;

struct p_current{
       int pid;
};


//extern struct p_current *current;

/* avoid conflict with <dm/device.h> */
#ifdef dev_dbg
#undef dev_dbg
#endif
#ifdef dev_vdbg
#undef dev_vdbg
#endif
#ifdef dev_info
#undef dev_info
#endif
#ifdef dev_err
#undef dev_err
#endif
#ifdef dev_warn
#undef dev_warn
#endif


#ifdef USB_DEBUG
#define dev_dbg(dev, fmt, args...)        \
    pr_info(fmt, ##args)
#define dev_vdbg(dev, fmt, args...)        \
    pr_info(fmt, ##args)
#define dev_info(dev, fmt, args...)        \
    pr_info(fmt, ##args)
#define dev_err(dev, fmt, args...)        \
    pr_info(fmt, ##args)
#define dev_warn(dev, fmt, args...)        \
    pr_info(fmt, ##args)

#define debug(fmt, args...)   pr_info(fmt, ##args)
#define ERR(fmt, args...)     pr_info(fmt, ##args)
#else
#define dev_dbg(dev, fmt, args...)        
#define dev_vdbg(dev, fmt, args...)        
#define dev_info(dev, fmt, args...)        
#define dev_err(dev, fmt, args...)        \
    pr_err(fmt, ##args)
#define dev_warn(dev, fmt, args...)        

#define debug(fmt, args...)   
#define ERR(fmt, args...)               \
    pr_err(fmt, ##args)
#endif


#define GFP_ATOMIC ((gfp_t) 0)
#define GFP_KERNEL ((gfp_t) 0)
#define GFP_NOFS ((gfp_t) 0)
#define GFP_USER ((gfp_t) 0)
#define __GFP_NOWARN ((gfp_t) 0)
#define __GFP_ZERO    ((gfp_t)0x8000u)    /* Return zeroed page on success */

#ifndef SIZE_MAX
#define SIZE_MAX    (~(size_t)0)
#endif

static inline void kfree(const void *block)
{
    USB_FREE((void *)block);
}
static inline void vfree(const void *addr)
{
    USB_FREE((void *)addr);
}

struct kmem_cache { int sz; };

struct kmem_cache *get_mem(int element_sz);
#define kmem_cache_create(a, sz, c, d, e)    get_mem(sz)
void *kmem_cache_alloc(struct kmem_cache *obj, int flag);
static inline void kmem_cache_free(struct kmem_cache *cachep, void *obj)
{
    USB_FREE(obj);
}
static inline void kmem_cache_destroy(struct kmem_cache *cachep)
{
    USB_FREE(cachep);
}

#define DECLARE_WAITQUEUE(...)      do { } while (0)
#define add_wait_queue(...)         do { } while (0)
#define remove_wait_queue(...)      do { } while (0)

#define KERNEL_VERSION(a,b,c)    (((a) << 16) + ((b) << 8) + (c))

#define PAGE_SIZE    4096

/* drivers/char/random.c */
#define get_random_bytes(...)

/* include/linux/leds.h */
struct led_trigger {};

#define DEFINE_LED_TRIGGER(x)        static struct led_trigger *x;
enum led_brightness {
    LED_OFF        = 0,
    LED_HALF    = 127,
    LED_FULL    = 255,
};

static inline void led_trigger_register_simple(const char *name,
                    struct led_trigger **trigger) {}
static inline void led_trigger_unregister_simple(struct led_trigger *trigger) {}
static inline void led_trigger_event(struct led_trigger *trigger,
                    enum led_brightness event) {}

/* uapi/linux/limits.h */
#define XATTR_LIST_MAX 65536    /* size of extended attribute namelist (64k) */

/**
 * The type used for indexing onto a disc or disc partition.
 *
 * Linux always considers sectors to be 512 bytes long independently
 * of the devices real block size.
 *
 * blkcnt_t is the type of the inode's block count.
 */
#ifdef CONFIG_LBDAF
typedef u64 sector_t;
typedef u64 blkcnt_t;
#else
#ifdef sector_t
#undef sector_t
typedef unsigned long sector_t;
#endif

#ifdef blkcnt_t
#undef blkcnt_t
typedef unsigned long blkcnt_t;
#endif
#endif

/* module */
#define THIS_MODULE                     0
#define try_module_get(...)             1
#define module_put(...)                 do { } while (0)
#define module_init(...)
#define module_exit(...)
#define EXPORT_SYMBOL(...)
#define EXPORT_SYMBOL_GPL(...)
#define module_param(...)
#define module_param_call(...)
#define MODULE_PARM_DESC(...)
#define MODULE_VERSION(...)
#define MODULE_DESCRIPTION(...)
#define MODULE_AUTHOR(...)
#define MODULE_LICENSE(...)
#define MODULE_ALIAS(...)
#define __module_get(...)

/* character device */
#define MKDEV(...)                      0
#define MAJOR(dev)                      0
#define MINOR(dev)                      0

#define alloc_chrdev_region(...)        0
#define unregister_chrdev_region(...)

#define class_create(...)               __builtin_return_address(0)
#define class_create_file(...)          0
#define class_register(...)             0
#define class_unregister(...)
#define class_remove_file(...)
#define class_destroy(...)
#define misc_register(...)              0
#define misc_deregister(...)

#define __initdata
#define late_initcall(...)

#define dev_set_name(...)               do { } while (0)
#define device_register(...)            0
#define device_unregister(...)
#define volume_sysfs_init(...)          0
#define volume_sysfs_close(...)         do { } while (0)

#define init_waitqueue_head(...)        do { } while (0)
#define wait_event_interruptible(...)   0
#define wake_up_interruptible(...)      do { } while (0)
#define print_hex_dump(...)             do { } while (0)
#define dump_stack(...)                 do { } while (0)

#define task_pid_nr(x)                  0
#define set_freezable(...)              do { } while (0)
#define try_to_freeze(...)              0
#define set_current_state(...)          do { } while (0)
#define kthread_should_stop(...)        0
#define schedule()                      do { } while (0)

#define setup_timer(timer, func, data)  do {} while (0)
#define del_timer_sync(timer)           do {} while (0)
#define schedule_work(work)             do {} while (0)
#define INIT_WORK(work, fun)            do {} while (0)

struct work_struct {};

typedef unused_t spinlock_t;
typedef int    wait_queue_head_t;

#define spin_lock_init(lock)            do {} while (0)
#define spin_lock(lock)                 do {} while (0)
#define spin_unlock(lock)               do {} while (0)
#define spin_lock_irqsave(lock, flags)  do {} while (0)
#define spin_unlock_irqrestore(lock, flags) do { flags = 0; } while (0)

#define DEFINE_MUTEX(...)
#define mutex_init(...)
#define mutex_lock(...)
#define mutex_unlock(...)

#define wake_up(...)

#define init_rwsem(...)            do { } while (0)
#define down_read(...)             do { } while (0)
#define down_write(...)            do { } while (0)
#define down_write_trylock(...)    1
#define up_read(...)               do { } while (0)
#define up_write(...)              do { } while (0)

#define cond_resched()             do { } while (0)
#define yield()                    do { } while (0)

#define __init
#define __exit
#define __devinit
#define __devinitconst

#define kthread_create(...)         __builtin_return_address(0)
#define kthread_stop(...)           do { } while (0)
#define wake_up_process(...)        do { } while (0)

struct rw_semaphore { int i; };
#define down_write(...)            do { } while (0)
#define up_write(...)              do { } while (0)
#define down_read(...)             do { } while (0)
#define up_read(...)               do { } while (0)
struct device {
    struct device        *parent;
    struct class         *class;
    dev_t                devt;    /* dev_t, creates the sysfs "dev" */
    void                 (*release)(struct device *dev);
    /* This is used from drivers/usb/musb-new subsystem only */
    void                 *driver_data;    /* data private to the driver */
    void            *device_data;   /* data private to the device */
};
struct mutex { int i; };
struct kernel_param { int i; };

struct cdev {
    int owner;
    dev_t dev;
};
#define cdev_init(...)          do { } while (0)
#define cdev_add(...)           0
#define cdev_del(...)           do { } while (0)

#define prandom_u32(...)        0

typedef struct {
    uid_t val;
} kuid_t;

typedef struct {
    gid_t val;
} kgid_t;

/* from include/linux/types.h */

/**
 * struct callback_head - callback structure for use with RCU and task_work
 * @next: next update requests in a list
 * @func: actual update function to call after the grace period.
 */
struct callback_head {
    struct callback_head *next;
    void (*func)(struct callback_head *head);
};
#define rcu_head callback_head
enum writeback_sync_modes {
    WB_SYNC_NONE,    /* Don't wait on anything */
    WB_SYNC_ALL,    /* Wait on every mapping */
};

/* from include/linux/writeback.h */
/*
 * A control structure which tells the writeback code what to do.  These are
 * always on the stack, and hence need no locking.  They are always initialised
 * in a manner such that unspecified fields are set to zero.
 */
struct writeback_control {
    long nr_to_write;        /* Write this many pages, and decrement
                       this for each page written */
    long pages_skipped;        /* Pages which were not written */

    /*
     * For a_ops->writepages(): if start or end are non-zero then this is
     * a hint that the filesystem need only write out the pages inside that
     * byterange.  The byte at `end' is included in the writeout request.
     */
    loff_t range_start;
    loff_t range_end;

    enum writeback_sync_modes sync_mode;

    unsigned for_kupdate:1;        /* A kupdate writeback */
    unsigned for_background:1;    /* A background writeback */
    unsigned tagged_writepages:1;    /* tag-and-write to avoid livelock */
    unsigned for_reclaim:1;        /* Invoked from the page allocator */
    unsigned range_cyclic:1;    /* range_start is cyclic */
    unsigned for_sync:1;        /* sync(2) WB_SYNC_ALL writeback */
};


typedef int irqreturn_t;

typedef unsigned long dmaaddr_t;

#define pm_runtime_get_sync(dev) do {} while (0)
#define pm_runtime_put(dev) do {} while (0)
#define pm_runtime_put_sync(dev) do {} while (0)
#define pm_runtime_use_autosuspend(dev) do {} while (0)
#define pm_runtime_set_autosuspend_delay(dev, delay) do {} while (0)
#define pm_runtime_enable(dev) do {} while (0)

#define IRQ_NONE        0
#define IRQ_HANDLED     1
#define IRQ_WAKE_THREAD 2

#define dev_set_drvdata(dev, data) do {} while (0)

#define disable_irq_wake(irq) do {} while (0)
#define enable_irq_wake(irq) -EINVAL
#define free_irq(irq, data) do {} while (0)
#define request_irq(nr, f, flags, nm, data) 0


#define __constant_cpu_to_le16(x) ((__le16)(__u16)(x))

#define cpu_relax() do {} while (0)


/// mark as unused for prevent compiler warning
#ifndef USB_UNUSED
#define USB_UNUSED(var) (void)(var)
#endif


////linux/bug.h

#define BUG() do { \
    pr_info("BUG at :%d/%s()!\n",  __LINE__, __func__); \
} while (0)

#define BUG_ON(condition) do { if (condition) BUG(); } while (0)

#define WARN_ON(condition) ({                        \
    if (condition == 1)                    \
        pr_info("WARNING at :%d/%s()!\n",  __LINE__, __func__); \
})


/*
 * You can initialize platform's USB host or device
 * ports by passing this enum as an argument to
 * board_usb_init().
 */
enum usb_init_type {
    USB_INIT_HOST,
    USB_INIT_DEVICE
};


int usb_lowlevel_init(int index, enum usb_init_type init, void **controller);
int usb_lowlevel_stop(int index);

/*
 * board-specific hardware initialization, called by
 * usb drivers and u-boot commands
 *
 * @param index USB controller number
 * @param init initializes controller as USB host or device
 */
int board_usb_init(int index, enum usb_init_type init);

/*
 * can be used to clean up after failed USB initialization attempt
 * vide: board_usb_init()
 *
 * @param index USB controller number for selective cleanup
 * @param init usb_init_type passed to board_usb_init()
 */
int board_usb_cleanup(int index, enum usb_init_type init);



////include\linux\unaligned\le_byteshift.h
static inline void __put_unaligned_le16(u16 val, u8 *p)
{
    *p++ = val;
    *p++ = val >> 8;
}

static inline void put_unaligned_le16(u16 val, void *p)
{
    __put_unaligned_le16(val, p);
}

unsigned long simple_strtoul(const char *cp, char **endp,
                unsigned int base);

static inline void *kmemdup(const void *src, size_t len)
{
    void *p;

    p = USB_MALLOC(len);
    if (p)
        USB_MEMCPY(p, src, len);
    return p;
}


#define WARN(condition, fmt, args...) ({    \
    int ret_warn = !!condition;        \
    if (ret_warn)                \
        pr_info(fmt, ##args);        \
    ret_warn; })

#define device_init_wakeup(dev, a) do {} while (0)

#define platform_data device_data

#ifndef wmb
#define wmb()        asm volatile (""   : : : "memory")
#endif

#define msleep(a)    udelay(a * 1000)

/*
 * Map U-Boot config options to Linux ones
 */

#define __set_bit generic_set_bit

#ifndef max_usb
#define max_usb(a, b) (((a) > (b)) ? (a) : (b))
#endif
#ifndef min_usb
#define min_usb(a, b) (((a) < (b)) ? (a) : (b))
#endif


#define min_t_usb(type, x, y) ({      \
    type __min1 = (x);            \
    type __min2 = (y);            \
    __min1 < __min2 ? __min1: __min2; })

#define max_t_usb(type, x, y) ({      \
    type __max1 = (x);            \
    type __max2 = (y);            \
    __max1 > __max2 ? __max1: __max2; })

static inline int ffs_me(int x)
{
    int r = 1;

    if (!x)
        return 0;
    if (!(x & 0xffff)) {
        x >>= 16;
        r += 16;
    }
    if (!(x & 0xff)) {
        x >>= 8;
        r += 8;
    }
    if (!(x & 0xf)) {
        x >>= 4;
        r += 4;
    }
    if (!(x & 3)) {
        x >>= 2;
        r += 2;
    }
    if (!(x & 1)) {
        x >>= 1;
        r += 1;
    }
    return r;
}

struct file{
  void* private_data;
  unsigned int f_flags;
};

struct inode{
};


#endif
