diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/base/driver.c | 4 | ||||
-rw-r--r-- | drivers/block/virtio_blk.c | 6 | ||||
-rw-r--r-- | drivers/hw_random/core.c | 12 | ||||
-rw-r--r-- | drivers/hw_random/virtio-rng.c | 6 | ||||
-rw-r--r-- | drivers/input/virtio_input.c | 5 | ||||
-rw-r--r-- | drivers/of/overlay.c | 3 | ||||
-rw-r--r-- | drivers/power/reset/nvmem-reboot-mode.c | 8 | ||||
-rw-r--r-- | drivers/serial/virtio_console.c | 14 | ||||
-rw-r--r-- | drivers/video/bcm2835.c | 21 |
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; |