ptp: ocp: Add firmware capability bits for feature gating
Add the ability to group sysfs nodes behind a firmware feature check. This way non-present sysfs attributes are omitted on older firmware, which does not have newer features. This will be used in the upcoming patches which adds more features to the timecard. Signed-off-by: Jonathan Lemon <jonathan.lemon@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
cd09193ffb
commit
c205d53c49
1 changed files with 33 additions and 5 deletions
|
@ -218,6 +218,13 @@ struct ptp_ocp_sma_connector {
|
||||||
bool disabled;
|
bool disabled;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ocp_attr_group {
|
||||||
|
u64 cap;
|
||||||
|
const struct attribute_group *group;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define OCP_CAP_BASIC BIT(0)
|
||||||
|
|
||||||
#define OCP_BOARD_ID_LEN 13
|
#define OCP_BOARD_ID_LEN 13
|
||||||
#define OCP_SERIAL_LEN 6
|
#define OCP_SERIAL_LEN 6
|
||||||
|
|
||||||
|
@ -248,6 +255,7 @@ struct ptp_ocp {
|
||||||
struct platform_device *spi_flash;
|
struct platform_device *spi_flash;
|
||||||
struct clk_hw *i2c_clk;
|
struct clk_hw *i2c_clk;
|
||||||
struct timer_list watchdog;
|
struct timer_list watchdog;
|
||||||
|
const struct ocp_attr_group *attr_tbl;
|
||||||
const struct ptp_ocp_eeprom_map *eeprom_map;
|
const struct ptp_ocp_eeprom_map *eeprom_map;
|
||||||
struct dentry *debug_root;
|
struct dentry *debug_root;
|
||||||
time64_t gnss_lost;
|
time64_t gnss_lost;
|
||||||
|
@ -265,6 +273,7 @@ struct ptp_ocp {
|
||||||
int flash_start;
|
int flash_start;
|
||||||
u32 utc_tai_offset;
|
u32 utc_tai_offset;
|
||||||
u32 ts_window_adjust;
|
u32 ts_window_adjust;
|
||||||
|
u64 fw_cap;
|
||||||
struct ptp_ocp_sma_connector sma[4];
|
struct ptp_ocp_sma_connector sma[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -290,6 +299,8 @@ static int ptp_ocp_fb_board_init(struct ptp_ocp *bp, struct ocp_resource *r);
|
||||||
static irqreturn_t ptp_ocp_ts_irq(int irq, void *priv);
|
static irqreturn_t ptp_ocp_ts_irq(int irq, void *priv);
|
||||||
static int ptp_ocp_ts_enable(void *priv, u32 req, bool enable);
|
static int ptp_ocp_ts_enable(void *priv, u32 req, bool enable);
|
||||||
|
|
||||||
|
static const struct ocp_attr_group fb_timecard_groups[];
|
||||||
|
|
||||||
struct ptp_ocp_eeprom_map {
|
struct ptp_ocp_eeprom_map {
|
||||||
u16 off;
|
u16 off;
|
||||||
u16 len;
|
u16 len;
|
||||||
|
@ -1526,6 +1537,8 @@ ptp_ocp_fb_board_init(struct ptp_ocp *bp, struct ocp_resource *r)
|
||||||
bp->flash_start = 1024 * 4096;
|
bp->flash_start = 1024 * 4096;
|
||||||
bp->eeprom_map = fb_eeprom_map;
|
bp->eeprom_map = fb_eeprom_map;
|
||||||
bp->fw_version = ioread32(&bp->image->version);
|
bp->fw_version = ioread32(&bp->image->version);
|
||||||
|
bp->attr_tbl = fb_timecard_groups;
|
||||||
|
bp->fw_cap = OCP_CAP_BASIC;
|
||||||
|
|
||||||
ptp_ocp_tod_init(bp);
|
ptp_ocp_tod_init(bp);
|
||||||
ptp_ocp_nmea_out_init(bp);
|
ptp_ocp_nmea_out_init(bp);
|
||||||
|
@ -2167,7 +2180,7 @@ tod_correction_store(struct device *dev, struct device_attribute *attr,
|
||||||
}
|
}
|
||||||
static DEVICE_ATTR_RW(tod_correction);
|
static DEVICE_ATTR_RW(tod_correction);
|
||||||
|
|
||||||
static struct attribute *timecard_attrs[] = {
|
static struct attribute *fb_timecard_attrs[] = {
|
||||||
&dev_attr_serialnum.attr,
|
&dev_attr_serialnum.attr,
|
||||||
&dev_attr_gnss_sync.attr,
|
&dev_attr_gnss_sync.attr,
|
||||||
&dev_attr_clock_source.attr,
|
&dev_attr_clock_source.attr,
|
||||||
|
@ -2186,7 +2199,13 @@ static struct attribute *timecard_attrs[] = {
|
||||||
&dev_attr_tod_correction.attr,
|
&dev_attr_tod_correction.attr,
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
ATTRIBUTE_GROUPS(timecard);
|
static const struct attribute_group fb_timecard_group = {
|
||||||
|
.attrs = fb_timecard_attrs,
|
||||||
|
};
|
||||||
|
static const struct ocp_attr_group fb_timecard_groups[] = {
|
||||||
|
{ .cap = OCP_CAP_BASIC, .group = &fb_timecard_group },
|
||||||
|
{ },
|
||||||
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gpio_input_map(char *buf, struct ptp_ocp *bp, u16 map[][2], u16 bit,
|
gpio_input_map(char *buf, struct ptp_ocp *bp, u16 map[][2], u16 bit,
|
||||||
|
@ -2605,6 +2624,7 @@ ptp_ocp_complete(struct ptp_ocp *bp)
|
||||||
{
|
{
|
||||||
struct pps_device *pps;
|
struct pps_device *pps;
|
||||||
char buf[32];
|
char buf[32];
|
||||||
|
int i, err;
|
||||||
|
|
||||||
if (bp->gnss_port != -1) {
|
if (bp->gnss_port != -1) {
|
||||||
sprintf(buf, "ttyS%d", bp->gnss_port);
|
sprintf(buf, "ttyS%d", bp->gnss_port);
|
||||||
|
@ -2629,8 +2649,13 @@ ptp_ocp_complete(struct ptp_ocp *bp)
|
||||||
if (pps)
|
if (pps)
|
||||||
ptp_ocp_symlink(bp, pps->dev, "pps");
|
ptp_ocp_symlink(bp, pps->dev, "pps");
|
||||||
|
|
||||||
if (device_add_groups(&bp->dev, timecard_groups))
|
for (i = 0; bp->attr_tbl[i].cap; i++) {
|
||||||
pr_err("device add groups failed\n");
|
if (!(bp->attr_tbl[i].cap & bp->fw_cap))
|
||||||
|
continue;
|
||||||
|
err = sysfs_create_group(&bp->dev.kobj, bp->attr_tbl[i].group);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
ptp_ocp_debugfs_add_device(bp);
|
ptp_ocp_debugfs_add_device(bp);
|
||||||
|
|
||||||
|
@ -2703,12 +2728,15 @@ static void
|
||||||
ptp_ocp_detach_sysfs(struct ptp_ocp *bp)
|
ptp_ocp_detach_sysfs(struct ptp_ocp *bp)
|
||||||
{
|
{
|
||||||
struct device *dev = &bp->dev;
|
struct device *dev = &bp->dev;
|
||||||
|
int i;
|
||||||
|
|
||||||
sysfs_remove_link(&dev->kobj, "ttyGNSS");
|
sysfs_remove_link(&dev->kobj, "ttyGNSS");
|
||||||
sysfs_remove_link(&dev->kobj, "ttyMAC");
|
sysfs_remove_link(&dev->kobj, "ttyMAC");
|
||||||
sysfs_remove_link(&dev->kobj, "ptp");
|
sysfs_remove_link(&dev->kobj, "ptp");
|
||||||
sysfs_remove_link(&dev->kobj, "pps");
|
sysfs_remove_link(&dev->kobj, "pps");
|
||||||
device_remove_groups(dev, timecard_groups);
|
if (bp->attr_tbl)
|
||||||
|
for (i = 0; bp->attr_tbl[i].cap; i++)
|
||||||
|
sysfs_remove_group(&dev->kobj, bp->attr_tbl[i].group);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
Loading…
Add table
Reference in a new issue