#include <linux/cpu_pm.h>
#include <linux/irq.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/ioport.h>
#include <linux/spinlock.h>
#include <linux/io.h>
#include <linux/gpio/driver.h>
#include <linux/gpio/consumer.h>
#include <linux/gpio/machine.h>
#include <linux/interrupt.h>
#include <linux/irqdomain.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_device.h>
#include <linux/of_platform.h>
#include <linux/omap-gpmc.h>
#include <linux/pm_runtime.h>
#include <linux/sizes.h>
#include <linux/platform_data/mtd-nand-omap2.h>
#define DEVICE_NAME …
#define GPMC_REVISION …
#define GPMC_SYSCONFIG …
#define GPMC_SYSSTATUS …
#define GPMC_IRQSTATUS …
#define GPMC_IRQENABLE …
#define GPMC_TIMEOUT_CONTROL …
#define GPMC_ERR_ADDRESS …
#define GPMC_ERR_TYPE …
#define GPMC_CONFIG …
#define GPMC_STATUS …
#define GPMC_PREFETCH_CONFIG1 …
#define GPMC_PREFETCH_CONFIG2 …
#define GPMC_PREFETCH_CONTROL …
#define GPMC_PREFETCH_STATUS …
#define GPMC_ECC_CONFIG …
#define GPMC_ECC_CONTROL …
#define GPMC_ECC_SIZE_CONFIG …
#define GPMC_ECC1_RESULT …
#define GPMC_ECC_BCH_RESULT_0 …
#define GPMC_ECC_BCH_RESULT_1 …
#define GPMC_ECC_BCH_RESULT_2 …
#define GPMC_ECC_BCH_RESULT_3 …
#define GPMC_ECC_BCH_RESULT_4 …
#define GPMC_ECC_BCH_RESULT_5 …
#define GPMC_ECC_BCH_RESULT_6 …
#define GPMC_ECC_CTRL_ECCCLEAR …
#define GPMC_ECC_CTRL_ECCDISABLE …
#define GPMC_ECC_CTRL_ECCREG1 …
#define GPMC_ECC_CTRL_ECCREG2 …
#define GPMC_ECC_CTRL_ECCREG3 …
#define GPMC_ECC_CTRL_ECCREG4 …
#define GPMC_ECC_CTRL_ECCREG5 …
#define GPMC_ECC_CTRL_ECCREG6 …
#define GPMC_ECC_CTRL_ECCREG7 …
#define GPMC_ECC_CTRL_ECCREG8 …
#define GPMC_ECC_CTRL_ECCREG9 …
#define GPMC_CONFIG_LIMITEDADDRESS …
#define GPMC_STATUS_EMPTYWRITEBUFFERSTATUS …
#define GPMC_CONFIG2_CSEXTRADELAY …
#define GPMC_CONFIG3_ADVEXTRADELAY …
#define GPMC_CONFIG4_OEEXTRADELAY …
#define GPMC_CONFIG4_WEEXTRADELAY …
#define GPMC_CONFIG6_CYCLE2CYCLEDIFFCSEN …
#define GPMC_CONFIG6_CYCLE2CYCLESAMECSEN …
#define GPMC_CS0_OFFSET …
#define GPMC_CS_SIZE …
#define GPMC_BCH_SIZE …
#define GPMC_MEM_START …
#define GPMC_MEM_END …
#define GPMC_CHUNK_SHIFT …
#define GPMC_SECTION_SHIFT …
#define CS_NUM_SHIFT …
#define ENABLE_PREFETCH …
#define DMA_MPU_MODE …
#define GPMC_REVISION_MAJOR(l) …
#define GPMC_REVISION_MINOR(l) …
#define GPMC_HAS_WR_ACCESS …
#define GPMC_HAS_WR_DATA_MUX_BUS …
#define GPMC_HAS_MUX_AAD …
#define GPMC_NR_WAITPINS …
#define GPMC_CS_CONFIG1 …
#define GPMC_CS_CONFIG2 …
#define GPMC_CS_CONFIG3 …
#define GPMC_CS_CONFIG4 …
#define GPMC_CS_CONFIG5 …
#define GPMC_CS_CONFIG6 …
#define GPMC_CS_CONFIG7 …
#define GPMC_CS_NAND_COMMAND …
#define GPMC_CS_NAND_ADDRESS …
#define GPMC_CS_NAND_DATA …
#define GPMC_CONFIG_RDY_BSY …
#define GPMC_CONFIG_DEV_SIZE …
#define GPMC_CONFIG_DEV_TYPE …
#define GPMC_CONFIG_WAITPINPOLARITY(pin) …
#define GPMC_CONFIG1_WRAPBURST_SUPP …
#define GPMC_CONFIG1_READMULTIPLE_SUPP …
#define GPMC_CONFIG1_READTYPE_ASYNC …
#define GPMC_CONFIG1_READTYPE_SYNC …
#define GPMC_CONFIG1_WRITEMULTIPLE_SUPP …
#define GPMC_CONFIG1_WRITETYPE_ASYNC …
#define GPMC_CONFIG1_WRITETYPE_SYNC …
#define GPMC_CONFIG1_CLKACTIVATIONTIME(val) …
#define GPMC_CONFIG1_CLKACTIVATIONTIME_MAX …
#define GPMC_CONFIG1_PAGE_LEN(val) …
#define GPMC_CONFIG1_ATTACHEDDEVICEPAGELENGTH_MAX …
#define GPMC_CONFIG1_WAIT_READ_MON …
#define GPMC_CONFIG1_WAIT_WRITE_MON …
#define GPMC_CONFIG1_WAIT_MON_TIME(val) …
#define GPMC_CONFIG1_WAITMONITORINGTIME_MAX …
#define GPMC_CONFIG1_WAIT_PIN_SEL(val) …
#define GPMC_CONFIG1_DEVICESIZE(val) …
#define GPMC_CONFIG1_DEVICESIZE_16 …
#define GPMC_CONFIG1_DEVICESIZE_MAX …
#define GPMC_CONFIG1_DEVICETYPE(val) …
#define GPMC_CONFIG1_DEVICETYPE_NOR …
#define GPMC_CONFIG1_MUXTYPE(val) …
#define GPMC_CONFIG1_TIME_PARA_GRAN …
#define GPMC_CONFIG1_FCLK_DIV(val) …
#define GPMC_CONFIG1_FCLK_DIV2 …
#define GPMC_CONFIG1_FCLK_DIV3 …
#define GPMC_CONFIG1_FCLK_DIV4 …
#define GPMC_CONFIG7_CSVALID …
#define GPMC_CONFIG7_BASEADDRESS_MASK …
#define GPMC_CONFIG7_CSVALID_MASK …
#define GPMC_CONFIG7_MASKADDRESS_OFFSET …
#define GPMC_CONFIG7_MASKADDRESS_MASK …
#define GPMC_CONFIG7_MASK …
#define GPMC_DEVICETYPE_NOR …
#define GPMC_DEVICETYPE_NAND …
#define GPMC_CONFIG_WRITEPROTECT …
#define WR_RD_PIN_MONITORING …
#define GPMC_ECC_READ …
#define GPMC_ECC_WRITE …
#define GPMC_ECC_READSYN …
#define GPMC_NR_NAND_IRQS …
enum gpmc_clk_domain { … };
struct gpmc_cs_data { … };
struct gpmc_cs_config { … };
struct omap3_gpmc_regs { … };
struct gpmc_waitpin { … };
struct gpmc_device { … };
static struct irq_domain *gpmc_irq_domain;
static struct resource gpmc_mem_root;
static struct gpmc_cs_data gpmc_cs[GPMC_CS_NUM];
static DEFINE_SPINLOCK(gpmc_mem_lock);
static unsigned int gpmc_cs_num = …;
static unsigned int gpmc_nr_waitpins;
static unsigned int gpmc_capability;
static void __iomem *gpmc_base;
static struct clk *gpmc_l3_clk;
static irqreturn_t gpmc_handle_irq(int irq, void *dev);
static void gpmc_write_reg(int idx, u32 val)
{ … }
static u32 gpmc_read_reg(int idx)
{ … }
void gpmc_cs_write_reg(int cs, int idx, u32 val)
{ … }
static u32 gpmc_cs_read_reg(int cs, int idx)
{ … }
static unsigned long gpmc_get_fclk_period(void)
{ … }
static unsigned long gpmc_get_clk_period(int cs, enum gpmc_clk_domain cd)
{ … }
static unsigned int gpmc_ns_to_clk_ticks(unsigned int time_ns, int cs,
enum gpmc_clk_domain cd)
{ … }
static unsigned int gpmc_ns_to_ticks(unsigned int time_ns)
{ … }
static unsigned int gpmc_ps_to_ticks(unsigned int time_ps)
{ … }
static unsigned int gpmc_clk_ticks_to_ns(unsigned int ticks, int cs,
enum gpmc_clk_domain cd)
{ … }
unsigned int gpmc_ticks_to_ns(unsigned int ticks)
{ … }
static unsigned int gpmc_ticks_to_ps(unsigned int ticks)
{ … }
static unsigned int gpmc_round_ps_to_ticks(unsigned int time_ps)
{ … }
static inline void gpmc_cs_modify_reg(int cs, int reg, u32 mask, bool value)
{ … }
static void gpmc_cs_bool_timings(int cs, const struct gpmc_bool_timings *p)
{ … }
#ifdef CONFIG_OMAP_GPMC_DEBUG
static int get_gpmc_timing_reg(
int cs, int reg, int st_bit, int end_bit, int max,
const char *name, const enum gpmc_clk_domain cd,
int shift,
bool raw, bool noval)
{ … }
#define GPMC_PRINT_CONFIG(cs, config) …
#define GPMC_GET_RAW(reg, st, end, field) …
#define GPMC_GET_RAW_MAX(reg, st, end, max, field) …
#define GPMC_GET_RAW_BOOL(reg, st, end, field) …
#define GPMC_GET_RAW_SHIFT_MAX(reg, st, end, shift, max, field) …
#define GPMC_GET_TICKS(reg, st, end, field) …
#define GPMC_GET_TICKS_CD(reg, st, end, field, cd) …
#define GPMC_GET_TICKS_CD_MAX(reg, st, end, max, field, cd) …
static void gpmc_show_regs(int cs, const char *desc)
{ … }
static void gpmc_cs_show_timings(int cs, const char *desc)
{ … }
#else
static inline void gpmc_cs_show_timings(int cs, const char *desc)
{
}
#endif
static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit, int max,
int time, enum gpmc_clk_domain cd, const char *name)
{ … }
static int gpmc_calc_waitmonitoring_divider(unsigned int wait_monitoring)
{ … }
int gpmc_calc_divider(unsigned int sync_clk)
{ … }
int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t,
const struct gpmc_settings *s)
{ … }
static int gpmc_cs_set_memconf(int cs, u32 base, u32 size)
{ … }
static void gpmc_cs_enable_mem(int cs)
{ … }
static void gpmc_cs_disable_mem(int cs)
{ … }
static void gpmc_cs_get_memconf(int cs, u32 *base, u32 *size)
{ … }
static int gpmc_cs_mem_enabled(int cs)
{ … }
static void gpmc_cs_set_reserved(int cs, int reserved)
{ … }
static bool gpmc_cs_reserved(int cs)
{ … }
static unsigned long gpmc_mem_align(unsigned long size)
{ … }
static int gpmc_cs_insert_mem(int cs, unsigned long base, unsigned long size)
{ … }
static int gpmc_cs_delete_mem(int cs)
{ … }
int gpmc_cs_request(int cs, unsigned long size, unsigned long *base)
{ … }
EXPORT_SYMBOL(…);
void gpmc_cs_free(int cs)
{ … }
EXPORT_SYMBOL(…);
static bool gpmc_is_valid_waitpin(u32 waitpin)
{ … }
static int gpmc_alloc_waitpin(struct gpmc_device *gpmc,
struct gpmc_settings *p)
{ … }
static void gpmc_free_waitpin(struct gpmc_device *gpmc,
int wait_pin)
{ … }
int gpmc_configure(int cmd, int wval)
{ … }
EXPORT_SYMBOL(…);
static bool gpmc_nand_writebuffer_empty(void)
{ … }
static struct gpmc_nand_ops nand_ops = …;
struct gpmc_nand_ops *gpmc_omap_get_nand_ops(struct gpmc_nand_regs *reg, int cs)
{ … }
EXPORT_SYMBOL_GPL(…);
static void gpmc_omap_onenand_calc_sync_timings(struct gpmc_timings *t,
struct gpmc_settings *s,
int freq, int latency)
{ … }
int gpmc_omap_onenand_set_timings(struct device *dev, int cs, int freq,
int latency,
struct gpmc_onenand_info *info)
{ … }
EXPORT_SYMBOL_GPL(…);
int gpmc_get_client_irq(unsigned int irq_config)
{ … }
static int gpmc_irq_endis(unsigned long hwirq, bool endis)
{ … }
static void gpmc_irq_disable(struct irq_data *p)
{ … }
static void gpmc_irq_enable(struct irq_data *p)
{ … }
static void gpmc_irq_mask(struct irq_data *d)
{ … }
static void gpmc_irq_unmask(struct irq_data *d)
{ … }
static void gpmc_irq_edge_config(unsigned long hwirq, bool rising_edge)
{ … }
static void gpmc_irq_ack(struct irq_data *d)
{ … }
static int gpmc_irq_set_type(struct irq_data *d, unsigned int trigger)
{ … }
static int gpmc_irq_map(struct irq_domain *d, unsigned int virq,
irq_hw_number_t hw)
{ … }
static const struct irq_domain_ops gpmc_irq_domain_ops = …;
static irqreturn_t gpmc_handle_irq(int irq, void *data)
{ … }
static int gpmc_setup_irq(struct gpmc_device *gpmc)
{ … }
static int gpmc_free_irq(struct gpmc_device *gpmc)
{ … }
static void gpmc_mem_exit(void)
{ … }
static void gpmc_mem_init(struct gpmc_device *gpmc)
{ … }
static u32 gpmc_round_ps_to_sync_clk(u32 time_ps, u32 sync_clk)
{ … }
static int gpmc_calc_sync_read_timings(struct gpmc_timings *gpmc_t,
struct gpmc_device_timings *dev_t,
bool mux)
{ … }
static int gpmc_calc_sync_write_timings(struct gpmc_timings *gpmc_t,
struct gpmc_device_timings *dev_t,
bool mux)
{ … }
static int gpmc_calc_async_read_timings(struct gpmc_timings *gpmc_t,
struct gpmc_device_timings *dev_t,
bool mux)
{ … }
static int gpmc_calc_async_write_timings(struct gpmc_timings *gpmc_t,
struct gpmc_device_timings *dev_t,
bool mux)
{ … }
static int gpmc_calc_sync_common_timings(struct gpmc_timings *gpmc_t,
struct gpmc_device_timings *dev_t)
{ … }
static int gpmc_calc_common_timings(struct gpmc_timings *gpmc_t,
struct gpmc_device_timings *dev_t,
bool sync)
{ … }
static void gpmc_convert_ps_to_ns(struct gpmc_timings *t)
{ … }
int gpmc_calc_timings(struct gpmc_timings *gpmc_t,
struct gpmc_settings *gpmc_s,
struct gpmc_device_timings *dev_t)
{ … }
int gpmc_cs_program_settings(int cs, struct gpmc_settings *p)
{ … }
#ifdef CONFIG_OF
static void gpmc_cs_set_name(int cs, const char *name)
{ … }
static const char *gpmc_cs_get_name(int cs)
{ … }
static int gpmc_cs_remap(int cs, u32 base)
{ … }
void gpmc_read_settings_dt(struct device_node *np, struct gpmc_settings *p)
{ … }
static void __maybe_unused gpmc_read_timings_dt(struct device_node *np,
struct gpmc_timings *gpmc_t)
{ … }
static int gpmc_probe_generic_child(struct platform_device *pdev,
struct device_node *child)
{ … }
static const struct of_device_id gpmc_dt_ids[];
static int gpmc_probe_dt(struct platform_device *pdev)
{ … }
static void gpmc_probe_dt_children(struct platform_device *pdev)
{ … }
#else
void gpmc_read_settings_dt(struct device_node *np, struct gpmc_settings *p)
{
memset(p, 0, sizeof(*p));
}
static int gpmc_probe_dt(struct platform_device *pdev)
{
return 0;
}
static void gpmc_probe_dt_children(struct platform_device *pdev)
{
}
#endif
static int gpmc_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
{ … }
static int gpmc_gpio_direction_input(struct gpio_chip *chip,
unsigned int offset)
{ … }
static int gpmc_gpio_direction_output(struct gpio_chip *chip,
unsigned int offset, int value)
{ … }
static void gpmc_gpio_set(struct gpio_chip *chip, unsigned int offset,
int value)
{ … }
static int gpmc_gpio_get(struct gpio_chip *chip, unsigned int offset)
{ … }
static int gpmc_gpio_init(struct gpmc_device *gpmc)
{ … }
static void omap3_gpmc_save_context(struct gpmc_device *gpmc)
{ … }
static void omap3_gpmc_restore_context(struct gpmc_device *gpmc)
{ … }
static int omap_gpmc_context_notifier(struct notifier_block *nb,
unsigned long cmd, void *v)
{ … }
static int gpmc_probe(struct platform_device *pdev)
{ … }
static void gpmc_remove(struct platform_device *pdev)
{ … }
#ifdef CONFIG_PM_SLEEP
static int gpmc_suspend(struct device *dev)
{ … }
static int gpmc_resume(struct device *dev)
{ … }
#endif
static SIMPLE_DEV_PM_OPS(gpmc_pm_ops, gpmc_suspend, gpmc_resume);
#ifdef CONFIG_OF
static const struct of_device_id gpmc_dt_ids[] = …;
MODULE_DEVICE_TABLE(of, gpmc_dt_ids);
#endif
static struct platform_driver gpmc_driver = …;
module_platform_driver(…) …;
MODULE_DESCRIPTION(…) …;
MODULE_LICENSE(…) …;