Commit ce7ec1b8 authored by David S. Miller's avatar David S. Miller

Merge branch 'ptrp-ocp-next'

Jonathan Lemon says:

====================
ptp: ocp: update devlink information

Both of these patches update the information displayed via devlink.

v1 -> v2: remove board.manufacture information
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents b57b44f7 b0ca789a
...@@ -11,12 +11,14 @@ ...@@ -11,12 +11,14 @@
#include <linux/clkdev.h> #include <linux/clkdev.h>
#include <linux/clk-provider.h> #include <linux/clk-provider.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/platform_data/i2c-xiic.h>
#include <linux/ptp_clock_kernel.h> #include <linux/ptp_clock_kernel.h>
#include <linux/spi/spi.h> #include <linux/spi/spi.h>
#include <linux/spi/xilinx_spi.h> #include <linux/spi/xilinx_spi.h>
#include <net/devlink.h> #include <net/devlink.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/mtd/mtd.h> #include <linux/mtd/mtd.h>
#include <linux/nvmem-consumer.h>
#ifndef PCI_VENDOR_ID_FACEBOOK #ifndef PCI_VENDOR_ID_FACEBOOK
#define PCI_VENDOR_ID_FACEBOOK 0x1d9b #define PCI_VENDOR_ID_FACEBOOK 0x1d9b
...@@ -204,6 +206,9 @@ struct ptp_ocp_ext_src { ...@@ -204,6 +206,9 @@ struct ptp_ocp_ext_src {
int irq_vec; int irq_vec;
}; };
#define OCP_BOARD_ID_LEN 13
#define OCP_SERIAL_LEN 6
struct ptp_ocp { struct ptp_ocp {
struct pci_dev *pdev; struct pci_dev *pdev;
struct device dev; struct device dev;
...@@ -230,6 +235,7 @@ struct ptp_ocp { ...@@ -230,6 +235,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 ptp_ocp_eeprom_map *eeprom_map;
struct dentry *debug_root; struct dentry *debug_root;
time64_t gnss_lost; time64_t gnss_lost;
int id; int id;
...@@ -238,8 +244,10 @@ struct ptp_ocp { ...@@ -238,8 +244,10 @@ struct ptp_ocp {
int gnss2_port; int gnss2_port;
int mac_port; /* miniature atomic clock */ int mac_port; /* miniature atomic clock */
int nmea_port; int nmea_port;
u8 serial[6]; u32 fw_version;
bool has_serial; u8 board_id[OCP_BOARD_ID_LEN];
u8 serial[OCP_SERIAL_LEN];
bool has_eeprom_data;
u32 pps_req_map; u32 pps_req_map;
int flash_start; int flash_start;
u32 utc_tai_offset; u32 utc_tai_offset;
...@@ -268,6 +276,28 @@ static int ptp_ocp_fb_board_init(struct ptp_ocp *bp, struct ocp_resource *r); ...@@ -268,6 +276,28 @@ 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);
struct ptp_ocp_eeprom_map {
u16 off;
u16 len;
u32 bp_offset;
const void * const tag;
};
#define EEPROM_ENTRY(addr, member) \
.off = addr, \
.len = sizeof_field(struct ptp_ocp, member), \
.bp_offset = offsetof(struct ptp_ocp, member)
#define BP_MAP_ENTRY_ADDR(bp, map) ({ \
(void *)((uintptr_t)(bp) + (map)->bp_offset); \
})
static struct ptp_ocp_eeprom_map fb_eeprom_map[] = {
{ EEPROM_ENTRY(0x43, board_id) },
{ EEPROM_ENTRY(0x00, serial), .tag = "mac" },
{ }
};
#define bp_assign_entry(bp, res, val) ({ \ #define bp_assign_entry(bp, res, val) ({ \
uintptr_t addr = (uintptr_t)(bp) + (res)->bp_offset; \ uintptr_t addr = (uintptr_t)(bp) + (res)->bp_offset; \
*(typeof(val) *)addr = val; \ *(typeof(val) *)addr = val; \
...@@ -396,6 +426,15 @@ static struct ocp_resource ocp_fb_resource[] = { ...@@ -396,6 +426,15 @@ static struct ocp_resource ocp_fb_resource[] = {
.extra = &(struct ptp_ocp_i2c_info) { .extra = &(struct ptp_ocp_i2c_info) {
.name = "xiic-i2c", .name = "xiic-i2c",
.fixed_rate = 50000000, .fixed_rate = 50000000,
.data_size = sizeof(struct xiic_i2c_platform_data),
.data = &(struct xiic_i2c_platform_data) {
.num_devices = 2,
.devices = (struct i2c_board_info[]) {
{ I2C_BOARD_INFO("24c02", 0x50) },
{ I2C_BOARD_INFO("24mac402", 0x58),
.platform_data = "mac" },
},
},
}, },
}, },
{ {
...@@ -919,78 +958,88 @@ ptp_ocp_tod_gnss_name(int idx) ...@@ -919,78 +958,88 @@ ptp_ocp_tod_gnss_name(int idx)
return gnss_name[idx]; return gnss_name[idx];
} }
struct ptp_ocp_nvmem_match_info {
struct ptp_ocp *bp;
const void * const tag;
};
static int static int
ptp_ocp_firstchild(struct device *dev, void *data) ptp_ocp_nvmem_match(struct device *dev, const void *data)
{ {
return 1; const struct ptp_ocp_nvmem_match_info *info = data;
dev = dev->parent;
if (!i2c_verify_client(dev) || info->tag != dev->platform_data)
return 0;
while ((dev = dev->parent))
if (dev->driver && !strcmp(dev->driver->name, KBUILD_MODNAME))
return info->bp == dev_get_drvdata(dev);
return 0;
} }
static int static inline struct nvmem_device *
ptp_ocp_read_i2c(struct i2c_adapter *adap, u8 addr, u8 reg, u8 sz, u8 *data) ptp_ocp_nvmem_device_get(struct ptp_ocp *bp, const void * const tag)
{ {
struct i2c_msg msgs[2] = { struct ptp_ocp_nvmem_match_info info = { .bp = bp, .tag = tag };
{
.addr = addr, return nvmem_device_find(&info, ptp_ocp_nvmem_match);
.len = 1, }
.buf = &reg,
}, static inline void
{ ptp_ocp_nvmem_device_put(struct nvmem_device **nvmemp)
.addr = addr, {
.flags = I2C_M_RD, if (*nvmemp != NULL) {
.len = 2, nvmem_device_put(*nvmemp);
.buf = data, *nvmemp = NULL;
},
};
int err;
u8 len;
/* xiic-i2c for some stupid reason only does 2 byte reads. */
while (sz) {
len = min_t(u8, sz, 2);
msgs[1].len = len;
err = i2c_transfer(adap, msgs, 2);
if (err != msgs[1].len)
return err;
msgs[1].buf += len;
reg += len;
sz -= len;
} }
return 0;
} }
static void static void
ptp_ocp_get_serial_number(struct ptp_ocp *bp) ptp_ocp_read_eeprom(struct ptp_ocp *bp)
{ {
struct i2c_adapter *adap; const struct ptp_ocp_eeprom_map *map;
struct device *dev; struct nvmem_device *nvmem;
int err; const void *tag;
int ret;
if (!bp->i2c_ctrl) if (!bp->i2c_ctrl)
return; return;
dev = device_find_child(&bp->i2c_ctrl->dev, NULL, ptp_ocp_firstchild); tag = NULL;
if (!dev) { nvmem = NULL;
dev_err(&bp->pdev->dev, "Can't find I2C adapter\n");
return;
}
adap = i2c_verify_adapter(dev); for (map = bp->eeprom_map; map->len; map++) {
if (!adap) { if (map->tag != tag) {
dev_err(&bp->pdev->dev, "device '%s' isn't an I2C adapter\n", tag = map->tag;
dev_name(dev)); ptp_ocp_nvmem_device_put(&nvmem);
goto out; }
} if (!nvmem) {
nvmem = ptp_ocp_nvmem_device_get(bp, tag);
err = ptp_ocp_read_i2c(adap, 0x58, 0x9A, 6, bp->serial); if (!nvmem)
if (err) { goto out;
dev_err(&bp->pdev->dev, "could not read eeprom: %d\n", err); }
goto out; ret = nvmem_device_read(nvmem, map->off, map->len,
BP_MAP_ENTRY_ADDR(bp, map));
if (ret != map->len)
goto read_fail;
} }
bp->has_serial = true; bp->has_eeprom_data = true;
out: out:
put_device(dev); ptp_ocp_nvmem_device_put(&nvmem);
return;
read_fail:
dev_err(&bp->pdev->dev, "could not read eeprom: %d\n", ret);
goto out;
}
static int
ptp_ocp_firstchild(struct device *dev, void *data)
{
return 1;
} }
static struct device * static struct device *
...@@ -1091,34 +1140,33 @@ ptp_ocp_devlink_info_get(struct devlink *devlink, struct devlink_info_req *req, ...@@ -1091,34 +1140,33 @@ ptp_ocp_devlink_info_get(struct devlink *devlink, struct devlink_info_req *req,
if (err) if (err)
return err; return err;
if (bp->image) { if (bp->fw_version & 0xffff) {
u32 ver = ioread32(&bp->image->version); sprintf(buf, "%d", bp->fw_version);
err = devlink_info_version_running_put(req, "fw", buf);
if (ver & 0xffff) { } else {
sprintf(buf, "%d", ver); sprintf(buf, "%d", bp->fw_version >> 16);
err = devlink_info_version_running_put(req, err = devlink_info_version_running_put(req, "loader", buf);
"fw",
buf);
} else {
sprintf(buf, "%d", ver >> 16);
err = devlink_info_version_running_put(req,
"loader",
buf);
}
if (err)
return err;
} }
if (err)
return err;
if (!bp->has_serial) if (!bp->has_eeprom_data) {
ptp_ocp_get_serial_number(bp); ptp_ocp_read_eeprom(bp);
if (!bp->has_eeprom_data)
if (bp->has_serial) { return 0;
sprintf(buf, "%pM", bp->serial);
err = devlink_info_serial_number_put(req, buf);
if (err)
return err;
} }
sprintf(buf, "%pM", bp->serial);
err = devlink_info_serial_number_put(req, buf);
if (err)
return err;
err = devlink_info_version_fixed_put(req,
DEVLINK_INFO_VERSION_GENERIC_BOARD_ID,
bp->board_id);
if (err)
return err;
return 0; return 0;
} }
...@@ -1412,6 +1460,8 @@ static int ...@@ -1412,6 +1460,8 @@ static int
ptp_ocp_fb_board_init(struct ptp_ocp *bp, struct ocp_resource *r) 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->fw_version = ioread32(&bp->image->version);
ptp_ocp_tod_init(bp); ptp_ocp_tod_init(bp);
ptp_ocp_nmea_out_init(bp); ptp_ocp_nmea_out_init(bp);
...@@ -1810,8 +1860,8 @@ serialnum_show(struct device *dev, struct device_attribute *attr, char *buf) ...@@ -1810,8 +1860,8 @@ serialnum_show(struct device *dev, struct device_attribute *attr, char *buf)
{ {
struct ptp_ocp *bp = dev_get_drvdata(dev); struct ptp_ocp *bp = dev_get_drvdata(dev);
if (!bp->has_serial) if (!bp->has_eeprom_data)
ptp_ocp_get_serial_number(bp); ptp_ocp_read_eeprom(bp);
return sysfs_emit(buf, "%pM\n", bp->serial); return sysfs_emit(buf, "%pM\n", bp->serial);
} }
...@@ -2520,17 +2570,14 @@ ptp_ocp_info(struct ptp_ocp *bp) ...@@ -2520,17 +2570,14 @@ ptp_ocp_info(struct ptp_ocp *bp)
ptp_ocp_phc_info(bp); ptp_ocp_phc_info(bp);
if (bp->image) { dev_info(dev, "version %x\n", bp->fw_version);
u32 ver = ioread32(&bp->image->version); if (bp->fw_version & 0xffff)
dev_info(dev, "regular image, version %d\n",
bp->fw_version & 0xffff);
else
dev_info(dev, "golden image, version %d\n",
bp->fw_version >> 16);
dev_info(dev, "version %x\n", ver);
if (ver & 0xffff)
dev_info(dev, "regular image, version %d\n",
ver & 0xffff);
else
dev_info(dev, "golden image, version %d\n",
ver >> 16);
}
ptp_ocp_serial_info(dev, "GNSS", bp->gnss_port, 115200); ptp_ocp_serial_info(dev, "GNSS", bp->gnss_port, 115200);
ptp_ocp_serial_info(dev, "GNSS2", bp->gnss2_port, 115200); ptp_ocp_serial_info(dev, "GNSS2", bp->gnss2_port, 115200);
ptp_ocp_serial_info(dev, "MAC", bp->mac_port, 57600); ptp_ocp_serial_info(dev, "MAC", bp->mac_port, 57600);
......
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