edac: change the mem allocation scheme to make Documentation/kobject.txt happy
[deliverable/linux.git] / drivers / edac / edac_mc_sysfs.c
index 0f671907c90bdd584e703bcee11806f9f5d3d32f..87b8d7d6385fd627b542a157034f639efe8686e6 100644 (file)
@@ -82,7 +82,7 @@ module_param_call(edac_mc_poll_msec, edac_set_poll_msec, param_get_int,
                  &edac_mc_poll_msec, 0644);
 MODULE_PARM_DESC(edac_mc_poll_msec, "Polling period in milliseconds");
 
-static struct device mci_pdev;
+static struct device *mci_pdev;
 
 /*
  * various constants for Memory Controllers
@@ -181,7 +181,7 @@ static ssize_t csrow_size_show(struct device *dev,
        u32 nr_pages = 0;
 
        for (i = 0; i < csrow->nr_channels; i++)
-               nr_pages += csrow->channels[i].dimm->nr_pages;
+               nr_pages += csrow->channels[i]->dimm->nr_pages;
        return sprintf(data, "%u\n", PAGES_TO_MiB(nr_pages));
 }
 
@@ -190,7 +190,7 @@ static ssize_t csrow_mem_type_show(struct device *dev,
 {
        struct csrow_info *csrow = to_csrow(dev);
 
-       return sprintf(data, "%s\n", mem_types[csrow->channels[0].dimm->mtype]);
+       return sprintf(data, "%s\n", mem_types[csrow->channels[0]->dimm->mtype]);
 }
 
 static ssize_t csrow_dev_type_show(struct device *dev,
@@ -198,7 +198,7 @@ static ssize_t csrow_dev_type_show(struct device *dev,
 {
        struct csrow_info *csrow = to_csrow(dev);
 
-       return sprintf(data, "%s\n", dev_types[csrow->channels[0].dimm->dtype]);
+       return sprintf(data, "%s\n", dev_types[csrow->channels[0]->dimm->dtype]);
 }
 
 static ssize_t csrow_edac_mode_show(struct device *dev,
@@ -207,7 +207,7 @@ static ssize_t csrow_edac_mode_show(struct device *dev,
 {
        struct csrow_info *csrow = to_csrow(dev);
 
-       return sprintf(data, "%s\n", edac_caps[csrow->channels[0].dimm->edac_mode]);
+       return sprintf(data, "%s\n", edac_caps[csrow->channels[0]->dimm->edac_mode]);
 }
 
 /* show/store functions for DIMM Label attributes */
@@ -217,7 +217,7 @@ static ssize_t channel_dimm_label_show(struct device *dev,
 {
        struct csrow_info *csrow = to_csrow(dev);
        unsigned chan = to_channel(mattr);
-       struct rank_info *rank = &csrow->channels[chan];
+       struct rank_info *rank = csrow->channels[chan];
 
        /* if field has not been initialized, there is nothing to send */
        if (!rank->dimm->label[0])
@@ -233,7 +233,7 @@ static ssize_t channel_dimm_label_store(struct device *dev,
 {
        struct csrow_info *csrow = to_csrow(dev);
        unsigned chan = to_channel(mattr);
-       struct rank_info *rank = &csrow->channels[chan];
+       struct rank_info *rank = csrow->channels[chan];
 
        ssize_t max_size = 0;
 
@@ -250,7 +250,7 @@ static ssize_t channel_ce_count_show(struct device *dev,
 {
        struct csrow_info *csrow = to_csrow(dev);
        unsigned chan = to_channel(mattr);
-       struct rank_info *rank = &csrow->channels[chan];
+       struct rank_info *rank = csrow->channels[chan];
 
        return sprintf(data, "%u\n", rank->ce_count);
 }
@@ -283,9 +283,12 @@ static const struct attribute_group *csrow_attr_groups[] = {
        NULL
 };
 
-static void csrow_attr_release(struct device *device)
+static void csrow_attr_release(struct device *dev)
 {
-       debugf1("Releasing csrow device %s\n", dev_name(device));
+       struct csrow_info *csrow = container_of(dev, struct csrow_info, dev);
+
+       debugf1("Releasing csrow device %s\n", dev_name(dev));
+       kfree(csrow);
 }
 
 static struct device_type csrow_attr_type = {
@@ -352,7 +355,7 @@ static inline int nr_pages_per_csrow(struct csrow_info *csrow)
        int chan, nr_pages = 0;
 
        for (chan = 0; chan < csrow->nr_channels; chan++)
-               nr_pages += csrow->channels[chan].dimm->nr_pages;
+               nr_pages += csrow->channels[chan]->dimm->nr_pages;
 
        return nr_pages;
 }
@@ -382,7 +385,7 @@ static int edac_create_csrow_object(struct mem_ctl_info *mci,
 
        for (chan = 0; chan < csrow->nr_channels; chan++) {
                /* Only expose populated DIMMs */
-               if (!csrow->channels[chan].dimm->nr_pages)
+               if (!csrow->channels[chan]->dimm->nr_pages)
                        continue;
                err = device_create_file(&csrow->dev,
                                         dynamic_csrow_dimm_attr[chan]);
@@ -418,10 +421,10 @@ static int edac_create_csrow_objects(struct mem_ctl_info *mci)
        struct csrow_info *csrow;
 
        for (i = 0; i < mci->nr_csrows; i++) {
-               csrow = &mci->csrows[i];
+               csrow = mci->csrows[i];
                if (!nr_pages_per_csrow(csrow))
                        continue;
-               err = edac_create_csrow_object(mci, &mci->csrows[i], i);
+               err = edac_create_csrow_object(mci, mci->csrows[i], i);
                if (err < 0)
                        goto error;
        }
@@ -429,18 +432,18 @@ static int edac_create_csrow_objects(struct mem_ctl_info *mci)
 
 error:
        for (--i; i >= 0; i--) {
-               csrow = &mci->csrows[i];
+               csrow = mci->csrows[i];
                if (!nr_pages_per_csrow(csrow))
                        continue;
                for (chan = csrow->nr_channels - 1; chan >= 0; chan--) {
-                       if (!csrow->channels[chan].dimm->nr_pages)
+                       if (!csrow->channels[chan]->dimm->nr_pages)
                                continue;
                        device_remove_file(&csrow->dev,
                                                dynamic_csrow_dimm_attr[chan]);
                        device_remove_file(&csrow->dev,
                                                dynamic_csrow_ce_count_attr[chan]);
                }
-               put_device(&mci->csrows[i].dev);
+               put_device(&mci->csrows[i]->dev);
        }
 
        return err;
@@ -452,11 +455,11 @@ static void edac_delete_csrow_objects(struct mem_ctl_info *mci)
        struct csrow_info *csrow;
 
        for (i = mci->nr_csrows - 1; i >= 0; i--) {
-               csrow = &mci->csrows[i];
+               csrow = mci->csrows[i];
                if (!nr_pages_per_csrow(csrow))
                        continue;
                for (chan = csrow->nr_channels - 1; chan >= 0; chan--) {
-                       if (!csrow->channels[chan].dimm->nr_pages)
+                       if (!csrow->channels[chan]->dimm->nr_pages)
                                continue;
                        debugf1("Removing csrow %d channel %d sysfs nodes\n",
                                i, chan);
@@ -465,8 +468,8 @@ static void edac_delete_csrow_objects(struct mem_ctl_info *mci)
                        device_remove_file(&csrow->dev,
                                                dynamic_csrow_ce_count_attr[chan]);
                }
-               put_device(&mci->csrows[i].dev);
-               device_del(&mci->csrows[i].dev);
+               put_device(&mci->csrows[i]->dev);
+               device_del(&mci->csrows[i]->dev);
        }
 }
 #endif
@@ -585,9 +588,12 @@ static const struct attribute_group *dimm_attr_groups[] = {
        NULL
 };
 
-static void dimm_attr_release(struct device *device)
+static void dimm_attr_release(struct device *dev)
 {
-       debugf1("Releasing dimm device %s\n", dev_name(device));
+       struct dimm_info *dimm = container_of(dev, struct dimm_info, dev);
+
+       debugf1("Releasing dimm device %s\n", dev_name(dev));
+       kfree(dimm);
 }
 
 static struct device_type dimm_attr_type = {
@@ -641,13 +647,13 @@ static ssize_t mci_reset_counters_store(struct device *dev,
        mci->ce_noinfo_count = 0;
 
        for (row = 0; row < mci->nr_csrows; row++) {
-               struct csrow_info *ri = &mci->csrows[row];
+               struct csrow_info *ri = mci->csrows[row];
 
                ri->ue_count = 0;
                ri->ce_count = 0;
 
                for (chan = 0; chan < ri->nr_channels; chan++)
-                       ri->channels[chan].ce_count = 0;
+                       ri->channels[chan]->ce_count = 0;
        }
 
        cnt = 1;
@@ -779,10 +785,10 @@ static ssize_t mci_size_mb_show(struct device *dev,
        int total_pages = 0, csrow_idx, j;
 
        for (csrow_idx = 0; csrow_idx < mci->nr_csrows; csrow_idx++) {
-               struct csrow_info *csrow = &mci->csrows[csrow_idx];
+               struct csrow_info *csrow = mci->csrows[csrow_idx];
 
                for (j = 0; j < csrow->nr_channels; j++) {
-                       struct dimm_info *dimm = csrow->channels[j].dimm;
+                       struct dimm_info *dimm = csrow->channels[j]->dimm;
 
                        total_pages += dimm->nr_pages;
                }
@@ -889,9 +895,12 @@ static const struct attribute_group *mci_attr_groups[] = {
        NULL
 };
 
-static void mci_attr_release(struct device *device)
+static void mci_attr_release(struct device *dev)
 {
-       debugf1("Releasing mci device %s\n", dev_name(device));
+       struct mem_ctl_info *mci = container_of(dev, struct mem_ctl_info, dev);
+
+       debugf1("Releasing csrow device %s\n", dev_name(dev));
+       kfree(mci);
 }
 
 static struct device_type mci_attr_type = {
@@ -950,29 +959,28 @@ int edac_create_sysfs_mci_device(struct mem_ctl_info *mci)
 {
        int i, err;
 
-       debugf0("%s() idx=%d\n", __func__, mci->mc_idx);
+       /*
+        * The memory controller needs its own bus, in order to avoid
+        * namespace conflicts at /sys/bus/edac.
+        */
+       mci->bus.name = kasprintf(GFP_KERNEL, "mc%d", mci->mc_idx);
+       if (!mci->bus.name)
+               return -ENOMEM;
+       debugf0("creating bus %s\n",mci->bus.name);
+       err = bus_register(&mci->bus);
+       if (err < 0)
+               return err;
 
        /* get the /sys/devices/system/edac subsys reference */
-
        mci->dev.type = &mci_attr_type;
        device_initialize(&mci->dev);
 
-       mci->dev.parent = &mci_pdev;
+       mci->dev.parent = mci_pdev;
        mci->dev.bus = &mci->bus;
        dev_set_name(&mci->dev, "mc%d", mci->mc_idx);
        dev_set_drvdata(&mci->dev, mci);
        pm_runtime_forbid(&mci->dev);
 
-       /*
-        * The memory controller needs its own bus, in order to avoid
-        * namespace conflicts at /sys/bus/edac.
-        */
-       debugf0("creating bus %s\n",mci->bus.name);
-       mci->bus.name = kstrdup(dev_name(&mci->dev), GFP_KERNEL);
-       err = bus_register(&mci->bus);
-       if (err < 0)
-               return err;
-
        debugf0("%s(): creating device %s\n", __func__,
                dev_name(&mci->dev));
        err = device_add(&mci->dev);
@@ -986,7 +994,7 @@ int edac_create_sysfs_mci_device(struct mem_ctl_info *mci)
         * Create the dimm/rank devices
         */
        for (i = 0; i < mci->tot_dimms; i++) {
-               struct dimm_info *dimm = &mci->dimms[i];
+               struct dimm_info *dimm = mci->dimms[i];
                /* Only expose populated DIMMs */
                if (dimm->nr_pages == 0)
                        continue;
@@ -1023,7 +1031,7 @@ int edac_create_sysfs_mci_device(struct mem_ctl_info *mci)
 
 fail:
        for (i--; i >= 0; i--) {
-               struct dimm_info *dimm = &mci->dimms[i];
+               struct dimm_info *dimm = mci->dimms[i];
                if (dimm->nr_pages == 0)
                        continue;
                put_device(&dimm->dev);
@@ -1053,7 +1061,7 @@ void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci)
 #endif
 
        for (i = 0; i < mci->tot_dimms; i++) {
-               struct dimm_info *dimm = &mci->dimms[i];
+               struct dimm_info *dimm = mci->dimms[i];
                if (dimm->nr_pages == 0)
                        continue;
                debugf0("%s(): removing device %s\n", __func__,
@@ -1072,9 +1080,15 @@ void edac_unregister_sysfs(struct mem_ctl_info *mci)
        kfree(mci->bus.name);
 }
 
-static void mc_attr_release(struct device *device)
+static void mc_attr_release(struct device *dev)
 {
-       debugf1("Releasing device %s\n", dev_name(device));
+       /*
+        * There's no container structure here, as this is just the mci
+        * parent device, used to create the /sys/devices/mc sysfs node.
+        * So, there are no attributes on it.
+        */
+       debugf1("Releasing device %s\n", dev_name(dev));
+       kfree(dev);
 }
 
 static struct device_type mc_attr_type = {
@@ -1095,21 +1109,25 @@ int __init edac_mc_sysfs_init(void)
                return -EINVAL;
        }
 
-       mci_pdev.bus = edac_subsys;
-       mci_pdev.type = &mc_attr_type;
-       device_initialize(&mci_pdev);
-       dev_set_name(&mci_pdev, "mc");
+       mci_pdev = kzalloc(sizeof(*mci_pdev), GFP_KERNEL);
+
+       mci_pdev->bus = edac_subsys;
+       mci_pdev->type = &mc_attr_type;
+       device_initialize(mci_pdev);
+       dev_set_name(mci_pdev, "mc");
 
-       err = device_add(&mci_pdev);
+       err = device_add(mci_pdev);
        if (err < 0)
                return err;
 
+       debugf0("device %s created\n", dev_name(mci_pdev));
+
        return 0;
 }
 
 void __exit edac_mc_sysfs_exit(void)
 {
-       put_device(&mci_pdev);
-       device_del(&mci_pdev);
+       put_device(mci_pdev);
+       device_del(mci_pdev);
        edac_put_sysfs_subsys();
 }
This page took 0.029193 seconds and 5 git commands to generate.