提交 8bf3c244 编写于 作者: T Tom Rini

Merge tag 'for-master-20181210' of git://git.denx.de/u-boot-rockchip

Improvements:
- init DRAM for RK322x in SPL
- add FAN53555 PMIC/regulator driver
- update MicroCrystal RV3029 driver to Kconfig and sync from Linux
- add bootcount uclass and first DM-driver for bootcount
......@@ -218,7 +218,8 @@
i2c-scl-falling-time-ns = <4>;
clock-frequency = <400000>;
vdd_gpu: fan535555@60 {
vdd_gpu: vdd_gpu {
status = "okay";
compatible = "fcs,fan53555";
reg = <0x60>;
vsel-gpios = <&gpio1 RK_PB6 GPIO_ACTIVE_HIGH>;
......@@ -420,7 +421,8 @@
status = "okay";
clock-frequency = <400000>;
vdd_cpu_b: fan53555@60 {
vdd_cpu_b: vdd_cpu_b {
status = "okay";
compatible = "fcs,fan53555";
reg = <0x60>;
vsel-gpios = <&gpio1 RK_PA4 GPIO_ACTIVE_HIGH>;
......
......@@ -76,6 +76,7 @@ CONFIG_PINCTRL=y
CONFIG_SPL_PINCTRL=y
CONFIG_PINCTRL_ROCKCHIP_RK3399=y
CONFIG_DM_PMIC=y
CONFIG_DM_PMIC_FAN53555=y
CONFIG_PMIC_RK8XX=y
CONFIG_SPL_DM_REGULATOR=y
CONFIG_DM_REGULATOR_FIXED=y
......
......@@ -42,6 +42,36 @@ Example
};
};
u-boot,bootcount-device property
--------------------------------
In a DM-based system, the bootcount may be stored in a device known to
the DM framework (e.g. in a battery-backed SRAM area within a RTC
device) managed by a device conforming to UCLASS_BOOTCOUNT. If
multiple such devices are present in a system concurrently, then the
u-boot,bootcount-device property can select the preferred target.
Example
-------
/ {
chosen {
u-boot,bootcount-device = &bootcount-rv3029;
};
bootcount-rv3029: bootcount@0 {
compatible = "u-boot,bootcount-rtc";
rtc = &rv3029;
offset = <0x38>;
};
i2c2 {
rv3029: rtc@56 {
compatible = "mc,rv3029";
reg = <0x56>;
};
};
};
u-boot,spl-boot-order property
------------------------------
......
Binding for Fairchild FAN53555 regulators
Required properties:
- compatible: "fcs,fan53555"
- reg: I2C address
Optional properties:
- fcs,suspend-voltage-selector: declare which of the two available
voltage selector registers should be used for the suspend
voltage. The other one is used for the runtime voltage setting
Possible values are either <0> or <1>
- vin-supply: regulator supplying the vin pin
Example:
regulator@40 {
compatible = "fcs,fan53555";
regulator-name = "fan53555";
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <1800000>;
vin-supply = <&parent_reg>;
fcs,suspend-voltage-selector = <1>;
};
......@@ -70,8 +70,36 @@ config BOOTCOUNT_AT91
bool "Boot counter for Atmel AT91SAM9XE"
depends on AT91SAM9XE
config DM_BOOTCOUNT
bool "Boot counter in a device-model device"
help
Enables reading/writing the bootcount in a device-model based
backing store. If an entry in /chosen/u-boot,bootcount-device
exists, this will be the preferred bootcount device; otherwise
the first available bootcount device will be used.
endchoice
if DM_BOOTCOUNT
menu "Backing stores for device-model backed bootcount"
config DM_BOOTCOUNT_RTC
bool "Support RTC devices as a backing store for bootcount"
depends on DM_RTC
help
Enabled reading/writing the bootcount in a DM RTC device.
The wrapper device is to be specified with the compatible string
'u-boot,bootcount-rtc' and the 'rtc'-property (a phandle pointing
to the underlying RTC device) and an optional 'offset' property
are supported.
Accesses to the backing store are performed using the write16
and read16 ops of DM RTC devices.
endmenu
endif
config BOOTCOUNT_BOOTLIMIT
int "Maximum number of reboot cycles allowed"
default 0
......
......@@ -7,3 +7,6 @@ obj-$(CONFIG_BOOTCOUNT_RAM) += bootcount_ram.o
obj-$(CONFIG_BOOTCOUNT_ENV) += bootcount_env.o
obj-$(CONFIG_BOOTCOUNT_I2C) += bootcount_i2c.o
obj-$(CONFIG_BOOTCOUNT_EXT) += bootcount_ext.o
obj-$(CONFIG_DM_BOOTCOUNT) += bootcount-uclass.o
obj-$(CONFIG_DM_BOOTCOUNT_RTC) += rtc.o
// SPDX-License-Identifier: GPL-2.0+
/*
* (C) Copyright 2018 Theobroma Systems Design und Consulting GmbH
*/
#include <common.h>
#include <dm.h>
#include <errno.h>
#include <bootcount.h>
int dm_bootcount_get(struct udevice *dev, u32 *bootcount)
{
struct bootcount_ops *ops = bootcount_get_ops(dev);
assert(ops);
if (!ops->get)
return -ENOSYS;
return ops->get(dev, bootcount);
}
int dm_bootcount_set(struct udevice *dev, const u32 bootcount)
{
struct bootcount_ops *ops = bootcount_get_ops(dev);
assert(ops);
if (!ops->set)
return -ENOSYS;
return ops->set(dev, bootcount);
}
/* Now implement the generic default functions */
void bootcount_store(ulong val)
{
struct udevice *dev = NULL;
ofnode node;
const char *propname = "u-boot,bootcount-device";
int ret = -ENODEV;
/*
* If there's a preferred bootcount device selected by the user (by
* setting '/chosen/u-boot,bootcount-device' in the DTS), try to use
* it if available.
*/
node = ofnode_get_chosen_node(propname);
if (ofnode_valid(node))
ret = uclass_get_device_by_ofnode(UCLASS_BOOTCOUNT, node, &dev);
/* If there was no user-selected device, use the first available one */
if (ret)
ret = uclass_get_device(UCLASS_BOOTCOUNT, 0, &dev);
if (dev)
ret = dm_bootcount_set(dev, val);
if (ret)
pr_debug("%s: failed to store 0x%lx\n", __func__, val);
}
ulong bootcount_load(void)
{
struct udevice *dev = NULL;
ofnode node;
const char *propname = "u-boot,bootcount-device";
int ret = -ENODEV;
u32 val;
/*
* If there's a preferred bootcount device selected by the user (by
* setting '/chosen/u-boot,bootcount-device' in the DTS), try to use
* it if available.
*/
node = ofnode_get_chosen_node(propname);
if (ofnode_valid(node))
ret = uclass_get_device_by_ofnode(UCLASS_BOOTCOUNT, node, &dev);
/* If there was no user-selected device, use the first available one */
if (ret)
ret = uclass_get_device(UCLASS_BOOTCOUNT, 0, &dev);
if (dev)
ret = dm_bootcount_get(dev, &val);
if (ret)
pr_debug("%s: failed to load bootcount\n", __func__);
/* Return the 0, if the call to dm_bootcount_get failed */
return ret ? 0 : val;
}
UCLASS_DRIVER(bootcount) = {
.name = "bootcount",
.id = UCLASS_BOOTCOUNT,
};
// SPDX-License-Identifier: GPL-2.0+
/*
* (C) Copyright 2018 Theobroma Systems Design und Consulting GmbH
*/
#include <common.h>
#include <bootcount.h>
#include <dm.h>
#include <rtc.h>
static const u8 bootcount_magic = 0xbc;
struct bootcount_rtc_priv {
struct udevice *rtc;
u32 offset;
};
static int bootcount_rtc_set(struct udevice *dev, const u32 a)
{
struct bootcount_rtc_priv *priv = dev_get_priv(dev);
const u16 val = bootcount_magic << 8 | (a & 0xff);
if (rtc_write16(priv->rtc, priv->offset, val) < 0) {
debug("%s: rtc_write16 failed\n", __func__);
return -EIO;
}
return 0;
}
static int bootcount_rtc_get(struct udevice *dev, u32 *a)
{
struct bootcount_rtc_priv *priv = dev_get_priv(dev);
u16 val;
if (rtc_read16(priv->rtc, priv->offset, &val) < 0) {
debug("%s: rtc_write16 failed\n", __func__);
return -EIO;
}
if (val >> 8 == bootcount_magic) {
*a = val & 0xff;
return 0;
}
debug("%s: bootcount magic does not match on %04x\n", __func__, val);
return -EIO;
}
static int bootcount_rtc_probe(struct udevice *dev)
{
struct ofnode_phandle_args phandle_args;
struct bootcount_rtc_priv *priv = dev_get_priv(dev);
struct udevice *rtc;
if (dev_read_phandle_with_args(dev, "rtc", NULL, 0, 0, &phandle_args)) {
debug("%s: rtc backing device not specified\n", dev->name);
return -ENOENT;
}
if (uclass_get_device_by_ofnode(UCLASS_RTC, phandle_args.node, &rtc)) {
debug("%s: could not get backing device\n", dev->name);
return -ENODEV;
}
priv->rtc = rtc;
priv->offset = dev_read_u32_default(dev, "offset", 0);
return 0;
}
static const struct bootcount_ops bootcount_rtc_ops = {
.get = bootcount_rtc_get,
.set = bootcount_rtc_set,
};
static const struct udevice_id bootcount_rtc_ids[] = {
{ .compatible = "u-boot,bootcount-rtc" },
{ }
};
U_BOOT_DRIVER(bootcount_rtc) = {
.name = "bootcount-rtc",
.id = UCLASS_BOOTCOUNT,
.priv_auto_alloc_size = sizeof(struct bootcount_rtc_priv),
.probe = bootcount_rtc_probe,
.of_match = bootcount_rtc_ids,
.ops = &bootcount_rtc_ops,
};
......@@ -48,6 +48,20 @@ config PMIC_AS3722
interface and is designs to cover most of the power managementment
required for a tablets or laptop.
config DM_PMIC_FAN53555
bool "Enable support for OnSemi FAN53555"
depends on DM_PMIC && DM_REGULATOR && DM_I2C
select DM_REGULATOR_FAN53555
help
This config enables implementation of driver-model PMIC
uclass features for the FAN53555 regulator. The FAN53555 is
a (family of) single-output regulators that supports
transitioning between two different output voltages based on
an voltage selection pin.
The driver implements read/write operations for use with the FAN53555
regulator driver and binds the regulator driver to its node.
config DM_PMIC_PFUZE100
bool "Enable Driver Model for PMIC PFUZE100"
depends on DM_PMIC
......
......@@ -4,6 +4,7 @@
# Lukasz Majewski <l.majewski@samsung.com>
obj-$(CONFIG_DM_PMIC) += pmic-uclass.o
obj-$(CONFIG_DM_PMIC_FAN53555) += fan53555.o
obj-$(CONFIG_DM_PMIC_MAX77686) += max77686.o
obj-$(CONFIG_DM_PMIC_MAX8998) += max8998.o
obj-$(CONFIG_DM_PMIC_MC34708) += mc34708.o
......
// SPDX-License-Identifier: GPL-2.0+
/*
* (C) 2018 Theobroma Systems Design und Consulting GmbH
*/
#include <common.h>
#include <dm.h>
#include <dm/device-internal.h>
#include <dm/lists.h>
#include <i2c.h>
#include <power/pmic.h>
#include <power/regulator.h>
static int pmic_fan53555_reg_count(struct udevice *dev)
{
return 1;
};
static int pmic_fan53555_read(struct udevice *dev, uint reg,
u8 *buff, int len)
{
if (dm_i2c_read(dev, reg, buff, len)) {
pr_err("%s: read error for register: %#x!", dev->name, reg);
return -EIO;
}
return 0;
}
static int pmic_fan53555_write(struct udevice *dev, uint reg,
const u8 *buff, int len)
{
if (dm_i2c_write(dev, reg, buff, len)) {
pr_err("%s: write error for register: %#x!", dev->name, reg);
return -EIO;
}
return 0;
}
static int pmic_fan53555_bind(struct udevice *dev)
{
/*
* The FAN53555 has only a single regulator and therefore doesn't
* have a subnode. So we have to rebind a child device (the one
* regulator) here.
*/
const char *regulator_driver_name = "fan53555_regulator";
struct udevice *child;
struct driver *drv;
debug("%s\n", __func__);
drv = lists_driver_lookup_name(regulator_driver_name);
if (!drv) {
dev_err(dev, "no driver '%s'\n", regulator_driver_name);
return -ENOENT;
}
return device_bind_with_driver_data(dev, drv, "SW", 0,
dev_ofnode(dev), &child);
};
static struct dm_pmic_ops pmic_fan53555_ops = {
.reg_count = pmic_fan53555_reg_count,
.read = pmic_fan53555_read,
.write = pmic_fan53555_write,
};
static const struct udevice_id pmic_fan53555_match[] = {
{ .compatible = "fcs,fan53555" },
{ },
};
U_BOOT_DRIVER(pmic_fan53555) = {
.name = "pmic_fan53555",
.id = UCLASS_PMIC,
.of_match = pmic_fan53555_match,
.bind = pmic_fan53555_bind,
.ops = &pmic_fan53555_ops,
};
......@@ -69,6 +69,22 @@ config DM_REGULATOR_MAX77686
features for REGULATOR MAX77686. The driver implements get/set api for:
value, enable and mode.
config DM_REGULATOR_FAN53555
bool "Enable Driver Model for REGULATOR FAN53555"
depends on DM_PMIC_FAN53555
help
This config enables implementation of driver-model regulator
uclass features for the FAN53555 regulator. The FAN53555 is
a (family of) single-output regulators that supports
transitioning between two different output voltages based on
an voltage selection pin.
The driver implements a get/set api for the voltage of the
'normal mode' voltage only. Switching to 'suspend mode'
(i.e. the alternate voltage), disabling output via software,
or switching the mode is not supported by this driver (at
this time).
config DM_REGULATOR_FIXED
bool "Enable Driver Model for REGULATOR Fixed value"
depends on DM_REGULATOR
......
......@@ -10,6 +10,7 @@ obj-$(CONFIG_REGULATOR_AS3722) += as3722_regulator.o
obj-$(CONFIG_DM_REGULATOR_MAX77686) += max77686.o
obj-$(CONFIG_$(SPL_)DM_PMIC_PFUZE100) += pfuze100.o
obj-$(CONFIG_REGULATOR_PWM) += pwm_regulator.o
obj-$(CONFIG_$(SPL_)DM_REGULATOR_FAN53555) += fan53555.o
obj-$(CONFIG_$(SPL_)DM_REGULATOR_FIXED) += fixed.o
obj-$(CONFIG_$(SPL_)DM_REGULATOR_GPIO) += gpio-regulator.o
obj-$(CONFIG_REGULATOR_RK8XX) += rk8xx.o
......
// SPDX-License-Identifier: GPL-2.0+
/*
* (C) 2018 Theobroma Systems Design und Consulting GmbH
*/
#include <common.h>
#include <bitfield.h>
#include <errno.h>
#include <dm.h>
#include <fdtdec.h>
#include <i2c.h>
#include <asm/gpio.h>
#include <power/pmic.h>
#include <power/regulator.h>
/**
* struct ic_types - definition of fan53555-family devices
*
* @die_id: Identifies the DIE_ID (lower nibble of the ID1 register)
* @die_rev: Identifies the DIE_REV (lower nibble of the ID2 register)
* @vsel_min: starting voltage (step 0) in uV
* @vsel_step: increment of the voltage in uV
*
* The voltage ramp (i.e. minimum voltage and step) is selected from the
* combination of 2 nibbles: DIE_ID and DIE_REV.
*
* See http://www.onsemi.com/pub/Collateral/FAN53555-D.pdf for details.
*/
static const struct {
u8 die_id;
u8 die_rev;
u32 vsel_min;
u32 vsel_step;
} ic_types[] = {
{ 0x0, 0x3, 600000, 10000 }, /* Option 00 */
{ 0x0, 0xf, 800000, 10000 }, /* Option 13 */
{ 0x0, 0xc, 600000, 12500 }, /* Option 23 */
{ 0x1, 0x3, 600000, 10000 }, /* Option 01 */
{ 0x3, 0x3, 600000, 10000 }, /* Option 03 */
{ 0x4, 0xf, 603000, 12826 }, /* Option 04 */
{ 0x5, 0x3, 600000, 10000 }, /* Option 05 */
{ 0x8, 0x1, 600000, 10000 }, /* Option 08 */
{ 0x8, 0xf, 600000, 10000 }, /* Option 08 */
{ 0xc, 0xf, 603000, 12826 }, /* Option 09 */
};
/* I2C-accessible byte-sized registers */
enum {
/* Voltage setting */
FAN53555_VSEL0 = 0x00,
FAN53555_VSEL1,
/* Control register */
FAN53555_CONTROL,
/* IC Type */
FAN53555_ID1,
/* IC mask version */
FAN53555_ID2,
/* Monitor register */
FAN53555_MONITOR,
};
struct fan53555_platdata {
/* Voltage setting register */
unsigned int vol_reg;
unsigned int sleep_reg;
};
struct fan53555_priv {
/* IC Vendor */
unsigned int vendor;
/* IC Type and Rev */
unsigned int die_id;
unsigned int die_rev;
/* Voltage range and step(linear) */
unsigned int vsel_min;
unsigned int vsel_step;
/* Voltage slew rate limiting */
unsigned int slew_rate;
/* Sleep voltage cache */
unsigned int sleep_vol_cache;
};
static int fan53555_regulator_ofdata_to_platdata(struct udevice *dev)
{
struct fan53555_platdata *dev_pdata = dev_get_platdata(dev);
struct dm_regulator_uclass_platdata *uc_pdata =
dev_get_uclass_platdata(dev);
u32 sleep_vsel;
/* This is a buck regulator */
uc_pdata->type = REGULATOR_TYPE_BUCK;
sleep_vsel = dev_read_u32_default(dev, "fcs,suspend-voltage-selector",
FAN53555_VSEL1);
/*
* Depending on the device-tree settings, the 'normal mode'
* voltage is either controlled by VSEL0 or VSEL1.
*/
switch (sleep_vsel) {
case FAN53555_VSEL0:
dev_pdata->sleep_reg = FAN53555_VSEL0;
dev_pdata->vol_reg = FAN53555_VSEL1;
break;
case FAN53555_VSEL1:
dev_pdata->sleep_reg = FAN53555_VSEL1;
dev_pdata->vol_reg = FAN53555_VSEL0;
break;
default:
pr_err("%s: invalid vsel id %d\n", dev->name, sleep_vsel);
return -EINVAL;
}
return 0;
}
static int fan53555_regulator_get_value(struct udevice *dev)
{
struct fan53555_platdata *pdata = dev_get_platdata(dev);
struct fan53555_priv *priv = dev_get_priv(dev);
int reg;
int voltage;
/* We only support a single voltage selector (i.e. 'normal' mode). */
reg = pmic_reg_read(dev->parent, pdata->vol_reg);
if (reg < 0)
return reg;
voltage = priv->vsel_min + (reg & 0x3f) * priv->vsel_step;
debug("%s: %d uV\n", __func__, voltage);
return voltage;
}
static int fan53555_regulator_set_value(struct udevice *dev, int uV)
{
struct fan53555_platdata *pdata = dev_get_platdata(dev);
struct fan53555_priv *priv = dev_get_priv(dev);
u8 vol;
vol = (uV - priv->vsel_min) / priv->vsel_step;
debug("%s: uV=%d; writing volume %d: %02x\n",
__func__, uV, pdata->vol_reg, vol);
return pmic_clrsetbits(dev, pdata->vol_reg, GENMASK(6, 0), vol);
}
static int fan53555_voltages_setup(struct udevice *dev)
{
struct fan53555_priv *priv = dev_get_priv(dev);
int i;
/* Init voltage range and step */
for (i = 0; i < ARRAY_SIZE(ic_types); ++i) {
if (ic_types[i].die_id != priv->die_id)
continue;
if (ic_types[i].die_rev != priv->die_rev)
continue;
priv->vsel_min = ic_types[i].vsel_min;
priv->vsel_step = ic_types[i].vsel_step;
return 0;
}
pr_err("%s: %s: die id %d rev %d not supported!\n",
dev->name, __func__, priv->die_id, priv->die_rev);
return -EINVAL;
}
enum {
DIE_ID_SHIFT = 0,
DIE_ID_WIDTH = 4,
DIE_REV_SHIFT = 0,
DIE_REV_WIDTH = 4,
};
static int fan53555_probe(struct udevice *dev)
{
struct fan53555_priv *priv = dev_get_priv(dev);
int ID1, ID2;
debug("%s\n", __func__);
/* read chip ID1 and ID2 (two registers, starting at ID1) */
ID1 = pmic_reg_read(dev->parent, FAN53555_ID1);
if (ID1 < 0)
return ID1;
ID2 = pmic_reg_read(dev->parent, FAN53555_ID2);
if (ID2 < 0)
return ID2;
/* extract vendor, die_id and die_rev */
priv->vendor = bitfield_extract(ID1, 5, 3);
priv->die_id = ID1 & GENMASK(3, 0);
priv->die_rev = ID2 & GENMASK(3, 0);
if (fan53555_voltages_setup(dev) < 0)
return -ENODATA;
debug("%s: FAN53555 option %d rev %d detected\n",
__func__, priv->die_id, priv->die_rev);
return 0;
}
static const struct dm_regulator_ops fan53555_regulator_ops = {
.get_value = fan53555_regulator_get_value,
.set_value = fan53555_regulator_set_value,
};
U_BOOT_DRIVER(fan53555_regulator) = {
.name = "fan53555_regulator",
.id = UCLASS_REGULATOR,
.ops = &fan53555_regulator_ops,
.ofdata_to_platdata = fan53555_regulator_ofdata_to_platdata,
.platdata_auto_alloc_size = sizeof(struct fan53555_platdata),
.priv_auto_alloc_size = sizeof(struct fan53555_priv),
.probe = fan53555_probe,
};
......@@ -49,7 +49,7 @@ struct rk322x_sdram_params {
struct regmap *map;
};
#ifdef CONFIG_TPL_BUILD
#ifdef CONFIG_SPL_BUILD
/*
* [7:6] bank(n:n bit bank)
* [5:4] row(13+n)
......@@ -750,7 +750,7 @@ static int rk322x_dmc_ofdata_to_platdata(struct udevice *dev)
return 0;
}
#endif /* CONFIG_TPL_BUILD */
#endif /* CONFIG_SPL_BUILD */
#if CONFIG_IS_ENABLED(OF_PLATDATA)
static int conv_of_platdata(struct udevice *dev)
......@@ -778,7 +778,7 @@ static int conv_of_platdata(struct udevice *dev)
static int rk322x_dmc_probe(struct udevice *dev)
{
#ifdef CONFIG_TPL_BUILD
#ifdef CONFIG_SPL_BUILD
struct rk322x_sdram_params *plat = dev_get_platdata(dev);
int ret;
struct udevice *dev_clk;
......@@ -786,7 +786,7 @@ static int rk322x_dmc_probe(struct udevice *dev)
struct dram_info *priv = dev_get_priv(dev);
priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
#ifdef CONFIG_TPL_BUILD
#ifdef CONFIG_SPL_BUILD
#if CONFIG_IS_ENABLED(OF_PLATDATA)
ret = conv_of_platdata(dev);
if (ret)
......@@ -842,12 +842,12 @@ U_BOOT_DRIVER(dmc_rk322x) = {
.id = UCLASS_RAM,
.of_match = rk322x_dmc_ids,
.ops = &rk322x_dmc_ops,
#ifdef CONFIG_TPL_BUILD
#ifdef CONFIG_SPL_BUILD
.ofdata_to_platdata = rk322x_dmc_ofdata_to_platdata,
#endif
.probe = rk322x_dmc_probe,
.priv_auto_alloc_size = sizeof(struct dram_info),
#ifdef CONFIG_TPL_BUILD
#ifdef CONFIG_SPL_BUILD
.platdata_auto_alloc_size = sizeof(struct rk322x_sdram_params),
#endif
};
......
......@@ -10,6 +10,54 @@
#include <asm/io.h>
#include <asm/byteorder.h>
#ifdef CONFIG_DM_BOOTCOUNT
struct bootcount_ops {
/**
* get() - get the current bootcount value
*
* Returns the current counter value of the bootcount backing
* store.
*
* @dev: Device to read from
* @bootcount: Address to put the current bootcount value
*/
int (*get)(struct udevice *dev, u32 *bootcount);
/**
* set() - set a bootcount value (e.g. to reset or increment)
*
* Sets the value in the bootcount backing store.
*
* @dev: Device to read from
* @bootcount: New bootcount value to store
*/
int (*set)(struct udevice *dev, const u32 bootcount);
};
/* Access the operations for a bootcount device */
#define bootcount_get_ops(dev) ((struct bootcount_ops *)(dev)->driver->ops)
/**
* dm_bootcount_get() - Read the current value from a bootcount storage
*
* @dev: Device to read from
* @bootcount: Place to put the current bootcount
* @return 0 if OK, -ve on error
*/
int dm_bootcount_get(struct udevice *dev, u32 *bootcount);
/**
* dm_bootcount_set() - Write a value to a bootcount storage
*
* @dev: Device to read from
* @bootcount: Value to be written to the backing storage
* @return 0 if OK, -ve on error
*/
int dm_bootcount_set(struct udevice *dev, u32 bootcount);
#endif
#if defined(CONFIG_SPL_BOOTCOUNT_LIMIT) || defined(CONFIG_BOOTCOUNT_LIMIT)
#if !defined(CONFIG_SYS_BOOTCOUNT_LE) && !defined(CONFIG_SYS_BOOTCOUNT_BE)
......
......@@ -32,6 +32,7 @@ enum uclass_id {
UCLASS_AXI, /* AXI bus */
UCLASS_BLK, /* Block device */
UCLASS_BOARD, /* Device information from hardware */
UCLASS_BOOTCOUNT, /* Bootcount backing store */
UCLASS_CLK, /* Clock source, e.g. used by peripherals */
UCLASS_CPU, /* CPU, typically part of an SoC */
UCLASS_CROS_EC, /* Chrome OS EC */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册