summaryrefslogtreecommitdiff
path: root/drivers/vme/vme.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-11-04 21:40:53 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2015-11-04 21:40:53 -0800
commit118c216e16c5ccb028cd03a0dcd56d17a07ff8d7 (patch)
tree94769cd9af230aec964d95f380b1119bb8d8edf0 /drivers/vme/vme.c
parentfd0d351de7bbd718bc2b34d5846854831aa2b88c (diff)
parente3cc3136df33de1aa26d606f2a42cac3fd30cf54 (diff)
Merge tag 'staging-4.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging
Pull staging driver updates from Greg KH: "Here's the big staging driver update for 4.4-rc1. If you were disappointed for 4.3-rc1 that we didn't contribute enough changesets, you should be happy with this pull request of over 2400 patches. But overall we removed more lines of code than we added, which is nice to see. Full details in the shortlog. All of these have been in linux-next for a while" Greg, I've never been disappointed in how few commits Staging contributes to the kernel.. Never. * tag 'staging-4.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging: (2431 commits) Staging: rtl8192u: ieee80211: added missing blank lines Staging: rtl8192u: ieee80211: removed unnecessary braces Staging: rtl8192u: ieee80211: corrected block comments Staging: rtl8192u: ieee80211: corrected indent Staging: rtl8192u: ieee80211: added missing spaces after if Staging: rtl8192u: ieee80211: added missing space around '=' Staging: rtl8192u: ieee80211: fixed position of else statements Staging: rtl8192u: ieee80211: fixed open brace positions staging: rdma: ipath: Remove unneeded vairable. staging: rtl8188eu: pwrGrpCnt variable removed in store_pwrindex_offset function staging: rtl8188eu: new variable for hal_data->MCSTxPowerLevelOriginalOffset[pwrGrpCnt] in store_pwrindex_offset function staging: rtl8188eu: checkpatch fixes: 'Avoid CamelCase' in hal/bb_cfg.c staging: rtl8188eu: checkpatch fixes: line over 80 characters splited into two parts staging: rtl8188eu: checkpatch fixes: alignment should match open parenthesis staging: rtl8188eu: checkpatch fixes: unnecessary parentheses removed in hal/bb_cfg.c staging: rtl8188eu: checkpatch fixes: spaces preferred around that '|' in hal/bb_cfg.c staging: rtl8188eu: operator = replaced by += in loop increment staging: rtl8188eu: occurrence of the 5 GHz code marked staging: rtl8188eu: increment placed into for loop header staging: rtl8188eu: while loop replaced by for loop in rtw_restruct_wmm_ie ...
Diffstat (limited to 'drivers/vme/vme.c')
-rw-r--r--drivers/vme/vme.c90
1 files changed, 90 insertions, 0 deletions
diff --git a/drivers/vme/vme.c b/drivers/vme/vme.c
index 56708915ebbe..72924b0632b7 100644
--- a/drivers/vme/vme.c
+++ b/drivers/vme/vme.c
@@ -223,6 +223,39 @@ int vme_check_window(u32 aspace, unsigned long long vme_base,
}
EXPORT_SYMBOL(vme_check_window);
+static u32 vme_get_aspace(int am)
+{
+ switch (am) {
+ case 0x29:
+ case 0x2D:
+ return VME_A16;
+ case 0x38:
+ case 0x39:
+ case 0x3A:
+ case 0x3B:
+ case 0x3C:
+ case 0x3D:
+ case 0x3E:
+ case 0x3F:
+ return VME_A24;
+ case 0x8:
+ case 0x9:
+ case 0xA:
+ case 0xB:
+ case 0xC:
+ case 0xD:
+ case 0xE:
+ case 0xF:
+ return VME_A32;
+ case 0x0:
+ case 0x1:
+ case 0x3:
+ return VME_A64;
+ }
+
+ return 0;
+}
+
/*
* Request a slave image with specific attributes, return some unique
* identifier.
@@ -990,6 +1023,63 @@ int vme_dma_free(struct vme_resource *resource)
}
EXPORT_SYMBOL(vme_dma_free);
+void vme_bus_error_handler(struct vme_bridge *bridge,
+ unsigned long long address, int am)
+{
+ struct list_head *handler_pos = NULL;
+ struct vme_error_handler *handler;
+ int handler_triggered = 0;
+ u32 aspace = vme_get_aspace(am);
+
+ list_for_each(handler_pos, &bridge->vme_error_handlers) {
+ handler = list_entry(handler_pos, struct vme_error_handler,
+ list);
+ if ((aspace == handler->aspace) &&
+ (address >= handler->start) &&
+ (address < handler->end)) {
+ if (!handler->num_errors)
+ handler->first_error = address;
+ if (handler->num_errors != UINT_MAX)
+ handler->num_errors++;
+ handler_triggered = 1;
+ }
+ }
+
+ if (!handler_triggered)
+ dev_err(bridge->parent,
+ "Unhandled VME access error at address 0x%llx\n",
+ address);
+}
+EXPORT_SYMBOL(vme_bus_error_handler);
+
+struct vme_error_handler *vme_register_error_handler(
+ struct vme_bridge *bridge, u32 aspace,
+ unsigned long long address, size_t len)
+{
+ struct vme_error_handler *handler;
+
+ handler = kmalloc(sizeof(*handler), GFP_KERNEL);
+ if (!handler)
+ return NULL;
+
+ handler->aspace = aspace;
+ handler->start = address;
+ handler->end = address + len;
+ handler->num_errors = 0;
+ handler->first_error = 0;
+ list_add_tail(&handler->list, &bridge->vme_error_handlers);
+
+ return handler;
+}
+EXPORT_SYMBOL(vme_register_error_handler);
+
+void vme_unregister_error_handler(struct vme_error_handler *handler)
+{
+ list_del(&handler->list);
+ kfree(handler);
+}
+EXPORT_SYMBOL(vme_unregister_error_handler);
+
void vme_irq_handler(struct vme_bridge *bridge, int level, int statid)
{
void (*call)(int, int, void *);