#define DRV_NAME …
#include <linux/bitops.h>
#include <linux/err.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/ioport.h>
#include <linux/kernel.h>
#include <linux/math.h>
#include <linux/of.h>
#include <linux/pinctrl/machine.h>
#include <linux/platform_device.h>
#include <linux/psci.h>
#include <linux/slab.h>
#include <linux/sys_soc.h>
#include "core.h"
static int sh_pfc_map_resources(struct sh_pfc *pfc,
struct platform_device *pdev)
{ … }
static void __iomem *sh_pfc_phys_to_virt(struct sh_pfc *pfc, u32 reg)
{ … }
int sh_pfc_get_pin_index(struct sh_pfc *pfc, unsigned int pin)
{ … }
static int sh_pfc_enum_in_range(u16 enum_id, const struct pinmux_range *r)
{ … }
u32 sh_pfc_read_raw_reg(void __iomem *mapped_reg, unsigned int reg_width)
{ … }
void sh_pfc_write_raw_reg(void __iomem *mapped_reg, unsigned int reg_width,
u32 data)
{ … }
u32 sh_pfc_read(struct sh_pfc *pfc, u32 reg)
{ … }
static void sh_pfc_unlock_reg(struct sh_pfc *pfc, u32 reg, u32 data)
{ … }
void sh_pfc_write(struct sh_pfc *pfc, u32 reg, u32 data)
{ … }
static void sh_pfc_config_reg_helper(struct sh_pfc *pfc,
const struct pinmux_cfg_reg *crp,
unsigned int in_pos,
void __iomem **mapped_regp, u32 *maskp,
unsigned int *posp)
{ … }
static void sh_pfc_write_config_reg(struct sh_pfc *pfc,
const struct pinmux_cfg_reg *crp,
unsigned int field, u32 value)
{ … }
static int sh_pfc_get_config_reg(struct sh_pfc *pfc, u16 enum_id,
const struct pinmux_cfg_reg **crp,
unsigned int *fieldp, u32 *valuep)
{ … }
static int sh_pfc_mark_to_enum(struct sh_pfc *pfc, u16 mark, int pos,
u16 *enum_idp)
{ … }
int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type)
{ … }
static int sh_pfc_init_ranges(struct sh_pfc *pfc)
{ … }
#ifdef CONFIG_OF
static const struct of_device_id sh_pfc_of_table[] = …;
#endif
#if defined(CONFIG_ARM_PSCI_FW)
static void sh_pfc_nop_reg(struct sh_pfc *pfc, u32 reg, unsigned int idx)
{
}
static void sh_pfc_save_reg(struct sh_pfc *pfc, u32 reg, unsigned int idx)
{
pfc->saved_regs[idx] = sh_pfc_read(pfc, reg);
}
static void sh_pfc_restore_reg(struct sh_pfc *pfc, u32 reg, unsigned int idx)
{
sh_pfc_write(pfc, reg, pfc->saved_regs[idx]);
}
static unsigned int sh_pfc_walk_regs(struct sh_pfc *pfc,
void (*do_reg)(struct sh_pfc *pfc, u32 reg, unsigned int idx))
{
unsigned int i, n = 0;
if (pfc->info->cfg_regs)
for (i = 0; pfc->info->cfg_regs[i].reg; i++)
do_reg(pfc, pfc->info->cfg_regs[i].reg, n++);
if (pfc->info->drive_regs)
for (i = 0; pfc->info->drive_regs[i].reg; i++)
do_reg(pfc, pfc->info->drive_regs[i].reg, n++);
if (pfc->info->bias_regs)
for (i = 0; pfc->info->bias_regs[i].puen ||
pfc->info->bias_regs[i].pud; i++) {
if (pfc->info->bias_regs[i].puen)
do_reg(pfc, pfc->info->bias_regs[i].puen, n++);
if (pfc->info->bias_regs[i].pud)
do_reg(pfc, pfc->info->bias_regs[i].pud, n++);
}
if (pfc->info->ioctrl_regs)
for (i = 0; pfc->info->ioctrl_regs[i].reg; i++)
do_reg(pfc, pfc->info->ioctrl_regs[i].reg, n++);
return n;
}
static int sh_pfc_suspend_init(struct sh_pfc *pfc)
{
unsigned int n;
if (!psci_ops.cpu_suspend)
return 0;
n = sh_pfc_walk_regs(pfc, sh_pfc_nop_reg);
if (!n)
return 0;
pfc->saved_regs = devm_kmalloc_array(pfc->dev, n,
sizeof(*pfc->saved_regs),
GFP_KERNEL);
if (!pfc->saved_regs)
return -ENOMEM;
dev_dbg(pfc->dev, "Allocated space to save %u regs\n", n);
return 0;
}
static int sh_pfc_suspend_noirq(struct device *dev)
{
struct sh_pfc *pfc = dev_get_drvdata(dev);
if (pfc->saved_regs)
sh_pfc_walk_regs(pfc, sh_pfc_save_reg);
return 0;
}
static int sh_pfc_resume_noirq(struct device *dev)
{
struct sh_pfc *pfc = dev_get_drvdata(dev);
if (pfc->saved_regs)
sh_pfc_walk_regs(pfc, sh_pfc_restore_reg);
return 0;
}
#define pm_psci_sleep_ptr …
#else
static int sh_pfc_suspend_init(struct sh_pfc *pfc) { … }
static int sh_pfc_suspend_noirq(struct device *dev) { … }
static int sh_pfc_resume_noirq(struct device *dev) { … }
#define pm_psci_sleep_ptr(_ptr) …
#endif
static DEFINE_NOIRQ_DEV_PM_OPS(sh_pfc_pm, sh_pfc_suspend_noirq, sh_pfc_resume_noirq);
#ifdef DEBUG
#define SH_PFC_MAX_REGS …
#define SH_PFC_MAX_ENUMS …
static unsigned int sh_pfc_errors __initdata;
static unsigned int sh_pfc_warnings __initdata;
static bool sh_pfc_bias_done __initdata;
static bool sh_pfc_drive_done __initdata;
static bool sh_pfc_power_done __initdata;
static struct { … } *sh_pfc_regs __initdata;
static u32 sh_pfc_num_regs __initdata;
static u16 *sh_pfc_enums __initdata;
static u32 sh_pfc_num_enums __initdata;
#define sh_pfc_err(fmt, ...) …
#define sh_pfc_err_once(type, fmt, ...) …
#define sh_pfc_warn(fmt, ...) …
static bool __init is0s(const u16 *enum_ids, unsigned int n)
{ … }
static bool __init same_name(const char *a, const char *b)
{ … }
static void __init sh_pfc_check_reg(const char *drvname, u32 reg, u32 bits)
{ … }
static int __init sh_pfc_check_enum(const char *drvname, u16 enum_id)
{ … }
static void __init sh_pfc_check_reg_enums(const char *drvname, u32 reg,
const u16 *enums, unsigned int n)
{ … }
static const struct sh_pfc_pin __init *sh_pfc_find_pin(
const struct sh_pfc_soc_info *info, u32 reg, unsigned int pin)
{ … }
static void __init sh_pfc_check_cfg_reg(const char *drvname,
const struct pinmux_cfg_reg *cfg_reg)
{ … }
static void __init sh_pfc_check_drive_reg(const struct sh_pfc_soc_info *info,
const struct pinmux_drive_reg *drive)
{ … }
static void __init sh_pfc_check_bias_reg(const struct sh_pfc_soc_info *info,
const struct pinmux_bias_reg *bias)
{ … }
static void __init sh_pfc_compare_groups(const char *drvname,
const struct sh_pfc_pin_group *a,
const struct sh_pfc_pin_group *b)
{ … }
static void __init sh_pfc_check_info(const struct sh_pfc_soc_info *info)
{ … }
static void __init sh_pfc_check_driver(const struct platform_driver *pdrv)
{ … }
#else
static inline void sh_pfc_check_driver(struct platform_driver *pdrv) {}
#endif
static int sh_pfc_probe(struct platform_device *pdev)
{ … }
static const struct platform_device_id sh_pfc_id_table[] = …;
static struct platform_driver sh_pfc_driver = …;
static int __init sh_pfc_init(void)
{ … }
postcore_initcall(sh_pfc_init);