[PATCH 09/12] misc: flexcard: add device attributes

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Add device attributes for common flexcard information access. The
attribiutes are read-only execpt "uid" (user ID register).
The "uid" attribute can also be used to change the user-defined ID of a
Flexcard.

Signed-off-by: Benedikt Spranger <b.spranger@xxxxxxxxxxxxx>
Signed-off-by: Holger Dengler <dengler@xxxxxxxxxxxxx>
cc: Arnd Bergmann <arnd@xxxxxxxx>
cc: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>
---
 drivers/misc/flexcard_misc.c | 196 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 196 insertions(+)

diff --git a/drivers/misc/flexcard_misc.c b/drivers/misc/flexcard_misc.c
index 93c951c..2a5c006 100644
--- a/drivers/misc/flexcard_misc.c
+++ b/drivers/misc/flexcard_misc.c
@@ -31,6 +31,183 @@ struct flexcard_misc {
 	struct fc_bar0_nf __iomem	*nf;
 };
 
+static ssize_t fw_version_show(struct device *dev,
+			       struct device_attribute *attr, char *buf)
+{
+	struct flexcard_misc *priv = dev_get_drvdata(dev);
+	union {
+		struct fc_version ver;
+		u32 reg;
+	} fw_ver;
+
+	fw_ver.reg = readl(&priv->conf->fc_fw_ver);
+	return sprintf(buf, "%02x.%02x.%02x\n",
+		       fw_ver.ver.maj, fw_ver.ver.min, fw_ver.ver.dev);
+}
+static DEVICE_ATTR_RO(fw_version);
+
+static ssize_t hw_version_show(struct device *dev,
+			       struct device_attribute *attr, char *buf)
+{
+	struct flexcard_misc *priv = dev_get_drvdata(dev);
+	union {
+		struct fc_version ver;
+		u32 reg;
+	} hw_ver;
+
+	hw_ver.reg = readl(&priv->conf->fc_hw_ver);
+	return sprintf(buf, "%02x.%02x.%02x\n",
+		       hw_ver.ver.maj, hw_ver.ver.min, hw_ver.ver.dev);
+}
+static DEVICE_ATTR_RO(hw_version);
+
+static ssize_t serialno_show(struct device *dev,
+			     struct device_attribute *attr, char *buf)
+{
+	struct flexcard_misc *priv = dev_get_drvdata(dev);
+	u64 fc_sn;
+
+	fc_sn = readq(&priv->conf->fc_sn);
+	return sprintf(buf, "%lld\n", fc_sn);
+}
+static DEVICE_ATTR_RO(serialno);
+
+static ssize_t tiny_stat_show(struct device *dev,
+			      struct device_attribute *attr, char *buf)
+{
+	struct flexcard_misc *priv = dev_get_drvdata(dev);
+
+	return sprintf(buf, "0x%x\n", readl(&priv->conf->tiny_stat));
+}
+static DEVICE_ATTR_RO(tiny_stat);
+
+static ssize_t can_dat_show(struct device *dev,
+			    struct device_attribute *attr, char *buf)
+{
+	struct flexcard_misc *priv = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%d\n", readl(&priv->conf->can_dat_cnt));
+}
+static DEVICE_ATTR_RO(can_dat);
+
+static ssize_t can_err_show(struct device *dev,
+			    struct device_attribute *attr, char *buf)
+{
+	struct flexcard_misc *priv = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%d\n", readl(&priv->conf->can_err_cnt));
+}
+static DEVICE_ATTR_RO(can_err);
+
+static ssize_t fc_data_show(struct device *dev,
+			    struct device_attribute *attr, char *buf)
+{
+	struct flexcard_misc *priv = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%d\n", readl(&priv->conf->fc_data_cnt));
+}
+static DEVICE_ATTR_RO(fc_data);
+
+static ssize_t fr_rx_show(struct device *dev,
+			    struct device_attribute *attr, char *buf)
+{
+	struct flexcard_misc *priv = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%d\n", readl(&priv->conf->fr_rx_cnt));
+}
+static DEVICE_ATTR_RO(fr_rx);
+
+static ssize_t fr_tx_show(struct device *dev,
+			    struct device_attribute *attr, char *buf)
+{
+	struct flexcard_misc *priv = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%d\n", readl(&priv->conf->fr_tx_cnt));
+}
+static DEVICE_ATTR_RO(fr_tx);
+
+static ssize_t nmv_show(struct device *dev,
+			struct device_attribute *attr, char *buf)
+{
+	struct flexcard_misc *priv = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%d\n", readl(&priv->conf->nmv_cnt));
+}
+static DEVICE_ATTR_RO(nmv);
+
+static ssize_t info_show(struct device *dev,
+			 struct device_attribute *attr, char *buf)
+{
+	struct flexcard_misc *priv = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%d\n", readl(&priv->conf->info_cnt));
+}
+static DEVICE_ATTR_RO(info);
+
+static ssize_t stat_trg_show(struct device *dev,
+			     struct device_attribute *attr, char *buf)
+{
+	struct flexcard_misc *priv = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%d\n", readl(&priv->conf->stat_trg_cnt));
+}
+static DEVICE_ATTR_RO(stat_trg);
+
+static ssize_t nf_show(struct device *dev,
+		       struct device_attribute *attr, char *buf)
+{
+	struct flexcard_misc *priv = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%d\n", readl(&priv->nf->nf_cnt));
+}
+static DEVICE_ATTR_RO(nf);
+
+static ssize_t uid_store(struct device *dev, struct device_attribute *attr,
+			 const char *buf, size_t count)
+{
+	struct flexcard_misc *priv = dev_get_drvdata(dev);
+	u32 uid;
+	int ret;
+
+	ret = kstrtou32(buf, 0, &uid);
+	if (ret)
+		return ret;
+
+	writel(uid, &priv->conf->fc_uid);
+	return count;
+}
+
+static ssize_t uid_show(struct device *dev,
+			struct device_attribute *attr, char *buf)
+{
+	struct flexcard_misc *priv = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%u\n", readl(&priv->conf->fc_uid));
+}
+static DEVICE_ATTR(uid, 0644, uid_show, uid_store);
+
+static struct attribute *flexcard_misc_dev_attrs[] = {
+	&dev_attr_fw_version.attr,
+	&dev_attr_hw_version.attr,
+	&dev_attr_serialno.attr,
+	&dev_attr_tiny_stat.attr,
+	&dev_attr_can_dat.attr,
+	&dev_attr_can_err.attr,
+	&dev_attr_fc_data.attr,
+	&dev_attr_fr_rx.attr,
+	&dev_attr_fr_tx.attr,
+	&dev_attr_nmv.attr,
+	&dev_attr_info.attr,
+	&dev_attr_stat_trg.attr,
+	&dev_attr_nf.attr,
+	&dev_attr_uid.attr,
+	NULL,
+};
+
+static const struct attribute_group flexcard_misc_dev_group = {
+	.attrs = flexcard_misc_dev_attrs,
+};
+
 static int flexcard_misc_mmap(struct file *filp, struct vm_area_struct *vma)
 {
 	unsigned long offset, vsize, psize, addr;
@@ -109,6 +286,7 @@ static int flexcard_misc_iomap(struct platform_device *pdev)
 static int flexcard_misc_probe(struct platform_device *pdev)
 {
 	struct flexcard_misc *priv;
+	struct device *this_device;
 	int ret;
 
 	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
@@ -137,13 +315,31 @@ static int flexcard_misc_probe(struct platform_device *pdev)
 		return ret;
 	}
 
+	this_device = priv->dev.this_device;
+	dev_set_drvdata(this_device, priv);
+
+	ret = sysfs_create_group(&this_device->kobj,
+				 &flexcard_misc_dev_group);
+	if (ret) {
+		dev_err(&pdev->dev,
+			"failed to create sysfs attributes: %d\n", ret);
+		goto out;
+	}
+
 	return 0;
+
+out:
+	misc_deregister(&priv->dev);
+	return ret;
 }
 
 static int flexcard_misc_remove(struct platform_device *pdev)
 {
 	struct flexcard_misc *priv = platform_get_drvdata(pdev);
+	struct device *this_device = priv->dev.this_device;
 
+	sysfs_remove_group(&this_device->kobj,
+			   &flexcard_misc_dev_group);
 	misc_deregister(&priv->dev);
 
 	return 0;
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe dmaengine" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux Kernel]     [Linux ARM (vger)]     [Linux ARM MSM]     [Linux Omap]     [Linux Arm]     [Linux Tegra]     [Fedora ARM]     [Linux for Samsung SOC]     [eCos]     [Linux PCI]     [Linux Fastboot]     [Gcc Help]     [Git]     [DCCP]     [IETF Announce]     [Security]     [Linux MIPS]     [Yosemite Campsites]

  Powered by Linux