mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-23 07:22:33 +00:00
128 lines
2.9 KiB
C
128 lines
2.9 KiB
C
|
/* SPDX-License-Identifier: GPL-2.0 */
|
||
|
/*
|
||
|
* Copyright (C) 2020 MediaTek Inc. All Rights Reserved.
|
||
|
*
|
||
|
* Author: Weijie Gao <weijie.gao@mediatek.com>
|
||
|
*/
|
||
|
|
||
|
#ifndef _MTK_SNAND_OS_H_
|
||
|
#define _MTK_SNAND_OS_H_
|
||
|
|
||
|
#include <linux/slab.h>
|
||
|
#include <linux/kernel.h>
|
||
|
#include <linux/limits.h>
|
||
|
#include <linux/types.h>
|
||
|
#include <linux/bitops.h>
|
||
|
#include <linux/sizes.h>
|
||
|
#include <linux/iopoll.h>
|
||
|
#include <linux/hrtimer.h>
|
||
|
#include <linux/device.h>
|
||
|
#include <linux/dma-mapping.h>
|
||
|
#include <linux/io.h>
|
||
|
#include <asm/div64.h>
|
||
|
|
||
|
struct mtk_snand_plat_dev {
|
||
|
struct device *dev;
|
||
|
struct completion done;
|
||
|
};
|
||
|
|
||
|
/* Polling helpers */
|
||
|
#define read16_poll_timeout(addr, val, cond, sleep_us, timeout_us) \
|
||
|
readw_poll_timeout((addr), (val), (cond), (sleep_us), (timeout_us))
|
||
|
|
||
|
#define read32_poll_timeout(addr, val, cond, sleep_us, timeout_us) \
|
||
|
readl_poll_timeout((addr), (val), (cond), (sleep_us), (timeout_us))
|
||
|
|
||
|
/* Timer helpers */
|
||
|
#define mtk_snand_time_t ktime_t
|
||
|
|
||
|
static inline mtk_snand_time_t timer_get_ticks(void)
|
||
|
{
|
||
|
return ktime_get();
|
||
|
}
|
||
|
|
||
|
static inline mtk_snand_time_t timer_time_to_tick(uint32_t timeout_us)
|
||
|
{
|
||
|
return ktime_add_us(ktime_set(0, 0), timeout_us);
|
||
|
}
|
||
|
|
||
|
static inline bool timer_is_timeout(mtk_snand_time_t start_tick,
|
||
|
mtk_snand_time_t timeout_tick)
|
||
|
{
|
||
|
ktime_t tmo = ktime_add(start_tick, timeout_tick);
|
||
|
|
||
|
return ktime_compare(ktime_get(), tmo) > 0;
|
||
|
}
|
||
|
|
||
|
/* Memory helpers */
|
||
|
static inline void *generic_mem_alloc(struct mtk_snand_plat_dev *pdev,
|
||
|
size_t size)
|
||
|
{
|
||
|
return devm_kzalloc(pdev->dev, size, GFP_KERNEL);
|
||
|
}
|
||
|
static inline void generic_mem_free(struct mtk_snand_plat_dev *pdev, void *ptr)
|
||
|
{
|
||
|
devm_kfree(pdev->dev, ptr);
|
||
|
}
|
||
|
|
||
|
static inline void *dma_mem_alloc(struct mtk_snand_plat_dev *pdev, size_t size)
|
||
|
{
|
||
|
return kzalloc(size, GFP_KERNEL);
|
||
|
}
|
||
|
static inline void dma_mem_free(struct mtk_snand_plat_dev *pdev, void *ptr)
|
||
|
{
|
||
|
kfree(ptr);
|
||
|
}
|
||
|
|
||
|
static inline int dma_mem_map(struct mtk_snand_plat_dev *pdev, void *vaddr,
|
||
|
uintptr_t *dma_addr, size_t size, bool to_device)
|
||
|
{
|
||
|
dma_addr_t addr;
|
||
|
int ret;
|
||
|
|
||
|
addr = dma_map_single(pdev->dev, vaddr, size,
|
||
|
to_device ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
|
||
|
ret = dma_mapping_error(pdev->dev, addr);
|
||
|
if (ret)
|
||
|
return ret;
|
||
|
|
||
|
*dma_addr = (uintptr_t)addr;
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static inline void dma_mem_unmap(struct mtk_snand_plat_dev *pdev,
|
||
|
uintptr_t dma_addr, size_t size,
|
||
|
bool to_device)
|
||
|
{
|
||
|
dma_unmap_single(pdev->dev, dma_addr, size,
|
||
|
to_device ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
|
||
|
}
|
||
|
|
||
|
/* Interrupt helpers */
|
||
|
static inline void irq_completion_done(struct mtk_snand_plat_dev *pdev)
|
||
|
{
|
||
|
complete(&pdev->done);
|
||
|
}
|
||
|
|
||
|
static inline void irq_completion_init(struct mtk_snand_plat_dev *pdev)
|
||
|
{
|
||
|
init_completion(&pdev->done);
|
||
|
}
|
||
|
|
||
|
static inline int irq_completion_wait(struct mtk_snand_plat_dev *pdev,
|
||
|
void __iomem *reg, uint32_t bit,
|
||
|
uint32_t timeout_us)
|
||
|
{
|
||
|
int ret;
|
||
|
|
||
|
ret = wait_for_completion_timeout(&pdev->done,
|
||
|
usecs_to_jiffies(timeout_us));
|
||
|
if (!ret)
|
||
|
return -ETIMEDOUT;
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
#endif /* _MTK_SNAND_OS_H_ */
|