Commit c205d53c authored by Jonathan Lemon's avatar Jonathan Lemon Committed by David S. Miller

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: default avatarJonathan Lemon <jonathan.lemon@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent cd09193f
...@@ -218,6 +218,13 @@ struct ptp_ocp_sma_connector { ...@@ -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 { ...@@ -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 { ...@@ -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); ...@@ -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) ...@@ -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, ...@@ -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[] = { ...@@ -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) ...@@ -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) ...@@ -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 ...@@ -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
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment