mcb: export bus information via sysfs
authorJohannes Thumshirn <jthumshirn@suse.de>
Tue, 3 May 2016 07:46:23 +0000 (09:46 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 3 May 2016 22:07:35 +0000 (15:07 -0700)
Export information about the bus stored in the FPGA's header to userspace via
sysfs, instead of hiding it in pr_debug()s from everyone.

Signed-off-by: Johannes Thumshirn <jthumshirn@suse.de>
Reviewed-by: Andreas Werner <andreas.werner@men.de>
Tested-by: Andreas Werner <andreas.werner@men.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Documentation/ABI/testing/sysfs-bus-mcb [new file with mode: 0644]
drivers/mcb/mcb-core.c
drivers/mcb/mcb-internal.h
drivers/mcb/mcb-parse.c
include/linux/mcb.h

diff --git a/Documentation/ABI/testing/sysfs-bus-mcb b/Documentation/ABI/testing/sysfs-bus-mcb
new file mode 100644 (file)
index 0000000..77947c5
--- /dev/null
@@ -0,0 +1,29 @@
+What:          /sys/bus/mcb/devices/mcb:X
+Date:          March 2016
+KernelVersion: 4.7
+Contact:       Johannes Thumshirn <jth@kernel.org>
+Description:   Hardware chip or device hosting the MEN chameleon bus
+
+What:          /sys/bus/mcb/devices/mcb:X/revision
+Date:          March 2016
+KernelVersion: 4.7
+Contact:       Johannes Thumshirn <jth@kernel.org>
+Description:   The FPGA's revision number
+
+What:          /sys/bus/mcb/devices/mcb:X/minor
+Date:          March 2016
+KernelVersion: 4.7
+Contact:       Johannes Thumshirn <jth@kernel.org>
+Description:   The FPGA's minor number
+
+What:          /sys/bus/mcb/devices/mcb:X/model
+Date:          March 2016
+KernelVersion: 4.7
+Contact:       Johannes Thumshirn <jth@kernel.org>
+Description:   The FPGA's model number
+
+What:          /sys/bus/mcb/devices/mcb:X/name
+Date:          March 2016
+KernelVersion: 4.7
+Contact:       Johannes Thumshirn <jth@kernel.org>
+Description:   The FPGA's name
index 1e336cc56751a28323ea4a081426de09a50283e5..9ae4d15fc229d79d5086731e7aacb9e999e759e8 100644 (file)
@@ -90,6 +90,60 @@ static void mcb_shutdown(struct device *dev)
                mdrv->shutdown(mdev);
 }
 
+static ssize_t revision_show(struct device *dev, struct device_attribute *attr,
+                        char *buf)
+{
+       struct mcb_bus *bus = to_mcb_bus(dev);
+
+       return scnprintf(buf, PAGE_SIZE, "%d\n", bus->revision);
+}
+static DEVICE_ATTR_RO(revision);
+
+static ssize_t model_show(struct device *dev, struct device_attribute *attr,
+                        char *buf)
+{
+       struct mcb_bus *bus = to_mcb_bus(dev);
+
+       return scnprintf(buf, PAGE_SIZE, "%c\n", bus->model);
+}
+static DEVICE_ATTR_RO(model);
+
+static ssize_t minor_show(struct device *dev, struct device_attribute *attr,
+                        char *buf)
+{
+       struct mcb_bus *bus = to_mcb_bus(dev);
+
+       return scnprintf(buf, PAGE_SIZE, "%d\n", bus->minor);
+}
+static DEVICE_ATTR_RO(minor);
+
+static ssize_t name_show(struct device *dev, struct device_attribute *attr,
+                        char *buf)
+{
+       struct mcb_bus *bus = to_mcb_bus(dev);
+
+       return scnprintf(buf, PAGE_SIZE, "%s\n", bus->name);
+}
+static DEVICE_ATTR_RO(name);
+
+static struct attribute *mcb_bus_attrs[] = {
+       &dev_attr_revision.attr,
+       &dev_attr_model.attr,
+       &dev_attr_minor.attr,
+       &dev_attr_name.attr,
+       NULL,
+};
+
+static const struct attribute_group mcb_carrier_group = {
+       .attrs = mcb_bus_attrs,
+};
+
+static const struct attribute_group *mcb_carrier_groups[] = {
+       &mcb_carrier_group,
+       NULL,
+};
+
+
 static struct bus_type mcb_bus_type = {
        .name = "mcb",
        .match = mcb_match,
@@ -99,6 +153,11 @@ static struct bus_type mcb_bus_type = {
        .shutdown = mcb_shutdown,
 };
 
+static struct device_type mcb_carrier_device_type = {
+       .name = "mcb-carrier",
+       .groups = mcb_carrier_groups,
+};
+
 /**
  * __mcb_register_driver() - Register a @mcb_driver at the system
  * @drv: The @mcb_driver
@@ -205,6 +264,7 @@ struct mcb_bus *mcb_alloc_bus(struct device *carrier)
        device_initialize(&bus->dev);
        bus->dev.parent = carrier;
        bus->dev.bus = &mcb_bus_type;
+       bus->dev.type = &mcb_carrier_device_type;
 
        dev_set_name(&bus->dev, "mcb:%d", bus_nr);
        rc = device_add(&bus->dev);
index fb7493dcfb79f409a8f483480f1c8d50bdba2278..5254e0285725cc85f36b1a0258b9de41367f8e74 100644 (file)
@@ -5,7 +5,6 @@
 
 #define PCI_VENDOR_ID_MEN              0x1a88
 #define PCI_DEVICE_ID_MEN_CHAMELEON    0x4d45
-#define CHAMELEON_FILENAME_LEN         12
 #define CHAMELEONV2_MAGIC              0xabce
 #define CHAM_HEADER_SIZE               0x200
 
index 00492695526354f104b115c61546142d77d47c46..35f385b59221c14d4c08916560dbbe698bed6275 100644 (file)
@@ -113,16 +113,11 @@ int chameleon_parse_cells(struct mcb_bus *bus, phys_addr_t mapbase,
        }
        p += hsize;
 
-       pr_debug("header->revision = %d\n", header->revision);
-       pr_debug("header->model = 0x%x ('%c')\n", header->model,
-               header->model);
-       pr_debug("header->minor = %d\n", header->minor);
-       pr_debug("header->bus_type = 0x%x\n", header->bus_type);
-
-
-       pr_debug("header->magic = 0x%x\n", header->magic);
-       pr_debug("header->filename = \"%.*s\"\n", CHAMELEON_FILENAME_LEN,
-               header->filename);
+       bus->revision = header->revision;
+       bus->model = header->model;
+       bus->minor = header->minor;
+       snprintf(bus->name, CHAMELEON_FILENAME_LEN + 1, "%s",
+                header->filename);
 
        for_each_chameleon_cell(dtype, p) {
                switch (dtype) {
index 3efafbca166df1dbe170c4a67557ea08071d11f9..ead13d233a97e60392110d0b8bba43c3b7fa5e5a 100644 (file)
@@ -15,6 +15,8 @@
 #include <linux/device.h>
 #include <linux/irqreturn.h>
 
+#define CHAMELEON_FILENAME_LEN 12
+
 struct mcb_driver;
 struct mcb_device;
 
@@ -25,11 +27,18 @@ struct mcb_device;
  * @carrier: pointer to carrier device
  * @bus_nr: mcb bus number
  * @get_irq: callback to get IRQ number
+ * @revision: the FPGA's revision number
+ * @model: the FPGA's model number
+ * @filename: the FPGA's name
  */
 struct mcb_bus {
        struct device dev;
        struct device *carrier;
        int bus_nr;
+       u8 revision;
+       char model;
+       u8 minor;
+       char name[CHAMELEON_FILENAME_LEN + 1];
        int (*get_irq)(struct mcb_device *dev);
 };
 #define to_mcb_bus(b) container_of((b), struct mcb_bus, dev)