diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-12-13 12:11:01 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-12-13 12:11:01 -0800 |
commit | b78b499a67c3f77aeb6cd0b54724bc38b141255d (patch) | |
tree | 8ebdb5303bb1552577182d9fe4086910b8648d22 /drivers/of | |
parent | 098c30557a9a19827240aaadc137e4668157dc6b (diff) | |
parent | 190cc65e912de7e8f7ebddcecfbf55a610281a8c (diff) | |
download | op-kernel-dev-b78b499a67c3f77aeb6cd0b54724bc38b141255d.zip op-kernel-dev-b78b499a67c3f77aeb6cd0b54724bc38b141255d.tar.gz |
Merge tag 'char-misc-4.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc
Pull char/misc driver updates from Greg KH:
"Here's the big char/misc driver patches for 4.10-rc1. Lots of tiny
changes over lots of "minor" driver subsystems, the largest being some
new FPGA drivers. Other than that, a few other new drivers, but no new
driver subsystems added for this kernel cycle, a nice change.
All of these have been in linux-next with no reported issues"
* tag 'char-misc-4.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (107 commits)
uio-hv-generic: store physical addresses instead of virtual
Tools: hv: kvp: configurable external scripts path
uio-hv-generic: new userspace i/o driver for VMBus
vmbus: add support for dynamic device id's
hv: change clockevents unbind tactics
hv: acquire vmbus_connection.channel_mutex in vmbus_free_channels()
hyperv: Fix spelling of HV_UNKOWN
mei: bus: enable non-blocking RX
mei: fix the back to back interrupt handling
mei: synchronize irq before initiating a reset.
VME: Remove shutdown entry from vme_driver
auxdisplay: ht16k33: select framebuffer helper modules
MAINTAINERS: add git url for fpga
fpga: Clarify how write_init works streaming modes
fpga zynq: Fix incorrect ISR state on bootup
fpga zynq: Remove priv->dev
fpga zynq: Add missing \n to messages
fpga: Add COMPILE_TEST to all drivers
uio: pruss: add clk_disable()
char/pcmcia: add some error checking in scr24x_read()
...
Diffstat (limited to 'drivers/of')
-rw-r--r-- | drivers/of/overlay.c | 47 |
1 files changed, 46 insertions, 1 deletions
diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c index 318dbb5..0d4cda7 100644 --- a/drivers/of/overlay.c +++ b/drivers/of/overlay.c @@ -58,6 +58,41 @@ struct of_overlay { static int of_overlay_apply_one(struct of_overlay *ov, struct device_node *target, const struct device_node *overlay); +static BLOCKING_NOTIFIER_HEAD(of_overlay_chain); + +int of_overlay_notifier_register(struct notifier_block *nb) +{ + return blocking_notifier_chain_register(&of_overlay_chain, nb); +} +EXPORT_SYMBOL_GPL(of_overlay_notifier_register); + +int of_overlay_notifier_unregister(struct notifier_block *nb) +{ + return blocking_notifier_chain_unregister(&of_overlay_chain, nb); +} +EXPORT_SYMBOL_GPL(of_overlay_notifier_unregister); + +static int of_overlay_notify(struct of_overlay *ov, + enum of_overlay_notify_action action) +{ + struct of_overlay_notify_data nd; + int i, ret; + + for (i = 0; i < ov->count; i++) { + struct of_overlay_info *ovinfo = &ov->ovinfo_tab[i]; + + nd.target = ovinfo->target; + nd.overlay = ovinfo->overlay; + + ret = blocking_notifier_call_chain(&of_overlay_chain, + action, &nd); + if (ret) + return notifier_to_errno(ret); + } + + return 0; +} + static int of_overlay_apply_single_property(struct of_overlay *ov, struct device_node *target, struct property *prop) { @@ -368,6 +403,13 @@ int of_overlay_create(struct device_node *tree) goto err_free_idr; } + err = of_overlay_notify(ov, OF_OVERLAY_PRE_APPLY); + if (err < 0) { + pr_err("%s: Pre-apply notifier failed (err=%d)\n", + __func__, err); + goto err_free_idr; + } + /* apply the overlay */ err = of_overlay_apply(ov); if (err) @@ -382,6 +424,8 @@ int of_overlay_create(struct device_node *tree) /* add to the tail of the overlay list */ list_add_tail(&ov->node, &ov_list); + of_overlay_notify(ov, OF_OVERLAY_POST_APPLY); + mutex_unlock(&of_mutex); return id; @@ -498,9 +542,10 @@ int of_overlay_destroy(int id) goto out; } - + of_overlay_notify(ov, OF_OVERLAY_PRE_REMOVE); list_del(&ov->node); __of_changeset_revert(&ov->cset); + of_overlay_notify(ov, OF_OVERLAY_POST_REMOVE); of_free_overlay_info(ov); idr_remove(&ov_idr, id); of_changeset_destroy(&ov->cset); |