summaryrefslogtreecommitdiff
path: root/arch/powerpc/kernel/vio.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kernel/vio.c')
-rw-r--r--arch/powerpc/kernel/vio.c114
1 files changed, 63 insertions, 51 deletions
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
index 536016d..76a6482 100644
--- a/arch/powerpc/kernel/vio.c
+++ b/arch/powerpc/kernel/vio.c
@@ -997,21 +997,36 @@ static struct device_attribute vio_cmo_dev_attrs[] = {
/* sysfs bus functions and data structures for CMO */
#define viobus_cmo_rd_attr(name) \
-static ssize_t \
-viobus_cmo_##name##_show(struct bus_type *bt, char *buf) \
+static ssize_t cmo_##name##_show(struct bus_type *bt, char *buf) \
{ \
return sprintf(buf, "%lu\n", vio_cmo.name); \
-}
+} \
+static BUS_ATTR_RO(cmo_##name)
#define viobus_cmo_pool_rd_attr(name, var) \
static ssize_t \
-viobus_cmo_##name##_pool_show_##var(struct bus_type *bt, char *buf) \
+cmo_##name##_##var##_show(struct bus_type *bt, char *buf) \
{ \
return sprintf(buf, "%lu\n", vio_cmo.name.var); \
+} \
+static BUS_ATTR_RO(cmo_##name##_##var)
+
+viobus_cmo_rd_attr(entitled);
+viobus_cmo_rd_attr(spare);
+viobus_cmo_rd_attr(min);
+viobus_cmo_rd_attr(desired);
+viobus_cmo_rd_attr(curr);
+viobus_cmo_pool_rd_attr(reserve, size);
+viobus_cmo_pool_rd_attr(excess, size);
+viobus_cmo_pool_rd_attr(excess, free);
+
+static ssize_t cmo_high_show(struct bus_type *bt, char *buf)
+{
+ return sprintf(buf, "%lu\n", vio_cmo.high);
}
-static ssize_t viobus_cmo_high_reset(struct bus_type *bt, const char *buf,
- size_t count)
+static ssize_t cmo_high_store(struct bus_type *bt, const char *buf,
+ size_t count)
{
unsigned long flags;
@@ -1021,35 +1036,26 @@ static ssize_t viobus_cmo_high_reset(struct bus_type *bt, const char *buf,
return count;
}
-
-viobus_cmo_rd_attr(entitled);
-viobus_cmo_pool_rd_attr(reserve, size);
-viobus_cmo_pool_rd_attr(excess, size);
-viobus_cmo_pool_rd_attr(excess, free);
-viobus_cmo_rd_attr(spare);
-viobus_cmo_rd_attr(min);
-viobus_cmo_rd_attr(desired);
-viobus_cmo_rd_attr(curr);
-viobus_cmo_rd_attr(high);
-
-static struct bus_attribute vio_cmo_bus_attrs[] = {
- __ATTR(cmo_entitled, S_IRUGO, viobus_cmo_entitled_show, NULL),
- __ATTR(cmo_reserve_size, S_IRUGO, viobus_cmo_reserve_pool_show_size, NULL),
- __ATTR(cmo_excess_size, S_IRUGO, viobus_cmo_excess_pool_show_size, NULL),
- __ATTR(cmo_excess_free, S_IRUGO, viobus_cmo_excess_pool_show_free, NULL),
- __ATTR(cmo_spare, S_IRUGO, viobus_cmo_spare_show, NULL),
- __ATTR(cmo_min, S_IRUGO, viobus_cmo_min_show, NULL),
- __ATTR(cmo_desired, S_IRUGO, viobus_cmo_desired_show, NULL),
- __ATTR(cmo_curr, S_IRUGO, viobus_cmo_curr_show, NULL),
- __ATTR(cmo_high, S_IWUSR|S_IRUSR|S_IWGRP|S_IRGRP|S_IROTH,
- viobus_cmo_high_show, viobus_cmo_high_reset),
- __ATTR_NULL
+static BUS_ATTR_RW(cmo_high);
+
+static struct attribute *vio_bus_attrs[] = {
+ &bus_attr_cmo_entitled.attr,
+ &bus_attr_cmo_spare.attr,
+ &bus_attr_cmo_min.attr,
+ &bus_attr_cmo_desired.attr,
+ &bus_attr_cmo_curr.attr,
+ &bus_attr_cmo_high.attr,
+ &bus_attr_cmo_reserve_size.attr,
+ &bus_attr_cmo_excess_size.attr,
+ &bus_attr_cmo_excess_free.attr,
+ NULL,
};
+ATTRIBUTE_GROUPS(vio_bus);
static void vio_cmo_sysfs_init(void)
{
vio_bus_type.dev_attrs = vio_cmo_dev_attrs;
- vio_bus_type.bus_attrs = vio_cmo_bus_attrs;
+ vio_bus_type.bus_groups = vio_bus_groups;
}
#else /* CONFIG_PPC_SMLPAR */
int vio_cmo_entitlement_update(size_t new_entitlement) { return 0; }
@@ -1153,7 +1159,7 @@ EXPORT_SYMBOL(vio_h_cop_sync);
static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev)
{
- const unsigned char *dma_window;
+ const __be32 *dma_window;
struct iommu_table *tbl;
unsigned long offset, size;
@@ -1312,8 +1318,7 @@ struct vio_dev *vio_register_device_node(struct device_node *of_node)
{
struct vio_dev *viodev;
struct device_node *parent_node;
- const unsigned int *unit_address;
- const unsigned int *pfo_resid = NULL;
+ const __be32 *prop;
enum vio_dev_family family;
const char *of_node_name = of_node->name ? of_node->name : "<unknown>";
@@ -1360,6 +1365,8 @@ struct vio_dev *vio_register_device_node(struct device_node *of_node)
/* we need the 'device_type' property, in order to match with drivers */
viodev->family = family;
if (viodev->family == VDEVICE) {
+ unsigned int unit_address;
+
if (of_node->type != NULL)
viodev->type = of_node->type;
else {
@@ -1368,24 +1375,24 @@ struct vio_dev *vio_register_device_node(struct device_node *of_node)
goto out;
}
- unit_address = of_get_property(of_node, "reg", NULL);
- if (unit_address == NULL) {
+ prop = of_get_property(of_node, "reg", NULL);
+ if (prop == NULL) {
pr_warn("%s: node %s missing 'reg'\n",
__func__, of_node_name);
goto out;
}
- dev_set_name(&viodev->dev, "%x", *unit_address);
+ unit_address = of_read_number(prop, 1);
+ dev_set_name(&viodev->dev, "%x", unit_address);
viodev->irq = irq_of_parse_and_map(of_node, 0);
- viodev->unit_address = *unit_address;
+ viodev->unit_address = unit_address;
} else {
/* PFO devices need their resource_id for submitting COP_OPs
* This is an optional field for devices, but is required when
* performing synchronous ops */
- pfo_resid = of_get_property(of_node, "ibm,resource-id", NULL);
- if (pfo_resid != NULL)
- viodev->resource_id = *pfo_resid;
+ prop = of_get_property(of_node, "ibm,resource-id", NULL);
+ if (prop != NULL)
+ viodev->resource_id = of_read_number(prop, 1);
- unit_address = NULL;
dev_set_name(&viodev->dev, "%s", of_node_name);
viodev->type = of_node_name;
viodev->irq = 0;
@@ -1412,8 +1419,7 @@ struct vio_dev *vio_register_device_node(struct device_node *of_node)
/* needed to ensure proper operation of coherent allocations
* later, in case driver doesn't set it explicitly */
- dma_set_mask(&viodev->dev, DMA_BIT_MASK(64));
- dma_set_coherent_mask(&viodev->dev, DMA_BIT_MASK(64));
+ dma_coerce_mask_and_coherent(&viodev->dev, DMA_BIT_MASK(64));
}
/* register with generic device framework */
@@ -1529,11 +1535,15 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
const char *cp;
dn = dev->of_node;
- if (!dn)
- return -ENODEV;
+ if (!dn) {
+ strcpy(buf, "\n");
+ return strlen(buf);
+ }
cp = of_get_property(dn, "compatible", NULL);
- if (!cp)
- return -ENODEV;
+ if (!cp) {
+ strcpy(buf, "\n");
+ return strlen(buf);
+ }
return sprintf(buf, "vio:T%sS%s\n", vio_dev->type, cp);
}
@@ -1622,7 +1632,6 @@ static struct vio_dev *vio_find_name(const char *name)
*/
struct vio_dev *vio_find_node(struct device_node *vnode)
{
- const uint32_t *unit_address;
char kobj_name[20];
struct device_node *vnode_parent;
const char *dev_type;
@@ -1638,10 +1647,13 @@ struct vio_dev *vio_find_node(struct device_node *vnode)
/* construct the kobject name from the device node */
if (!strcmp(dev_type, "vdevice")) {
- unit_address = of_get_property(vnode, "reg", NULL);
- if (!unit_address)
+ const __be32 *prop;
+
+ prop = of_get_property(vnode, "reg", NULL);
+ if (!prop)
return NULL;
- snprintf(kobj_name, sizeof(kobj_name), "%x", *unit_address);
+ snprintf(kobj_name, sizeof(kobj_name), "%x",
+ (uint32_t)of_read_number(prop, 1));
} else if (!strcmp(dev_type, "ibm,platform-facilities"))
snprintf(kobj_name, sizeof(kobj_name), "%s", vnode->name);
else