summaryrefslogtreecommitdiff
path: root/drivers/pinctrl/renesas/core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pinctrl/renesas/core.c')
-rw-r--r--drivers/pinctrl/renesas/core.c356
1 files changed, 266 insertions, 90 deletions
diff --git a/drivers/pinctrl/renesas/core.c b/drivers/pinctrl/renesas/core.c
index 0d4ea2e22a53..96d6040a8871 100644
--- a/drivers/pinctrl/renesas/core.c
+++ b/drivers/pinctrl/renesas/core.c
@@ -13,12 +13,12 @@
#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/init.h>
+#include <linux/math.h>
#include <linux/of.h>
-#include <linux/of_device.h>
#include <linux/pinctrl/machine.h>
#include <linux/platform_device.h>
#include <linux/psci.h>
@@ -71,12 +71,11 @@ static int sh_pfc_map_resources(struct sh_pfc *pfc,
/* Fill them. */
for (i = 0; i < num_windows; i++) {
- res = platform_get_resource(pdev, IORESOURCE_MEM, i);
- windows->phys = res->start;
- windows->size = resource_size(res);
- windows->virt = devm_ioremap_resource(pfc->dev, res);
+ windows->virt = devm_platform_get_and_ioremap_resource(pdev, i, &res);
if (IS_ERR(windows->virt))
return -ENOMEM;
+ windows->phys = res->start;
+ windows->size = resource_size(res);
windows++;
}
for (i = 0; i < num_irqs; i++)
@@ -214,7 +213,7 @@ static void sh_pfc_config_reg_helper(struct sh_pfc *pfc,
*maskp = (1 << crp->var_field_width[in_pos]) - 1;
*posp = crp->reg_width;
for (k = 0; k <= in_pos; k++)
- *posp -= crp->var_field_width[k];
+ *posp -= abs(crp->var_field_width[k]);
}
}
@@ -262,14 +261,17 @@ static int sh_pfc_get_config_reg(struct sh_pfc *pfc, u16 enum_id,
if (!r_width)
break;
- for (bit_pos = 0; bit_pos < r_width; bit_pos += curr_width) {
+ for (bit_pos = 0; bit_pos < r_width; bit_pos += curr_width, m++) {
u32 ncomb;
u32 n;
- if (f_width)
+ if (f_width) {
curr_width = f_width;
- else
- curr_width = config_reg->var_field_width[m];
+ } else {
+ curr_width = abs(config_reg->var_field_width[m]);
+ if (config_reg->var_field_width[m] < 0)
+ continue;
+ }
ncomb = 1 << curr_width;
for (n = 0; n < ncomb; n++) {
@@ -281,7 +283,6 @@ static int sh_pfc_get_config_reg(struct sh_pfc *pfc, u16 enum_id,
}
}
pos += ncomb;
- m++;
}
k++;
}
@@ -571,23 +572,12 @@ static const struct of_device_id sh_pfc_of_table[] = {
.data = &r8a7794_pinmux_info,
},
#endif
-/*
- * Both r8a7795 entries must be present to make sanity checks work, but only
- * the first entry is actually used.
- * R-Car H3 ES1.x is matched using soc_device_match() instead.
- */
#ifdef CONFIG_PINCTRL_PFC_R8A77951
{
.compatible = "renesas,pfc-r8a7795",
.data = &r8a77951_pinmux_info,
},
#endif
-#ifdef CONFIG_PINCTRL_PFC_R8A77950
- {
- .compatible = "renesas,pfc-r8a7795",
- .data = &r8a77950_pinmux_info,
- },
-#endif
#ifdef CONFIG_PINCTRL_PFC_R8A77960
{
.compatible = "renesas,pfc-r8a7796",
@@ -636,17 +626,35 @@ static const struct of_device_id sh_pfc_of_table[] = {
.data = &r8a779a0_pinmux_info,
},
#endif
+#ifdef CONFIG_PINCTRL_PFC_R8A779F0
+ {
+ .compatible = "renesas,pfc-r8a779f0",
+ .data = &r8a779f0_pinmux_info,
+ },
+#endif
+#ifdef CONFIG_PINCTRL_PFC_R8A779G0
+ {
+ .compatible = "renesas,pfc-r8a779g0",
+ .data = &r8a779g0_pinmux_info,
+ },
+#endif
+#ifdef CONFIG_PINCTRL_PFC_R8A779H0
+ {
+ .compatible = "renesas,pfc-r8a779h0",
+ .data = &r8a779h0_pinmux_info,
+ },
+#endif
#ifdef CONFIG_PINCTRL_PFC_SH73A0
{
.compatible = "renesas,pfc-sh73a0",
.data = &sh73a0_pinmux_info,
},
#endif
- { },
+ { /* sentinel */ }
};
#endif
-#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_ARM_PSCI_FW)
+#if defined(CONFIG_ARM_PSCI_FW)
static void sh_pfc_nop_reg(struct sh_pfc *pfc, u32 reg, unsigned int idx)
{
}
@@ -729,22 +737,25 @@ static int sh_pfc_resume_noirq(struct device *dev)
sh_pfc_walk_regs(pfc, sh_pfc_restore_reg);
return 0;
}
-
-static const struct dev_pm_ops sh_pfc_pm = {
- SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(sh_pfc_suspend_noirq, sh_pfc_resume_noirq)
-};
-#define DEV_PM_OPS &sh_pfc_pm
+#define pm_psci_sleep_ptr(_ptr) pm_sleep_ptr(_ptr)
#else
static int sh_pfc_suspend_init(struct sh_pfc *pfc) { return 0; }
-#define DEV_PM_OPS NULL
-#endif /* CONFIG_PM_SLEEP && CONFIG_ARM_PSCI_FW */
+static int sh_pfc_suspend_noirq(struct device *dev) { return 0; }
+static int sh_pfc_resume_noirq(struct device *dev) { return 0; }
+#define pm_psci_sleep_ptr(_ptr) PTR_IF(false, (_ptr))
+#endif /* CONFIG_ARM_PSCI_FW */
+
+static DEFINE_NOIRQ_DEV_PM_OPS(sh_pfc_pm, sh_pfc_suspend_noirq, sh_pfc_resume_noirq);
#ifdef DEBUG
#define SH_PFC_MAX_REGS 300
-#define SH_PFC_MAX_ENUMS 3000
+#define SH_PFC_MAX_ENUMS 5000
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 {
u32 reg;
u32 bits;
@@ -758,6 +769,15 @@ static u32 sh_pfc_num_enums __initdata;
pr_err("%s: " fmt, drvname, ##__VA_ARGS__); \
sh_pfc_errors++; \
} while (0)
+
+#define sh_pfc_err_once(type, fmt, ...) \
+ do { \
+ if (!sh_pfc_ ## type ## _done) { \
+ sh_pfc_ ## type ## _done = true; \
+ sh_pfc_err(fmt, ##__VA_ARGS__); \
+ } \
+ } while (0)
+
#define sh_pfc_warn(fmt, ...) \
do { \
pr_warn("%s: " fmt, drvname, ##__VA_ARGS__); \
@@ -777,10 +797,7 @@ static bool __init is0s(const u16 *enum_ids, unsigned int n)
static bool __init same_name(const char *a, const char *b)
{
- if (!a || !b)
- return false;
-
- return !strcmp(a, b);
+ return a && b && !strcmp(a, b);
}
static void __init sh_pfc_check_reg(const char *drvname, u32 reg, u32 bits)
@@ -839,52 +856,70 @@ static void __init sh_pfc_check_reg_enums(const char *drvname, u32 reg,
}
}
-static void __init sh_pfc_check_pin(const struct sh_pfc_soc_info *info,
- u32 reg, unsigned int pin)
+static const struct sh_pfc_pin __init *sh_pfc_find_pin(
+ const struct sh_pfc_soc_info *info, u32 reg, unsigned int pin)
{
const char *drvname = info->name;
unsigned int i;
if (pin == SH_PFC_PIN_NONE)
- return;
+ return NULL;
for (i = 0; i < info->nr_pins; i++) {
if (pin == info->pins[i].pin)
- return;
+ return &info->pins[i];
}
sh_pfc_err("reg 0x%x: pin %u not found\n", reg, pin);
+ return NULL;
}
static void __init sh_pfc_check_cfg_reg(const char *drvname,
const struct pinmux_cfg_reg *cfg_reg)
{
- unsigned int i, n, rw, fw;
+ unsigned int i, n, rw, r;
+ int fw;
sh_pfc_check_reg(drvname, cfg_reg->reg,
GENMASK(cfg_reg->reg_width - 1, 0));
if (cfg_reg->field_width) {
- n = cfg_reg->reg_width / cfg_reg->field_width;
+ fw = cfg_reg->field_width;
+ n = (cfg_reg->reg_width / fw) << fw;
+ for (i = 0, r = 0; i < n; i += 1 << fw) {
+ if (is0s(&cfg_reg->enum_ids[i], 1 << fw))
+ r++;
+ }
+
+ if ((r << fw) * sizeof(u16) > cfg_reg->reg_width / fw)
+ sh_pfc_warn("reg 0x%x can be described with variable-width reserved fields\n",
+ cfg_reg->reg);
+
/* Skip field checks (done at build time) */
goto check_enum_ids;
}
for (i = 0, n = 0, rw = 0; (fw = cfg_reg->var_field_width[i]); i++) {
- if (fw > 3 && is0s(&cfg_reg->enum_ids[n], 1 << fw))
- sh_pfc_warn("reg 0x%x: reserved field [%u:%u] can be split to reduce table size\n",
- cfg_reg->reg, rw, rw + fw - 1);
- n += 1 << fw;
- rw += fw;
+ if (fw < 0) {
+ rw += -fw;
+ } else {
+ if (is0s(&cfg_reg->enum_ids[n], 1 << fw))
+ sh_pfc_warn("reg 0x%x: field [%u:%u] can be described as reserved\n",
+ cfg_reg->reg, rw, rw + fw - 1);
+ n += 1 << fw;
+ rw += fw;
+ }
}
if (rw != cfg_reg->reg_width)
sh_pfc_err("reg 0x%x: var_field_width declares %u instead of %u bits\n",
cfg_reg->reg, rw, cfg_reg->reg_width);
- if (n != cfg_reg->nr_enum_ids)
+ if (n != cfg_reg->nr_enum_ids) {
sh_pfc_err("reg 0x%x: enum_ids[] has %u instead of %u values\n",
cfg_reg->reg, cfg_reg->nr_enum_ids, n);
+ n = cfg_reg->nr_enum_ids;
+ }
check_enum_ids:
sh_pfc_check_reg_enums(drvname, cfg_reg->reg, cfg_reg->enum_ids, n);
@@ -893,6 +928,8 @@ check_enum_ids:
static void __init sh_pfc_check_drive_reg(const struct sh_pfc_soc_info *info,
const struct pinmux_drive_reg *drive)
{
+ const char *drvname = info->name;
+ const struct sh_pfc_pin *pin;
unsigned int i;
for (i = 0; i < ARRAY_SIZE(drive->fields); i++) {
@@ -905,13 +942,18 @@ static void __init sh_pfc_check_drive_reg(const struct sh_pfc_soc_info *info,
GENMASK(field->offset + field->size - 1,
field->offset));
- sh_pfc_check_pin(info, drive->reg, field->pin);
+ pin = sh_pfc_find_pin(info, drive->reg, field->pin);
+ if (pin && !(pin->configs & SH_PFC_PIN_CFG_DRIVE_STRENGTH))
+ sh_pfc_err("drive_reg 0x%x: field %u: pin %s lacks SH_PFC_PIN_CFG_DRIVE_STRENGTH flag\n",
+ drive->reg, i, pin->name);
}
}
static void __init sh_pfc_check_bias_reg(const struct sh_pfc_soc_info *info,
const struct pinmux_bias_reg *bias)
{
+ const char *drvname = info->name;
+ const struct sh_pfc_pin *pin;
unsigned int i;
u32 bits;
@@ -923,13 +965,78 @@ static void __init sh_pfc_check_bias_reg(const struct sh_pfc_soc_info *info,
sh_pfc_check_reg(info->name, bias->puen, bits);
if (bias->pud)
sh_pfc_check_reg(info->name, bias->pud, bits);
- for (i = 0; i < ARRAY_SIZE(bias->pins); i++)
- sh_pfc_check_pin(info, bias->puen, bias->pins[i]);
+ for (i = 0; i < ARRAY_SIZE(bias->pins); i++) {
+ pin = sh_pfc_find_pin(info, bias->puen, bias->pins[i]);
+ if (!pin)
+ continue;
+
+ if (bias->puen && bias->pud) {
+ /*
+ * Pull-enable and pull-up/down control registers
+ * As some SoCs have pins that support only pull-up
+ * or pull-down, we just check for one of them
+ */
+ if (!(pin->configs & SH_PFC_PIN_CFG_PULL_UP_DOWN))
+ sh_pfc_err("bias_reg 0x%x:%u: pin %s lacks one or more SH_PFC_PIN_CFG_PULL_* flags\n",
+ bias->puen, i, pin->name);
+ } else if (bias->puen) {
+ /* Pull-up control register only */
+ if (!(pin->configs & SH_PFC_PIN_CFG_PULL_UP))
+ sh_pfc_err("bias_reg 0x%x:%u: pin %s lacks SH_PFC_PIN_CFG_PULL_UP flag\n",
+ bias->puen, i, pin->name);
+ } else if (bias->pud) {
+ /* Pull-down control register only */
+ if (!(pin->configs & SH_PFC_PIN_CFG_PULL_DOWN))
+ sh_pfc_err("bias_reg 0x%x:%u: pin %s lacks SH_PFC_PIN_CFG_PULL_DOWN flag\n",
+ bias->pud, i, pin->name);
+ }
+ }
+}
+
+static void __init sh_pfc_compare_groups(const char *drvname,
+ const struct sh_pfc_pin_group *a,
+ const struct sh_pfc_pin_group *b)
+{
+ unsigned int i;
+ size_t len;
+
+ if (same_name(a->name, b->name))
+ sh_pfc_err("group %s: name conflict\n", a->name);
+
+ if (a->nr_pins > b->nr_pins)
+ swap(a, b);
+
+ len = a->nr_pins * sizeof(a->pins[0]);
+ for (i = 0; i <= b->nr_pins - a->nr_pins; i++) {
+ if (a->pins == b->pins + i || a->mux == b->mux + i ||
+ memcmp(a->pins, b->pins + i, len) ||
+ memcmp(a->mux, b->mux + i, len))
+ continue;
+
+ if (a->nr_pins == b->nr_pins)
+ sh_pfc_warn("group %s can be an alias for %s\n",
+ a->name, b->name);
+ else
+ sh_pfc_warn("group %s is a subset of %s\n", a->name,
+ b->name);
+ }
}
static void __init sh_pfc_check_info(const struct sh_pfc_soc_info *info)
{
+ const struct pinmux_drive_reg *drive_regs = info->drive_regs;
+#define drive_nfields ARRAY_SIZE(drive_regs->fields)
+#define drive_ofs(i) drive_regs[(i) / drive_nfields]
+#define drive_reg(i) drive_ofs(i).reg
+#define drive_bit(i) ((i) % drive_nfields)
+#define drive_field(i) drive_ofs(i).fields[drive_bit(i)]
const struct pinmux_bias_reg *bias_regs = info->bias_regs;
+#define bias_npins ARRAY_SIZE(bias_regs->pins)
+#define bias_ofs(i) bias_regs[(i) / bias_npins]
+#define bias_puen(i) bias_ofs(i).puen
+#define bias_pud(i) bias_ofs(i).pud
+#define bias_bit(i) ((i) % bias_npins)
+#define bias_pin(i) bias_ofs(i).pins[bias_bit(i)]
const char *drvname = info->name;
unsigned int *refcnts;
unsigned int i, j, k;
@@ -937,10 +1044,14 @@ static void __init sh_pfc_check_info(const struct sh_pfc_soc_info *info)
pr_info("sh_pfc: Checking %s\n", drvname);
sh_pfc_num_regs = 0;
sh_pfc_num_enums = 0;
+ sh_pfc_bias_done = false;
+ sh_pfc_drive_done = false;
+ sh_pfc_power_done = false;
/* Check pins */
for (i = 0; i < info->nr_pins; i++) {
const struct sh_pfc_pin *pin = &info->pins[i];
+ unsigned int x;
if (!pin->name) {
sh_pfc_err("empty pin %u\n", i);
@@ -962,6 +1073,65 @@ static void __init sh_pfc_check_info(const struct sh_pfc_soc_info *info)
pin->name, pin2->name,
pin->enum_id);
}
+
+ if (pin->configs & SH_PFC_PIN_CFG_PULL_UP_DOWN) {
+ if (!info->ops || !info->ops->get_bias ||
+ !info->ops->set_bias)
+ sh_pfc_err_once(bias, "SH_PFC_PIN_CFG_PULL_* flag set but .[gs]et_bias() not implemented\n");
+
+ if (!bias_regs &&
+ (!info->ops || !info->ops->pin_to_portcr))
+ sh_pfc_err_once(bias, "SH_PFC_PIN_CFG_PULL_UP flag set but no bias_regs defined and .pin_to_portcr() not implemented\n");
+ }
+
+ if ((pin->configs & SH_PFC_PIN_CFG_PULL_UP_DOWN) && bias_regs) {
+ const struct pinmux_bias_reg *bias_reg =
+ rcar_pin_to_bias_reg(info, pin->pin, &x);
+
+ if (!bias_reg ||
+ ((pin->configs & SH_PFC_PIN_CFG_PULL_UP) &&
+ !bias_reg->puen))
+ sh_pfc_err("pin %s: SH_PFC_PIN_CFG_PULL_UP flag set but pin not in bias_regs\n",
+ pin->name);
+
+ if (!bias_reg ||
+ ((pin->configs & SH_PFC_PIN_CFG_PULL_DOWN) &&
+ !bias_reg->pud))
+ sh_pfc_err("pin %s: SH_PFC_PIN_CFG_PULL_DOWN flag set but pin not in bias_regs\n",
+ pin->name);
+ }
+
+ if (pin->configs & SH_PFC_PIN_CFG_DRIVE_STRENGTH) {
+ if (!drive_regs) {
+ sh_pfc_err_once(drive, "SH_PFC_PIN_CFG_DRIVE_STRENGTH flag set but drive_regs missing\n");
+ } else {
+ for (j = 0; drive_reg(j); j++) {
+ if (!drive_field(j).pin &&
+ !drive_field(j).offset &&
+ !drive_field(j).size)
+ continue;
+
+ if (drive_field(j).pin == pin->pin)
+ break;
+ }
+
+ if (!drive_reg(j))
+ sh_pfc_err("pin %s: SH_PFC_PIN_CFG_DRIVE_STRENGTH flag set but not in drive_regs\n",
+ pin->name);
+ }
+ }
+
+ if (pin->configs & SH_PFC_PIN_CFG_IO_VOLTAGE_MASK) {
+ if (!info->ops || !info->ops->pin_to_pocctrl)
+ sh_pfc_err_once(power, "SH_PFC_PIN_CFG_IO_VOLTAGE set but .pin_to_pocctrl() not implemented\n");
+ else if (info->ops->pin_to_pocctrl(pin->pin, &x) < 0)
+ sh_pfc_err("pin %s: SH_PFC_PIN_CFG_IO_VOLTAGE set but invalid pin_to_pocctrl()\n",
+ pin->name);
+ } else if (info->ops && info->ops->pin_to_pocctrl &&
+ info->ops->pin_to_pocctrl(pin->pin, &x) >= 0) {
+ sh_pfc_warn("pin %s: SH_PFC_PIN_CFG_IO_VOLTAGE not set but valid pin_to_pocctrl()\n",
+ pin->name);
+ }
}
/* Check groups and functions */
@@ -1003,11 +1173,9 @@ static void __init sh_pfc_check_info(const struct sh_pfc_soc_info *info)
sh_pfc_err("empty group %u\n", i);
continue;
}
- for (j = 0; j < i; j++) {
- if (same_name(group->name, info->groups[j].name))
- sh_pfc_err("group %s: name conflict\n",
- group->name);
- }
+ for (j = 0; j < i; j++)
+ sh_pfc_compare_groups(drvname, group, &info->groups[j]);
+
if (!refcnts[i])
sh_pfc_err("orphan group %s\n", group->name);
else if (refcnts[i] > 1)
@@ -1022,13 +1190,47 @@ static void __init sh_pfc_check_info(const struct sh_pfc_soc_info *info)
sh_pfc_check_cfg_reg(drvname, &info->cfg_regs[i]);
/* Check drive strength registers */
- for (i = 0; info->drive_regs && info->drive_regs[i].reg; i++)
- sh_pfc_check_drive_reg(info, &info->drive_regs[i]);
+ for (i = 0; drive_regs && drive_regs[i].reg; i++)
+ sh_pfc_check_drive_reg(info, &drive_regs[i]);
+
+ for (i = 0; drive_regs && drive_reg(i); i++) {
+ if (!drive_field(i).pin && !drive_field(i).offset &&
+ !drive_field(i).size)
+ continue;
+
+ for (j = 0; j < i; j++) {
+ if (drive_field(i).pin == drive_field(j).pin &&
+ drive_field(j).offset && drive_field(j).size) {
+ sh_pfc_err("drive_reg 0x%x:%zu/0x%x:%zu: pin conflict\n",
+ drive_reg(i), drive_bit(i),
+ drive_reg(j), drive_bit(j));
+ }
+ }
+ }
/* Check bias registers */
for (i = 0; bias_regs && (bias_regs[i].puen || bias_regs[i].pud); i++)
sh_pfc_check_bias_reg(info, &bias_regs[i]);
+ for (i = 0; bias_regs && (bias_puen(i) || bias_pud(i)); i++) {
+ if (bias_pin(i) == SH_PFC_PIN_NONE)
+ continue;
+
+ for (j = 0; j < i; j++) {
+ if (bias_pin(i) != bias_pin(j))
+ continue;
+
+ if (bias_puen(i) && bias_puen(j))
+ sh_pfc_err("bias_reg 0x%x:%zu/0x%x:%zu: pin conflict\n",
+ bias_puen(i), bias_bit(i),
+ bias_puen(j), bias_bit(j));
+ if (bias_pud(i) && bias_pud(j))
+ sh_pfc_err("bias_reg 0x%x:%zu/0x%x:%zu: pin conflict\n",
+ bias_pud(i), bias_bit(i),
+ bias_pud(j), bias_bit(j));
+ }
+ }
+
/* Check ioctrl registers */
for (i = 0; info->ioctrl_regs && info->ioctrl_regs[i].reg; i++)
sh_pfc_check_reg(drvname, info->ioctrl_regs[i].reg, U32_MAX);
@@ -1103,41 +1305,15 @@ free_regs:
static inline void sh_pfc_check_driver(struct platform_driver *pdrv) {}
#endif /* !DEBUG */
-#ifdef CONFIG_OF
-static const void *sh_pfc_quirk_match(void)
-{
-#ifdef CONFIG_PINCTRL_PFC_R8A77950
- const struct soc_device_attribute *match;
- static const struct soc_device_attribute quirks[] = {
- {
- .soc_id = "r8a7795", .revision = "ES1.*",
- .data = &r8a77950_pinmux_info,
- },
- { /* sentinel */ }
- };
-
- match = soc_device_match(quirks);
- if (match)
- return match->data;
-#endif /* CONFIG_PINCTRL_PFC_R8A77950 */
-
- return NULL;
-}
-#endif /* CONFIG_OF */
-
static int sh_pfc_probe(struct platform_device *pdev)
{
const struct sh_pfc_soc_info *info;
struct sh_pfc *pfc;
int ret;
-#ifdef CONFIG_OF
- if (pdev->dev.of_node) {
- info = sh_pfc_quirk_match();
- if (!info)
- info = of_device_get_match_data(&pdev->dev);
- } else
-#endif
+ if (pdev->dev.of_node)
+ info = of_device_get_match_data(&pdev->dev);
+ else
info = (const void *)platform_get_device_id(pdev)->driver_data;
pfc = devm_kzalloc(&pdev->dev, sizeof(*pfc), GFP_KERNEL);
@@ -1240,7 +1416,7 @@ static const struct platform_device_id sh_pfc_id_table[] = {
#ifdef CONFIG_PINCTRL_PFC_SHX3
{ "pfc-shx3", (kernel_ulong_t)&shx3_pinmux_info },
#endif
- { },
+ { /* sentinel */ }
};
static struct platform_driver sh_pfc_driver = {
@@ -1249,7 +1425,7 @@ static struct platform_driver sh_pfc_driver = {
.driver = {
.name = DRV_NAME,
.of_match_table = of_match_ptr(sh_pfc_of_table),
- .pm = DEV_PM_OPS,
+ .pm = pm_psci_sleep_ptr(&sh_pfc_pm),
},
};