summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/base/driver.c4
-rw-r--r--drivers/block/virtio_blk.c6
-rw-r--r--drivers/hw_random/core.c12
-rw-r--r--drivers/hw_random/virtio-rng.c6
-rw-r--r--drivers/input/virtio_input.c5
-rw-r--r--drivers/of/overlay.c3
-rw-r--r--drivers/power/reset/nvmem-reboot-mode.c8
-rw-r--r--drivers/serial/virtio_console.c14
-rw-r--r--drivers/video/bcm2835.c21
9 files changed, 74 insertions, 5 deletions
diff --git a/drivers/base/driver.c b/drivers/base/driver.c
index 0e04ef3686..23d11d4dad 100644
--- a/drivers/base/driver.c
+++ b/drivers/base/driver.c
@@ -511,8 +511,10 @@ static void devices_shutdown(void)
struct device_d *dev;
list_for_each_entry(dev, &active, active) {
- if (dev->bus->remove)
+ if (dev->bus->remove) {
dev->bus->remove(dev);
+ dev->driver = NULL;
+ }
}
}
devshutdown_exitcall(devices_shutdown);
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
index b7a83cf686..87ab505f83 100644
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -95,6 +95,7 @@ static int virtio_blk_probe(struct virtio_device *vdev)
return ret;
priv->vdev = vdev;
+ vdev->priv = priv;
devnum = cdev_find_free_index("virtioblk");
priv->blk.cdev.name = xasprintf("virtioblk%d", devnum);
@@ -115,8 +116,13 @@ static int virtio_blk_probe(struct virtio_device *vdev)
static void virtio_blk_remove(struct virtio_device *vdev)
{
+ struct virtio_blk_priv *priv = vdev->priv;
+
vdev->config->reset(vdev);
+ blockdevice_unregister(&priv->blk);
vdev->config->del_vqs(vdev);
+
+ free(priv);
}
static const struct virtio_device_id id_table[] = {
diff --git a/drivers/hw_random/core.c b/drivers/hw_random/core.c
index ee3d5a52dd..86214dc8ba 100644
--- a/drivers/hw_random/core.c
+++ b/drivers/hw_random/core.c
@@ -92,6 +92,12 @@ static int hwrng_register_cdev(struct hwrng *rng)
return devfs_create(&rng->cdev);
}
+static void hwrng_unregister_cdev(struct hwrng *rng)
+{
+ devfs_remove(&rng->cdev);
+ free(rng->cdev.name);
+}
+
struct hwrng *hwrng_get_first(void)
{
if (list_empty(&hwrngs))
@@ -122,3 +128,9 @@ int hwrng_register(struct device_d *dev, struct hwrng *rng)
return err;
}
+
+void hwrng_unregister(struct hwrng *rng)
+{
+ hwrng_unregister_cdev(rng);
+ free(rng->buf);
+}
diff --git a/drivers/hw_random/virtio-rng.c b/drivers/hw_random/virtio-rng.c
index 7bdacc976e..f0a3d3cb74 100644
--- a/drivers/hw_random/virtio-rng.c
+++ b/drivers/hw_random/virtio-rng.c
@@ -78,8 +78,14 @@ static int virtrng_probe(struct virtio_device *vdev)
static void virtrng_remove(struct virtio_device *vdev)
{
+ struct virtrng_info *vi = vdev->priv;
+
vdev->config->reset(vdev);
+ if (vi->hwrng_register_done)
+ hwrng_unregister(&vi->hwrng);
vdev->config->del_vqs(vdev);
+
+ kfree(vi);
}
static void virtrng_scan(struct virtio_device *vdev)
diff --git a/drivers/input/virtio_input.c b/drivers/input/virtio_input.c
index b354933209..b5430886ab 100644
--- a/drivers/input/virtio_input.c
+++ b/drivers/input/virtio_input.c
@@ -259,10 +259,11 @@ static void virtinput_remove(struct virtio_device *vdev)
{
struct virtio_input *vi = vdev->priv;
- poller_unregister(&vi->poller);
-
vdev->config->reset(vdev);
+ poller_unregister(&vi->poller);
+ input_device_unregister(&vi->idev);
vdev->config->del_vqs(vdev);
+
kfree(vi);
}
diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c
index 42b309805f..25140eed31 100644
--- a/drivers/of/overlay.c
+++ b/drivers/of/overlay.c
@@ -460,6 +460,9 @@ static int of_overlay_global_fixup(struct device_node *root, void *data)
if (*of_overlay_dir == '/')
return of_overlay_apply_dir(root, of_overlay_dir, true);
+ if (*of_overlay_dir == '\0')
+ return 0;
+
dir = concat_path_file(of_overlay_basedir, of_overlay_dir);
ret = of_overlay_apply_dir(root, dir, true);
diff --git a/drivers/power/reset/nvmem-reboot-mode.c b/drivers/power/reset/nvmem-reboot-mode.c
index b82b37d642..2086e96400 100644
--- a/drivers/power/reset/nvmem-reboot-mode.c
+++ b/drivers/power/reset/nvmem-reboot-mode.c
@@ -57,6 +57,14 @@ static int nvmem_reboot_mode_probe(struct device_d *dev)
nvmem_rbm->reboot.write = nvmem_reboot_mode_write;
nvmem_rbm->reboot.priority = 200;
+ /*
+ * Fixing up the nvmem reboot device tree node is problematic, because it
+ * contains a phandle to another node. Take the easy way out for now and
+ * expect user to provide matching reboot-mode nodes in both kernel and
+ * barebox device tree manually.
+ */
+ nvmem_rbm->reboot.no_fixup = true;
+
magicbuf = nvmem_cell_read(nvmem_rbm->cell, &len);
if (IS_ERR(magicbuf) || len != 4) {
dev_err(dev, "error reading reboot mode: %pe\n", magicbuf);
diff --git a/drivers/serial/virtio_console.c b/drivers/serial/virtio_console.c
index a1331035d9..a4adb77610 100644
--- a/drivers/serial/virtio_console.c
+++ b/drivers/serial/virtio_console.c
@@ -134,6 +134,8 @@ static int virtcons_probe(struct virtio_device *vdev)
virtcons = xzalloc(sizeof(*virtcons));
+ vdev->priv = virtcons;
+
virtcons->in_vq = vqs[0];
virtcons->out_vq = vqs[1];
@@ -150,6 +152,17 @@ static int virtcons_probe(struct virtio_device *vdev)
return console_register(&virtcons->cdev);
}
+static void virtcons_remove(struct virtio_device *vdev)
+{
+ struct virtio_console *virtcons = vdev->priv;
+
+ vdev->config->reset(vdev);
+ console_unregister(&virtcons->cdev);
+ vdev->config->del_vqs(vdev);
+
+ free(virtcons);
+}
+
static struct virtio_device_id id_table[] = {
{ VIRTIO_ID_CONSOLE, VIRTIO_DEV_ANY_ID },
{ 0 },
@@ -159,6 +172,7 @@ static struct virtio_driver virtio_console = {
.driver.name = "virtio_console",
.id_table = id_table,
.probe = virtcons_probe,
+ .remove = virtcons_remove,
};
device_virtio_driver(virtio_console);
diff --git a/drivers/video/bcm2835.c b/drivers/video/bcm2835.c
index d808bc5c9f..14735fe465 100644
--- a/drivers/video/bcm2835.c
+++ b/drivers/video/bcm2835.c
@@ -14,6 +14,7 @@
#include <malloc.h>
#include <xfuncs.h>
+#include <of_address.h>
#include <mach/mbox.h>
struct bcm2835fb_info {
@@ -58,9 +59,24 @@ static int bcm2835fb_probe(struct device_d *dev)
BCM2835_MBOX_STACK_ALIGN(struct msg_fb_query, msg_query);
BCM2835_MBOX_STACK_ALIGN(struct msg_fb_setup, msg_setup);
struct bcm2835fb_info *info;
+ struct device_node *soc;
u32 w, h;
+ u64 dma_addr, cpu_addr, _region_size;
+ phys_addr_t buffer_addr;
int ret;
+ soc = of_find_node_by_path("/soc");
+ if (!soc) {
+ dev_err(dev, "could not find required OF node /soc\n");
+ return -ENODEV;
+ }
+
+ ret = of_dma_get_range(soc, &dma_addr, &cpu_addr, &_region_size);
+ if (ret) {
+ dev_err(dev, "OF node /soc has no dma-ranges\n");
+ return ret;
+ }
+
BCM2835_MBOX_INIT_HDR(msg_query);
BCM2835_MBOX_INIT_TAG_NO_REQ(&msg_query->physical_w_h,
GET_PHYSICAL_W_H);
@@ -99,10 +115,11 @@ static int bcm2835fb_probe(struct device_d *dev)
return ret;
}
+ buffer_addr = (msg_setup->allocate_buffer.body.resp.fb_address & ~dma_addr) + cpu_addr;
+
info = xzalloc(sizeof *info);
info->fbi.fbops = &bcm2835fb_ops;
- info->fbi.screen_base =
- (void *)msg_setup->allocate_buffer.body.resp.fb_address;
+ info->fbi.screen_base = phys_to_virt(buffer_addr);
info->fbi.xres = msg_setup->physical_w_h.body.resp.width;
info->fbi.yres = msg_setup->physical_w_h.body.resp.height;
info->fbi.bits_per_pixel = 16;