diff --git a/[refs] b/[refs]
index 2130caa18400..c3b49f5b0ffa 100644
--- a/[refs]
+++ b/[refs]
@@ -1,2 +1,2 @@
---
-refs/heads/master: 01a678c5a2f41663b8faf03d17e2bbdbf44158a9
+refs/heads/master: 5520ebd308927a3beba599a2b68fa8c52f41f43b
diff --git a/trunk/Documentation/ABI/stable/thermal-notification b/trunk/Documentation/ABI/stable/thermal-notification
new file mode 100644
index 000000000000..9723e8b7aeb3
--- /dev/null
+++ b/trunk/Documentation/ABI/stable/thermal-notification
@@ -0,0 +1,4 @@
+What: A notification mechanism for thermal related events
+Description:
+ This interface enables notification for thermal related events.
+ The notification is in the form of a netlink event.
diff --git a/trunk/Documentation/DocBook/80211.tmpl b/trunk/Documentation/DocBook/80211.tmpl
index 03641a08e275..8906648f962b 100644
--- a/trunk/Documentation/DocBook/80211.tmpl
+++ b/trunk/Documentation/DocBook/80211.tmpl
@@ -268,10 +268,6 @@
!Finclude/net/mac80211.h ieee80211_ops
!Finclude/net/mac80211.h ieee80211_alloc_hw
!Finclude/net/mac80211.h ieee80211_register_hw
-!Finclude/net/mac80211.h ieee80211_get_tx_led_name
-!Finclude/net/mac80211.h ieee80211_get_rx_led_name
-!Finclude/net/mac80211.h ieee80211_get_assoc_led_name
-!Finclude/net/mac80211.h ieee80211_get_radio_led_name
!Finclude/net/mac80211.h ieee80211_unregister_hw
!Finclude/net/mac80211.h ieee80211_free_hw
@@ -382,6 +378,23 @@
+
+ LED support
+
+ Mac80211 supports various ways of blinking LEDs. Wherever possible,
+ device LEDs should be exposed as LED class devices and hooked up to
+ the appropriate trigger, which will then be triggered appropriately
+ by mac80211.
+
+!Finclude/net/mac80211.h ieee80211_get_tx_led_name
+!Finclude/net/mac80211.h ieee80211_get_rx_led_name
+!Finclude/net/mac80211.h ieee80211_get_assoc_led_name
+!Finclude/net/mac80211.h ieee80211_get_radio_led_name
+!Finclude/net/mac80211.h ieee80211_tpt_blink
+!Finclude/net/mac80211.h ieee80211_tpt_led_trigger_flags
+!Finclude/net/mac80211.h ieee80211_create_tpt_led_trigger
+
+
Hardware crypto acceleration
!Pinclude/net/mac80211.h Hardware crypto acceleration
diff --git a/trunk/Documentation/IPMI.txt b/trunk/Documentation/IPMI.txt
index 69dd29ed824e..b2bea15137d2 100644
--- a/trunk/Documentation/IPMI.txt
+++ b/trunk/Documentation/IPMI.txt
@@ -533,6 +533,33 @@ completion during sending a panic event.
Other Pieces
------------
+Get the detailed info related with the IPMI device
+--------------------------------------------------
+
+Some users need more detailed information about a device, like where
+the address came from or the raw base device for the IPMI interface.
+You can use the IPMI smi_watcher to catch the IPMI interfaces as they
+come or go, and to grab the information, you can use the function
+ipmi_get_smi_info(), which returns the following structure:
+
+struct ipmi_smi_info {
+ enum ipmi_addr_src addr_src;
+ struct device *dev;
+ union {
+ struct {
+ void *acpi_handle;
+ } acpi_info;
+ } addr_info;
+};
+
+Currently special info for only for SI_ACPI address sources is
+returned. Others may be added as necessary.
+
+Note that the dev pointer is included in the above structure, and
+assuming ipmi_smi_get_info returns success, you must call put_device
+on the dev pointer.
+
+
Watchdog
--------
diff --git a/trunk/Documentation/acpi/apei/output_format.txt b/trunk/Documentation/acpi/apei/output_format.txt
new file mode 100644
index 000000000000..9146952c612a
--- /dev/null
+++ b/trunk/Documentation/acpi/apei/output_format.txt
@@ -0,0 +1,122 @@
+ APEI output format
+ ~~~~~~~~~~~~~~~~~~
+
+APEI uses printk as hardware error reporting interface, the output
+format is as follow.
+
+ :=
+APEI generic hardware error status
+severity: ,
+section: , severity: ,
+flags:
+
+fru_id:
+fru_text:
+section_type:
+
+
+* := recoverable | fatal | corrected | info
+
+# :=
+[primary][, containment warning][, reset][, threshold exceeded]\
+[, resource not accessible][, latent error]
+
+ := generic processor error | memory error | \
+PCIe error | unknown,
+
+ :=
+ | | \
+ |
+
+ :=
+[processor_type: , ]
+[processor_isa: , ]
+[error_type:
+]
+[operation: , ]
+[flags:
+]
+[level: ]
+[version_info: ]
+[processor_id: ]
+[target_address: ]
+[requestor_id: ]
+[responder_id: ]
+[IP: ]
+
+* := IA32/X64 | IA64
+
+* := IA32 | IA64 | X64
+
+# :=
+[cache error][, TLB error][, bus error][, micro-architectural error]
+
+* := unknown or generic | data read | data write | \
+instruction execution
+
+# :=
+[restartable][, precise IP][, overflow][, corrected]
+
+ :=
+[error_status: ]
+[physical_address: ]
+[physical_address_mask: ]
+[node: ]
+[card: ]
+[module: ]
+[bank: ]
+[device: ]
+[row: ]
+[column: ]
+[bit_position: ]
+[requestor_id: ]
+[responder_id: ]
+[target_id: ]
+[error_type: , ]
+
+* :=
+unknown | no error | single-bit ECC | multi-bit ECC | \
+single-symbol chipkill ECC | multi-symbol chipkill ECC | master abort | \
+target abort | parity error | watchdog timeout | invalid address | \
+mirror Broken | memory sparing | scrub corrected error | \
+scrub uncorrected error
+
+ :=
+[port_type: , ]
+[version: .]
+[command: , status: ]
+[device_id: ::.
+slot:
+secondary_bus:
+vendor_id: , device_id:
+class_code: ]
+[serial number: , ]
+[bridge: secondary_status: , control: ]
+
+* := PCIe end point | legacy PCI end point | \
+unknown | unknown | root port | upstream switch port | \
+downstream switch port | PCIe to PCI/PCI-X bridge | \
+PCI/PCI-X to PCIe bridge | root complex integrated endpoint device | \
+root complex event collector
+
+Where, [] designate corresponding content is optional
+
+All description with * has the following format:
+
+field: ,
+
+Where value of should be the position of "string" in description. Otherwise, will be "unknown".
+
+All description with # has the following format:
+
+field:
+
+
+Where each string in corresponding to one set bit of
+. The bit position is the position of "string" in description.
+
+For more detailed explanation of every field, please refer to UEFI
+specification version 2.3 or later, section Appendix N: Common
+Platform Error Record.
diff --git a/trunk/Documentation/device-mapper/dm-crypt.txt b/trunk/Documentation/device-mapper/dm-crypt.txt
index 524de926290d..59293ac4a5d0 100644
--- a/trunk/Documentation/device-mapper/dm-crypt.txt
+++ b/trunk/Documentation/device-mapper/dm-crypt.txt
@@ -8,7 +8,7 @@ Parameters:
Encryption cipher and an optional IV generation mode.
- (In format cipher-chainmode-ivopts:ivmode).
+ (In format cipher[:keycount]-chainmode-ivopts:ivmode).
Examples:
des
aes-cbc-essiv:sha256
@@ -20,6 +20,11 @@ Parameters:
Key used for encryption. It is encoded as a hexadecimal number.
You can only use key sizes that are valid for the selected cipher.
+
+ Multi-key compatibility mode. You can define keys and
+ then sectors are encrypted according to their offsets (sector 0 uses key0;
+ sector 1 uses key1 etc.). must be a power of two.
+
The IV offset is a sector count that is added to the sector number
before creating the IV.
diff --git a/trunk/Documentation/device-mapper/dm-raid.txt b/trunk/Documentation/device-mapper/dm-raid.txt
new file mode 100644
index 000000000000..33b6b7071ac8
--- /dev/null
+++ b/trunk/Documentation/device-mapper/dm-raid.txt
@@ -0,0 +1,70 @@
+Device-mapper RAID (dm-raid) is a bridge from DM to MD. It
+provides a way to use device-mapper interfaces to access the MD RAID
+drivers.
+
+As with all device-mapper targets, the nominal public interfaces are the
+constructor (CTR) tables and the status outputs (both STATUSTYPE_INFO
+and STATUSTYPE_TABLE). The CTR table looks like the following:
+
+1: raid \
+2: <#raid_params> \
+3: <#raid_devs> ..
+
+Line 1 contains the standard first three arguments to any device-mapper
+target - the start, length, and target type fields. The target type in
+this case is "raid".
+
+Line 2 contains the arguments that define the particular raid
+type/personality/level, the required arguments for that raid type, and
+any optional arguments. Possible raid types include: raid4, raid5_la,
+raid5_ls, raid5_rs, raid6_zr, raid6_nr, and raid6_nc. (raid1 is
+planned for the future.) The list of required and optional parameters
+is the same for all the current raid types. The required parameters are
+positional, while the optional parameters are given as key/value pairs.
+The possible parameters are as follows:
+ Chunk size in sectors.
+ [[no]sync] Force/Prevent RAID initialization
+ [rebuild ] Rebuild the drive indicated by the index
+ [daemon_sleep ] Time between bitmap daemon work to clear bits
+ [min_recovery_rate ] Throttle RAID initialization
+ [max_recovery_rate ] Throttle RAID initialization
+ [max_write_behind ] See '-write-behind=' (man mdadm)
+ [stripe_cache ] Stripe cache size for higher RAIDs
+
+Line 3 contains the list of devices that compose the array in
+metadata/data device pairs. If the metadata is stored separately, a '-'
+is given for the metadata device position. If a drive has failed or is
+missing at creation time, a '-' can be given for both the metadata and
+data drives for a given position.
+
+NB. Currently all metadata devices must be specified as '-'.
+
+Examples:
+# RAID4 - 4 data drives, 1 parity
+# No metadata devices specified to hold superblock/bitmap info
+# Chunk size of 1MiB
+# (Lines separated for easy reading)
+0 1960893648 raid \
+ raid4 1 2048 \
+ 5 - 8:17 - 8:33 - 8:49 - 8:65 - 8:81
+
+# RAID4 - 4 data drives, 1 parity (no metadata devices)
+# Chunk size of 1MiB, force RAID initialization,
+# min recovery rate at 20 kiB/sec/disk
+0 1960893648 raid \
+ raid4 4 2048 min_recovery_rate 20 sync\
+ 5 - 8:17 - 8:33 - 8:49 - 8:65 - 8:81
+
+Performing a 'dmsetup table' should display the CTR table used to
+construct the mapping (with possible reordering of optional
+parameters).
+
+Performing a 'dmsetup status' will yield information on the state and
+health of the array. The output is as follows:
+1: raid \
+2: <#devices> <1 health char for each dev>
+
+Line 1 is standard DM output. Line 2 is best shown by example:
+ 0 1960893648 raid raid4 5 AAAAA 2/490221568
+Here we can see the RAID type is raid4, there are 5 devices - all of
+which are 'A'live, and the array is 2/490221568 complete with recovery.
diff --git a/trunk/Documentation/feature-removal-schedule.txt b/trunk/Documentation/feature-removal-schedule.txt
index 6cbbd20534cf..8c594c45b6a1 100644
--- a/trunk/Documentation/feature-removal-schedule.txt
+++ b/trunk/Documentation/feature-removal-schedule.txt
@@ -248,6 +248,17 @@ Who: Zhang Rui
---------------------------
+What: CONFIG_ACPI_PROCFS_POWER
+When: 2.6.39
+Why: sysfs I/F for ACPI power devices, including AC and Battery,
+ has been working in upstream kenrel since 2.6.24, Sep 2007.
+ In 2.6.37, we make the sysfs I/F always built in and this option
+ disabled by default.
+ Remove this option and the ACPI power procfs interface in 2.6.39.
+Who: Zhang Rui
+
+---------------------------
+
What: /proc/acpi/button
When: August 2007
Why: /proc/acpi/button has been replaced by events to the input layer
diff --git a/trunk/Documentation/filesystems/Locking b/trunk/Documentation/filesystems/Locking
index 977d8919cc69..651d5237c155 100644
--- a/trunk/Documentation/filesystems/Locking
+++ b/trunk/Documentation/filesystems/Locking
@@ -19,6 +19,8 @@ prototypes:
void (*d_release)(struct dentry *);
void (*d_iput)(struct dentry *, struct inode *);
char *(*d_dname)((struct dentry *dentry, char *buffer, int buflen);
+ struct vfsmount *(*d_automount)(struct path *path);
+ int (*d_manage)(struct dentry *, bool);
locking rules:
rename_lock ->d_lock may block rcu-walk
@@ -29,6 +31,8 @@ d_delete: no yes no no
d_release: no no yes no
d_iput: no no yes no
d_dname: no no no no
+d_automount: no no yes no
+d_manage: no no yes (ref-walk) maybe
--------------------------- inode_operations ---------------------------
prototypes:
@@ -343,7 +347,6 @@ prototypes:
int (*fl_grant)(struct file_lock *, struct file_lock *, int);
void (*fl_release_private)(struct file_lock *);
void (*fl_break)(struct file_lock *); /* break_lease callback */
- int (*fl_mylease)(struct file_lock *, struct file_lock *);
int (*fl_change)(struct file_lock **, int);
locking rules:
@@ -353,7 +356,6 @@ fl_notify: yes no
fl_grant: no no
fl_release_private: maybe no
fl_break: yes no
-fl_mylease: yes no
fl_change yes no
--------------------------- buffer_head -----------------------------------
diff --git a/trunk/Documentation/filesystems/porting b/trunk/Documentation/filesystems/porting
index 266d2059b9b8..dfbcd1b00b0a 100644
--- a/trunk/Documentation/filesystems/porting
+++ b/trunk/Documentation/filesystems/porting
@@ -365,8 +365,8 @@ must be done in the RCU callback.
[recommended]
vfs now tries to do path walking in "rcu-walk mode", which avoids
atomic operations and scalability hazards on dentries and inodes (see
-Documentation/filesystems/path-walk.txt). d_hash and d_compare changes (above)
-are examples of the changes required to support this. For more complex
+Documentation/filesystems/path-lookup.txt). d_hash and d_compare changes
+(above) are examples of the changes required to support this. For more complex
filesystem callbacks, the vfs drops out of rcu-walk mode before the fs call, so
no changes are required to the filesystem. However, this is costly and loses
the benefits of rcu-walk mode. We will begin to add filesystem callbacks that
@@ -383,8 +383,8 @@ Documentation/filesystems/vfs.txt for more details.
permission and check_acl are inode permission checks that are called
on many or all directory inodes on the way down a path walk (to check for
-exec permission). These must now be rcu-walk aware (flags & IPERM_RCU). See
-Documentation/filesystems/vfs.txt for more details.
+exec permission). These must now be rcu-walk aware (flags & IPERM_FLAG_RCU).
+See Documentation/filesystems/vfs.txt for more details.
--
[mandatory]
diff --git a/trunk/Documentation/filesystems/proc.txt b/trunk/Documentation/filesystems/proc.txt
index 9471225212c4..23cae6548d3a 100644
--- a/trunk/Documentation/filesystems/proc.txt
+++ b/trunk/Documentation/filesystems/proc.txt
@@ -375,6 +375,7 @@ Anonymous: 0 kB
Swap: 0 kB
KernelPageSize: 4 kB
MMUPageSize: 4 kB
+Locked: 374 kB
The first of these lines shows the same information as is displayed for the
mapping in /proc/PID/maps. The remaining lines show the size of the mapping
@@ -670,6 +671,8 @@ varies by architecture and compile options. The following is from a
> cat /proc/meminfo
+The "Locked" indicates whether the mapping is locked in memory or not.
+
MemTotal: 16344972 kB
MemFree: 13634064 kB
@@ -1320,6 +1323,10 @@ scaled linearly with /proc//oom_score_adj.
Writing to /proc//oom_score_adj or /proc//oom_adj will change the
other with its scaled value.
+The value of /proc//oom_score_adj may be reduced no lower than the last
+value set by a CAP_SYS_RESOURCE process. To reduce the value any lower
+requires CAP_SYS_RESOURCE.
+
NOTICE: /proc//oom_adj is deprecated and will be removed, please see
Documentation/feature-removal-schedule.txt.
diff --git a/trunk/Documentation/filesystems/vfs.txt b/trunk/Documentation/filesystems/vfs.txt
index fbb324e2bd43..94cf97b901d7 100644
--- a/trunk/Documentation/filesystems/vfs.txt
+++ b/trunk/Documentation/filesystems/vfs.txt
@@ -415,8 +415,8 @@ otherwise noted.
permission: called by the VFS to check for access rights on a POSIX-like
filesystem.
- May be called in rcu-walk mode (flags & IPERM_RCU). If in rcu-walk
- mode, the filesystem must check the permission without blocking or
+ May be called in rcu-walk mode (flags & IPERM_FLAG_RCU). If in rcu-walk
+ mode, the filesystem must check the permission without blocking or
storing to the inode.
If a situation is encountered that rcu-walk cannot handle, return
@@ -864,6 +864,8 @@ struct dentry_operations {
void (*d_release)(struct dentry *);
void (*d_iput)(struct dentry *, struct inode *);
char *(*d_dname)(struct dentry *, char *, int);
+ struct vfsmount *(*d_automount)(struct path *);
+ int (*d_manage)(struct dentry *, bool, bool);
};
d_revalidate: called when the VFS needs to revalidate a dentry. This
@@ -930,6 +932,47 @@ struct dentry_operations {
at the end of the buffer, and returns a pointer to the first char.
dynamic_dname() helper function is provided to take care of this.
+ d_automount: called when an automount dentry is to be traversed (optional).
+ This should create a new VFS mount record and return the record to the
+ caller. The caller is supplied with a path parameter giving the
+ automount directory to describe the automount target and the parent
+ VFS mount record to provide inheritable mount parameters. NULL should
+ be returned if someone else managed to make the automount first. If
+ the vfsmount creation failed, then an error code should be returned.
+ If -EISDIR is returned, then the directory will be treated as an
+ ordinary directory and returned to pathwalk to continue walking.
+
+ If a vfsmount is returned, the caller will attempt to mount it on the
+ mountpoint and will remove the vfsmount from its expiration list in
+ the case of failure. The vfsmount should be returned with 2 refs on
+ it to prevent automatic expiration - the caller will clean up the
+ additional ref.
+
+ This function is only used if DCACHE_NEED_AUTOMOUNT is set on the
+ dentry. This is set by __d_instantiate() if S_AUTOMOUNT is set on the
+ inode being added.
+
+ d_manage: called to allow the filesystem to manage the transition from a
+ dentry (optional). This allows autofs, for example, to hold up clients
+ waiting to explore behind a 'mountpoint' whilst letting the daemon go
+ past and construct the subtree there. 0 should be returned to let the
+ calling process continue. -EISDIR can be returned to tell pathwalk to
+ use this directory as an ordinary directory and to ignore anything
+ mounted on it and not to check the automount flag. Any other error
+ code will abort pathwalk completely.
+
+ If the 'mounting_here' parameter is true, then namespace_sem is being
+ held by the caller and the function should not initiate any mounts or
+ unmounts that it will then wait for.
+
+ If the 'rcu_walk' parameter is true, then the caller is doing a
+ pathwalk in RCU-walk mode. Sleeping is not permitted in this mode,
+ and the caller can be asked to leave it and call again by returing
+ -ECHILD.
+
+ This function is only used if DCACHE_MANAGE_TRANSIT is set on the
+ dentry being transited from.
+
Example :
static char *pipefs_dname(struct dentry *dent, char *buffer, int buflen)
diff --git a/trunk/Documentation/gpio.txt b/trunk/Documentation/gpio.txt
index a492d92bb098..792faa3c06cf 100644
--- a/trunk/Documentation/gpio.txt
+++ b/trunk/Documentation/gpio.txt
@@ -135,7 +135,7 @@ setting up a platform_device using the GPIO, is mark its direction:
int gpio_direction_input(unsigned gpio);
int gpio_direction_output(unsigned gpio, int value);
-The return value is zero for success, else a negative errno. It must
+The return value is zero for success, else a negative errno. It should
be checked, since the get/set calls don't have error returns and since
misconfiguration is possible. You should normally issue these calls from
a task context. However, for spinlock-safe GPIOs it's OK to use them
diff --git a/trunk/Documentation/kernel-parameters.txt b/trunk/Documentation/kernel-parameters.txt
index 55fe7599bc8e..b72e071a3e5b 100644
--- a/trunk/Documentation/kernel-parameters.txt
+++ b/trunk/Documentation/kernel-parameters.txt
@@ -199,11 +199,6 @@ and is between 256 and 4096 characters. It is defined in the file
unusable. The "log_buf_len" parameter may be useful
if you need to capture more output.
- acpi_display_output= [HW,ACPI]
- acpi_display_output=vendor
- acpi_display_output=video
- See above.
-
acpi_irq_balance [HW,ACPI]
ACPI will balance active IRQs
default in APIC mode
diff --git a/trunk/Documentation/target/tcm_mod_builder.py b/trunk/Documentation/target/tcm_mod_builder.py
new file mode 100755
index 000000000000..dbeb8a0d7175
--- /dev/null
+++ b/trunk/Documentation/target/tcm_mod_builder.py
@@ -0,0 +1,1094 @@
+#!/usr/bin/python
+# The TCM v4 multi-protocol fabric module generation script for drivers/target/$NEW_MOD
+#
+# Copyright (c) 2010 Rising Tide Systems
+# Copyright (c) 2010 Linux-iSCSI.org
+#
+# Author: nab@kernel.org
+#
+import os, sys
+import subprocess as sub
+import string
+import re
+import optparse
+
+tcm_dir = ""
+
+fabric_ops = []
+fabric_mod_dir = ""
+fabric_mod_port = ""
+fabric_mod_init_port = ""
+
+def tcm_mod_err(msg):
+ print msg
+ sys.exit(1)
+
+def tcm_mod_create_module_subdir(fabric_mod_dir_var):
+
+ if os.path.isdir(fabric_mod_dir_var) == True:
+ return 1
+
+ print "Creating fabric_mod_dir: " + fabric_mod_dir_var
+ ret = os.mkdir(fabric_mod_dir_var)
+ if ret:
+ tcm_mod_err("Unable to mkdir " + fabric_mod_dir_var)
+
+ return
+
+def tcm_mod_build_FC_include(fabric_mod_dir_var, fabric_mod_name):
+ global fabric_mod_port
+ global fabric_mod_init_port
+ buf = ""
+
+ f = fabric_mod_dir_var + "/" + fabric_mod_name + "_base.h"
+ print "Writing file: " + f
+
+ p = open(f, 'w');
+ if not p:
+ tcm_mod_err("Unable to open file: " + f)
+
+ buf = "#define " + fabric_mod_name.upper() + "_VERSION \"v0.1\"\n"
+ buf += "#define " + fabric_mod_name.upper() + "_NAMELEN 32\n"
+ buf += "\n"
+ buf += "struct " + fabric_mod_name + "_nacl {\n"
+ buf += " /* Binary World Wide unique Port Name for FC Initiator Nport */\n"
+ buf += " u64 nport_wwpn;\n"
+ buf += " /* ASCII formatted WWPN for FC Initiator Nport */\n"
+ buf += " char nport_name[" + fabric_mod_name.upper() + "_NAMELEN];\n"
+ buf += " /* Returned by " + fabric_mod_name + "_make_nodeacl() */\n"
+ buf += " struct se_node_acl se_node_acl;\n"
+ buf += "};\n"
+ buf += "\n"
+ buf += "struct " + fabric_mod_name + "_tpg {\n"
+ buf += " /* FC lport target portal group tag for TCM */\n"
+ buf += " u16 lport_tpgt;\n"
+ buf += " /* Pointer back to " + fabric_mod_name + "_lport */\n"
+ buf += " struct " + fabric_mod_name + "_lport *lport;\n"
+ buf += " /* Returned by " + fabric_mod_name + "_make_tpg() */\n"
+ buf += " struct se_portal_group se_tpg;\n"
+ buf += "};\n"
+ buf += "\n"
+ buf += "struct " + fabric_mod_name + "_lport {\n"
+ buf += " /* SCSI protocol the lport is providing */\n"
+ buf += " u8 lport_proto_id;\n"
+ buf += " /* Binary World Wide unique Port Name for FC Target Lport */\n"
+ buf += " u64 lport_wwpn;\n"
+ buf += " /* ASCII formatted WWPN for FC Target Lport */\n"
+ buf += " char lport_name[" + fabric_mod_name.upper() + "_NAMELEN];\n"
+ buf += " /* Returned by " + fabric_mod_name + "_make_lport() */\n"
+ buf += " struct se_wwn lport_wwn;\n"
+ buf += "};\n"
+
+ ret = p.write(buf)
+ if ret:
+ tcm_mod_err("Unable to write f: " + f)
+
+ p.close()
+
+ fabric_mod_port = "lport"
+ fabric_mod_init_port = "nport"
+
+ return
+
+def tcm_mod_build_SAS_include(fabric_mod_dir_var, fabric_mod_name):
+ global fabric_mod_port
+ global fabric_mod_init_port
+ buf = ""
+
+ f = fabric_mod_dir_var + "/" + fabric_mod_name + "_base.h"
+ print "Writing file: " + f
+
+ p = open(f, 'w');
+ if not p:
+ tcm_mod_err("Unable to open file: " + f)
+
+ buf = "#define " + fabric_mod_name.upper() + "_VERSION \"v0.1\"\n"
+ buf += "#define " + fabric_mod_name.upper() + "_NAMELEN 32\n"
+ buf += "\n"
+ buf += "struct " + fabric_mod_name + "_nacl {\n"
+ buf += " /* Binary World Wide unique Port Name for SAS Initiator port */\n"
+ buf += " u64 iport_wwpn;\n"
+ buf += " /* ASCII formatted WWPN for Sas Initiator port */\n"
+ buf += " char iport_name[" + fabric_mod_name.upper() + "_NAMELEN];\n"
+ buf += " /* Returned by " + fabric_mod_name + "_make_nodeacl() */\n"
+ buf += " struct se_node_acl se_node_acl;\n"
+ buf += "};\n\n"
+ buf += "struct " + fabric_mod_name + "_tpg {\n"
+ buf += " /* SAS port target portal group tag for TCM */\n"
+ buf += " u16 tport_tpgt;\n"
+ buf += " /* Pointer back to " + fabric_mod_name + "_tport */\n"
+ buf += " struct " + fabric_mod_name + "_tport *tport;\n"
+ buf += " /* Returned by " + fabric_mod_name + "_make_tpg() */\n"
+ buf += " struct se_portal_group se_tpg;\n"
+ buf += "};\n\n"
+ buf += "struct " + fabric_mod_name + "_tport {\n"
+ buf += " /* SCSI protocol the tport is providing */\n"
+ buf += " u8 tport_proto_id;\n"
+ buf += " /* Binary World Wide unique Port Name for SAS Target port */\n"
+ buf += " u64 tport_wwpn;\n"
+ buf += " /* ASCII formatted WWPN for SAS Target port */\n"
+ buf += " char tport_name[" + fabric_mod_name.upper() + "_NAMELEN];\n"
+ buf += " /* Returned by " + fabric_mod_name + "_make_tport() */\n"
+ buf += " struct se_wwn tport_wwn;\n"
+ buf += "};\n"
+
+ ret = p.write(buf)
+ if ret:
+ tcm_mod_err("Unable to write f: " + f)
+
+ p.close()
+
+ fabric_mod_port = "tport"
+ fabric_mod_init_port = "iport"
+
+ return
+
+def tcm_mod_build_iSCSI_include(fabric_mod_dir_var, fabric_mod_name):
+ global fabric_mod_port
+ global fabric_mod_init_port
+ buf = ""
+
+ f = fabric_mod_dir_var + "/" + fabric_mod_name + "_base.h"
+ print "Writing file: " + f
+
+ p = open(f, 'w');
+ if not p:
+ tcm_mod_err("Unable to open file: " + f)
+
+ buf = "#define " + fabric_mod_name.upper() + "_VERSION \"v0.1\"\n"
+ buf += "#define " + fabric_mod_name.upper() + "_NAMELEN 32\n"
+ buf += "\n"
+ buf += "struct " + fabric_mod_name + "_nacl {\n"
+ buf += " /* ASCII formatted InitiatorName */\n"
+ buf += " char iport_name[" + fabric_mod_name.upper() + "_NAMELEN];\n"
+ buf += " /* Returned by " + fabric_mod_name + "_make_nodeacl() */\n"
+ buf += " struct se_node_acl se_node_acl;\n"
+ buf += "};\n\n"
+ buf += "struct " + fabric_mod_name + "_tpg {\n"
+ buf += " /* iSCSI target portal group tag for TCM */\n"
+ buf += " u16 tport_tpgt;\n"
+ buf += " /* Pointer back to " + fabric_mod_name + "_tport */\n"
+ buf += " struct " + fabric_mod_name + "_tport *tport;\n"
+ buf += " /* Returned by " + fabric_mod_name + "_make_tpg() */\n"
+ buf += " struct se_portal_group se_tpg;\n"
+ buf += "};\n\n"
+ buf += "struct " + fabric_mod_name + "_tport {\n"
+ buf += " /* SCSI protocol the tport is providing */\n"
+ buf += " u8 tport_proto_id;\n"
+ buf += " /* ASCII formatted TargetName for IQN */\n"
+ buf += " char tport_name[" + fabric_mod_name.upper() + "_NAMELEN];\n"
+ buf += " /* Returned by " + fabric_mod_name + "_make_tport() */\n"
+ buf += " struct se_wwn tport_wwn;\n"
+ buf += "};\n"
+
+ ret = p.write(buf)
+ if ret:
+ tcm_mod_err("Unable to write f: " + f)
+
+ p.close()
+
+ fabric_mod_port = "tport"
+ fabric_mod_init_port = "iport"
+
+ return
+
+def tcm_mod_build_base_includes(proto_ident, fabric_mod_dir_val, fabric_mod_name):
+
+ if proto_ident == "FC":
+ tcm_mod_build_FC_include(fabric_mod_dir_val, fabric_mod_name)
+ elif proto_ident == "SAS":
+ tcm_mod_build_SAS_include(fabric_mod_dir_val, fabric_mod_name)
+ elif proto_ident == "iSCSI":
+ tcm_mod_build_iSCSI_include(fabric_mod_dir_val, fabric_mod_name)
+ else:
+ print "Unsupported proto_ident: " + proto_ident
+ sys.exit(1)
+
+ return
+
+def tcm_mod_build_configfs(proto_ident, fabric_mod_dir_var, fabric_mod_name):
+ buf = ""
+
+ f = fabric_mod_dir_var + "/" + fabric_mod_name + "_configfs.c"
+ print "Writing file: " + f
+
+ p = open(f, 'w');
+ if not p:
+ tcm_mod_err("Unable to open file: " + f)
+
+ buf = "#include \n"
+ buf += "#include \n"
+ buf += "#include \n"
+ buf += "#include \n"
+ buf += "#include \n"
+ buf += "#include \n"
+ buf += "#include \n"
+ buf += "#include \n"
+ buf += "#include \n"
+ buf += "#include \n"
+ buf += "#include \n"
+ buf += "#include \n"
+ buf += "#include \n\n"
+ buf += "#include \n"
+ buf += "#include \n"
+ buf += "#include \n"
+ buf += "#include \n"
+ buf += "#include \n"
+ buf += "#include \n"
+ buf += "#include \n"
+ buf += "#include \n"
+ buf += "#include \n"
+ buf += "#include \n\n"
+ buf += "#include <" + fabric_mod_name + "_base.h>\n"
+ buf += "#include <" + fabric_mod_name + "_fabric.h>\n\n"
+
+ buf += "/* Local pointer to allocated TCM configfs fabric module */\n"
+ buf += "struct target_fabric_configfs *" + fabric_mod_name + "_fabric_configfs;\n\n"
+
+ buf += "static struct se_node_acl *" + fabric_mod_name + "_make_nodeacl(\n"
+ buf += " struct se_portal_group *se_tpg,\n"
+ buf += " struct config_group *group,\n"
+ buf += " const char *name)\n"
+ buf += "{\n"
+ buf += " struct se_node_acl *se_nacl, *se_nacl_new;\n"
+ buf += " struct " + fabric_mod_name + "_nacl *nacl;\n"
+
+ if proto_ident == "FC" or proto_ident == "SAS":
+ buf += " u64 wwpn = 0;\n"
+
+ buf += " u32 nexus_depth;\n\n"
+ buf += " /* " + fabric_mod_name + "_parse_wwn(name, &wwpn, 1) < 0)\n"
+ buf += " return ERR_PTR(-EINVAL); */\n"
+ buf += " se_nacl_new = " + fabric_mod_name + "_alloc_fabric_acl(se_tpg);\n"
+ buf += " if (!(se_nacl_new))\n"
+ buf += " return ERR_PTR(-ENOMEM);\n"
+ buf += "//#warning FIXME: Hardcoded nexus depth in " + fabric_mod_name + "_make_nodeacl()\n"
+ buf += " nexus_depth = 1;\n"
+ buf += " /*\n"
+ buf += " * se_nacl_new may be released by core_tpg_add_initiator_node_acl()\n"
+ buf += " * when converting a NodeACL from demo mode -> explict\n"
+ buf += " */\n"
+ buf += " se_nacl = core_tpg_add_initiator_node_acl(se_tpg, se_nacl_new,\n"
+ buf += " name, nexus_depth);\n"
+ buf += " if (IS_ERR(se_nacl)) {\n"
+ buf += " " + fabric_mod_name + "_release_fabric_acl(se_tpg, se_nacl_new);\n"
+ buf += " return se_nacl;\n"
+ buf += " }\n"
+ buf += " /*\n"
+ buf += " * Locate our struct " + fabric_mod_name + "_nacl and set the FC Nport WWPN\n"
+ buf += " */\n"
+ buf += " nacl = container_of(se_nacl, struct " + fabric_mod_name + "_nacl, se_node_acl);\n"
+
+ if proto_ident == "FC" or proto_ident == "SAS":
+ buf += " nacl->" + fabric_mod_init_port + "_wwpn = wwpn;\n"
+
+ buf += " /* " + fabric_mod_name + "_format_wwn(&nacl->" + fabric_mod_init_port + "_name[0], " + fabric_mod_name.upper() + "_NAMELEN, wwpn); */\n\n"
+ buf += " return se_nacl;\n"
+ buf += "}\n\n"
+ buf += "static void " + fabric_mod_name + "_drop_nodeacl(struct se_node_acl *se_acl)\n"
+ buf += "{\n"
+ buf += " struct " + fabric_mod_name + "_nacl *nacl = container_of(se_acl,\n"
+ buf += " struct " + fabric_mod_name + "_nacl, se_node_acl);\n"
+ buf += " kfree(nacl);\n"
+ buf += "}\n\n"
+
+ buf += "static struct se_portal_group *" + fabric_mod_name + "_make_tpg(\n"
+ buf += " struct se_wwn *wwn,\n"
+ buf += " struct config_group *group,\n"
+ buf += " const char *name)\n"
+ buf += "{\n"
+ buf += " struct " + fabric_mod_name + "_" + fabric_mod_port + "*" + fabric_mod_port + " = container_of(wwn,\n"
+ buf += " struct " + fabric_mod_name + "_" + fabric_mod_port + ", " + fabric_mod_port + "_wwn);\n\n"
+ buf += " struct " + fabric_mod_name + "_tpg *tpg;\n"
+ buf += " unsigned long tpgt;\n"
+ buf += " int ret;\n\n"
+ buf += " if (strstr(name, \"tpgt_\") != name)\n"
+ buf += " return ERR_PTR(-EINVAL);\n"
+ buf += " if (strict_strtoul(name + 5, 10, &tpgt) || tpgt > UINT_MAX)\n"
+ buf += " return ERR_PTR(-EINVAL);\n\n"
+ buf += " tpg = kzalloc(sizeof(struct " + fabric_mod_name + "_tpg), GFP_KERNEL);\n"
+ buf += " if (!(tpg)) {\n"
+ buf += " printk(KERN_ERR \"Unable to allocate struct " + fabric_mod_name + "_tpg\");\n"
+ buf += " return ERR_PTR(-ENOMEM);\n"
+ buf += " }\n"
+ buf += " tpg->" + fabric_mod_port + " = " + fabric_mod_port + ";\n"
+ buf += " tpg->" + fabric_mod_port + "_tpgt = tpgt;\n\n"
+ buf += " ret = core_tpg_register(&" + fabric_mod_name + "_fabric_configfs->tf_ops, wwn,\n"
+ buf += " &tpg->se_tpg, (void *)tpg,\n"
+ buf += " TRANSPORT_TPG_TYPE_NORMAL);\n"
+ buf += " if (ret < 0) {\n"
+ buf += " kfree(tpg);\n"
+ buf += " return NULL;\n"
+ buf += " }\n"
+ buf += " return &tpg->se_tpg;\n"
+ buf += "}\n\n"
+ buf += "static void " + fabric_mod_name + "_drop_tpg(struct se_portal_group *se_tpg)\n"
+ buf += "{\n"
+ buf += " struct " + fabric_mod_name + "_tpg *tpg = container_of(se_tpg,\n"
+ buf += " struct " + fabric_mod_name + "_tpg, se_tpg);\n\n"
+ buf += " core_tpg_deregister(se_tpg);\n"
+ buf += " kfree(tpg);\n"
+ buf += "}\n\n"
+
+ buf += "static struct se_wwn *" + fabric_mod_name + "_make_" + fabric_mod_port + "(\n"
+ buf += " struct target_fabric_configfs *tf,\n"
+ buf += " struct config_group *group,\n"
+ buf += " const char *name)\n"
+ buf += "{\n"
+ buf += " struct " + fabric_mod_name + "_" + fabric_mod_port + " *" + fabric_mod_port + ";\n"
+
+ if proto_ident == "FC" or proto_ident == "SAS":
+ buf += " u64 wwpn = 0;\n\n"
+
+ buf += " /* if (" + fabric_mod_name + "_parse_wwn(name, &wwpn, 1) < 0)\n"
+ buf += " return ERR_PTR(-EINVAL); */\n\n"
+ buf += " " + fabric_mod_port + " = kzalloc(sizeof(struct " + fabric_mod_name + "_" + fabric_mod_port + "), GFP_KERNEL);\n"
+ buf += " if (!(" + fabric_mod_port + ")) {\n"
+ buf += " printk(KERN_ERR \"Unable to allocate struct " + fabric_mod_name + "_" + fabric_mod_port + "\");\n"
+ buf += " return ERR_PTR(-ENOMEM);\n"
+ buf += " }\n"
+
+ if proto_ident == "FC" or proto_ident == "SAS":
+ buf += " " + fabric_mod_port + "->" + fabric_mod_port + "_wwpn = wwpn;\n"
+
+ buf += " /* " + fabric_mod_name + "_format_wwn(&" + fabric_mod_port + "->" + fabric_mod_port + "_name[0], " + fabric_mod_name.upper() + "__NAMELEN, wwpn); */\n\n"
+ buf += " return &" + fabric_mod_port + "->" + fabric_mod_port + "_wwn;\n"
+ buf += "}\n\n"
+ buf += "static void " + fabric_mod_name + "_drop_" + fabric_mod_port + "(struct se_wwn *wwn)\n"
+ buf += "{\n"
+ buf += " struct " + fabric_mod_name + "_" + fabric_mod_port + " *" + fabric_mod_port + " = container_of(wwn,\n"
+ buf += " struct " + fabric_mod_name + "_" + fabric_mod_port + ", " + fabric_mod_port + "_wwn);\n"
+ buf += " kfree(" + fabric_mod_port + ");\n"
+ buf += "}\n\n"
+ buf += "static ssize_t " + fabric_mod_name + "_wwn_show_attr_version(\n"
+ buf += " struct target_fabric_configfs *tf,\n"
+ buf += " char *page)\n"
+ buf += "{\n"
+ buf += " return sprintf(page, \"" + fabric_mod_name.upper() + " fabric module %s on %s/%s\"\n"
+ buf += " \"on \"UTS_RELEASE\"\\n\", " + fabric_mod_name.upper() + "_VERSION, utsname()->sysname,\n"
+ buf += " utsname()->machine);\n"
+ buf += "}\n\n"
+ buf += "TF_WWN_ATTR_RO(" + fabric_mod_name + ", version);\n\n"
+ buf += "static struct configfs_attribute *" + fabric_mod_name + "_wwn_attrs[] = {\n"
+ buf += " &" + fabric_mod_name + "_wwn_version.attr,\n"
+ buf += " NULL,\n"
+ buf += "};\n\n"
+
+ buf += "static struct target_core_fabric_ops " + fabric_mod_name + "_ops = {\n"
+ buf += " .get_fabric_name = " + fabric_mod_name + "_get_fabric_name,\n"
+ buf += " .get_fabric_proto_ident = " + fabric_mod_name + "_get_fabric_proto_ident,\n"
+ buf += " .tpg_get_wwn = " + fabric_mod_name + "_get_fabric_wwn,\n"
+ buf += " .tpg_get_tag = " + fabric_mod_name + "_get_tag,\n"
+ buf += " .tpg_get_default_depth = " + fabric_mod_name + "_get_default_depth,\n"
+ buf += " .tpg_get_pr_transport_id = " + fabric_mod_name + "_get_pr_transport_id,\n"
+ buf += " .tpg_get_pr_transport_id_len = " + fabric_mod_name + "_get_pr_transport_id_len,\n"
+ buf += " .tpg_parse_pr_out_transport_id = " + fabric_mod_name + "_parse_pr_out_transport_id,\n"
+ buf += " .tpg_check_demo_mode = " + fabric_mod_name + "_check_false,\n"
+ buf += " .tpg_check_demo_mode_cache = " + fabric_mod_name + "_check_true,\n"
+ buf += " .tpg_check_demo_mode_write_protect = " + fabric_mod_name + "_check_true,\n"
+ buf += " .tpg_check_prod_mode_write_protect = " + fabric_mod_name + "_check_false,\n"
+ buf += " .tpg_alloc_fabric_acl = " + fabric_mod_name + "_alloc_fabric_acl,\n"
+ buf += " .tpg_release_fabric_acl = " + fabric_mod_name + "_release_fabric_acl,\n"
+ buf += " .tpg_get_inst_index = " + fabric_mod_name + "_tpg_get_inst_index,\n"
+ buf += " .release_cmd_to_pool = " + fabric_mod_name + "_release_cmd,\n"
+ buf += " .release_cmd_direct = " + fabric_mod_name + "_release_cmd,\n"
+ buf += " .shutdown_session = " + fabric_mod_name + "_shutdown_session,\n"
+ buf += " .close_session = " + fabric_mod_name + "_close_session,\n"
+ buf += " .stop_session = " + fabric_mod_name + "_stop_session,\n"
+ buf += " .fall_back_to_erl0 = " + fabric_mod_name + "_reset_nexus,\n"
+ buf += " .sess_logged_in = " + fabric_mod_name + "_sess_logged_in,\n"
+ buf += " .sess_get_index = " + fabric_mod_name + "_sess_get_index,\n"
+ buf += " .sess_get_initiator_sid = NULL,\n"
+ buf += " .write_pending = " + fabric_mod_name + "_write_pending,\n"
+ buf += " .write_pending_status = " + fabric_mod_name + "_write_pending_status,\n"
+ buf += " .set_default_node_attributes = " + fabric_mod_name + "_set_default_node_attrs,\n"
+ buf += " .get_task_tag = " + fabric_mod_name + "_get_task_tag,\n"
+ buf += " .get_cmd_state = " + fabric_mod_name + "_get_cmd_state,\n"
+ buf += " .new_cmd_failure = " + fabric_mod_name + "_new_cmd_failure,\n"
+ buf += " .queue_data_in = " + fabric_mod_name + "_queue_data_in,\n"
+ buf += " .queue_status = " + fabric_mod_name + "_queue_status,\n"
+ buf += " .queue_tm_rsp = " + fabric_mod_name + "_queue_tm_rsp,\n"
+ buf += " .get_fabric_sense_len = " + fabric_mod_name + "_get_fabric_sense_len,\n"
+ buf += " .set_fabric_sense_len = " + fabric_mod_name + "_set_fabric_sense_len,\n"
+ buf += " .is_state_remove = " + fabric_mod_name + "_is_state_remove,\n"
+ buf += " .pack_lun = " + fabric_mod_name + "_pack_lun,\n"
+ buf += " /*\n"
+ buf += " * Setup function pointers for generic logic in target_core_fabric_configfs.c\n"
+ buf += " */\n"
+ buf += " .fabric_make_wwn = " + fabric_mod_name + "_make_" + fabric_mod_port + ",\n"
+ buf += " .fabric_drop_wwn = " + fabric_mod_name + "_drop_" + fabric_mod_port + ",\n"
+ buf += " .fabric_make_tpg = " + fabric_mod_name + "_make_tpg,\n"
+ buf += " .fabric_drop_tpg = " + fabric_mod_name + "_drop_tpg,\n"
+ buf += " .fabric_post_link = NULL,\n"
+ buf += " .fabric_pre_unlink = NULL,\n"
+ buf += " .fabric_make_np = NULL,\n"
+ buf += " .fabric_drop_np = NULL,\n"
+ buf += " .fabric_make_nodeacl = " + fabric_mod_name + "_make_nodeacl,\n"
+ buf += " .fabric_drop_nodeacl = " + fabric_mod_name + "_drop_nodeacl,\n"
+ buf += "};\n\n"
+
+ buf += "static int " + fabric_mod_name + "_register_configfs(void)\n"
+ buf += "{\n"
+ buf += " struct target_fabric_configfs *fabric;\n"
+ buf += " int ret;\n\n"
+ buf += " printk(KERN_INFO \"" + fabric_mod_name.upper() + " fabric module %s on %s/%s\"\n"
+ buf += " \" on \"UTS_RELEASE\"\\n\"," + fabric_mod_name.upper() + "_VERSION, utsname()->sysname,\n"
+ buf += " utsname()->machine);\n"
+ buf += " /*\n"
+ buf += " * Register the top level struct config_item_type with TCM core\n"
+ buf += " */\n"
+ buf += " fabric = target_fabric_configfs_init(THIS_MODULE, \"" + fabric_mod_name[4:] + "\");\n"
+ buf += " if (!(fabric)) {\n"
+ buf += " printk(KERN_ERR \"target_fabric_configfs_init() failed\\n\");\n"
+ buf += " return -ENOMEM;\n"
+ buf += " }\n"
+ buf += " /*\n"
+ buf += " * Setup fabric->tf_ops from our local " + fabric_mod_name + "_ops\n"
+ buf += " */\n"
+ buf += " fabric->tf_ops = " + fabric_mod_name + "_ops;\n"
+ buf += " /*\n"
+ buf += " * Setup default attribute lists for various fabric->tf_cit_tmpl\n"
+ buf += " */\n"
+ buf += " TF_CIT_TMPL(fabric)->tfc_wwn_cit.ct_attrs = " + fabric_mod_name + "_wwn_attrs;\n"
+ buf += " TF_CIT_TMPL(fabric)->tfc_tpg_base_cit.ct_attrs = NULL;\n"
+ buf += " TF_CIT_TMPL(fabric)->tfc_tpg_attrib_cit.ct_attrs = NULL;\n"
+ buf += " TF_CIT_TMPL(fabric)->tfc_tpg_param_cit.ct_attrs = NULL;\n"
+ buf += " TF_CIT_TMPL(fabric)->tfc_tpg_np_base_cit.ct_attrs = NULL;\n"
+ buf += " TF_CIT_TMPL(fabric)->tfc_tpg_nacl_base_cit.ct_attrs = NULL;\n"
+ buf += " TF_CIT_TMPL(fabric)->tfc_tpg_nacl_attrib_cit.ct_attrs = NULL;\n"
+ buf += " TF_CIT_TMPL(fabric)->tfc_tpg_nacl_auth_cit.ct_attrs = NULL;\n"
+ buf += " TF_CIT_TMPL(fabric)->tfc_tpg_nacl_param_cit.ct_attrs = NULL;\n"
+ buf += " /*\n"
+ buf += " * Register the fabric for use within TCM\n"
+ buf += " */\n"
+ buf += " ret = target_fabric_configfs_register(fabric);\n"
+ buf += " if (ret < 0) {\n"
+ buf += " printk(KERN_ERR \"target_fabric_configfs_register() failed\"\n"
+ buf += " \" for " + fabric_mod_name.upper() + "\\n\");\n"
+ buf += " return ret;\n"
+ buf += " }\n"
+ buf += " /*\n"
+ buf += " * Setup our local pointer to *fabric\n"
+ buf += " */\n"
+ buf += " " + fabric_mod_name + "_fabric_configfs = fabric;\n"
+ buf += " printk(KERN_INFO \"" + fabric_mod_name.upper() + "[0] - Set fabric -> " + fabric_mod_name + "_fabric_configfs\\n\");\n"
+ buf += " return 0;\n"
+ buf += "};\n\n"
+ buf += "static void " + fabric_mod_name + "_deregister_configfs(void)\n"
+ buf += "{\n"
+ buf += " if (!(" + fabric_mod_name + "_fabric_configfs))\n"
+ buf += " return;\n\n"
+ buf += " target_fabric_configfs_deregister(" + fabric_mod_name + "_fabric_configfs);\n"
+ buf += " " + fabric_mod_name + "_fabric_configfs = NULL;\n"
+ buf += " printk(KERN_INFO \"" + fabric_mod_name.upper() + "[0] - Cleared " + fabric_mod_name + "_fabric_configfs\\n\");\n"
+ buf += "};\n\n"
+
+ buf += "static int __init " + fabric_mod_name + "_init(void)\n"
+ buf += "{\n"
+ buf += " int ret;\n\n"
+ buf += " ret = " + fabric_mod_name + "_register_configfs();\n"
+ buf += " if (ret < 0)\n"
+ buf += " return ret;\n\n"
+ buf += " return 0;\n"
+ buf += "};\n\n"
+ buf += "static void " + fabric_mod_name + "_exit(void)\n"
+ buf += "{\n"
+ buf += " " + fabric_mod_name + "_deregister_configfs();\n"
+ buf += "};\n\n"
+
+ buf += "#ifdef MODULE\n"
+ buf += "MODULE_DESCRIPTION(\"" + fabric_mod_name.upper() + " series fabric driver\");\n"
+ buf += "MODULE_LICENSE(\"GPL\");\n"
+ buf += "module_init(" + fabric_mod_name + "_init);\n"
+ buf += "module_exit(" + fabric_mod_name + "_exit);\n"
+ buf += "#endif\n"
+
+ ret = p.write(buf)
+ if ret:
+ tcm_mod_err("Unable to write f: " + f)
+
+ p.close()
+
+ return
+
+def tcm_mod_scan_fabric_ops(tcm_dir):
+
+ fabric_ops_api = tcm_dir + "include/target/target_core_fabric_ops.h"
+
+ print "Using tcm_mod_scan_fabric_ops: " + fabric_ops_api
+ process_fo = 0;
+
+ p = open(fabric_ops_api, 'r')
+
+ line = p.readline()
+ while line:
+ if process_fo == 0 and re.search('struct target_core_fabric_ops {', line):
+ line = p.readline()
+ continue
+
+ if process_fo == 0:
+ process_fo = 1;
+ line = p.readline()
+ # Search for function pointer
+ if not re.search('\(\*', line):
+ continue
+
+ fabric_ops.append(line.rstrip())
+ continue
+
+ line = p.readline()
+ # Search for function pointer
+ if not re.search('\(\*', line):
+ continue
+
+ fabric_ops.append(line.rstrip())
+
+ p.close()
+ return
+
+def tcm_mod_dump_fabric_ops(proto_ident, fabric_mod_dir_var, fabric_mod_name):
+ buf = ""
+ bufi = ""
+
+ f = fabric_mod_dir_var + "/" + fabric_mod_name + "_fabric.c"
+ print "Writing file: " + f
+
+ p = open(f, 'w')
+ if not p:
+ tcm_mod_err("Unable to open file: " + f)
+
+ fi = fabric_mod_dir_var + "/" + fabric_mod_name + "_fabric.h"
+ print "Writing file: " + fi
+
+ pi = open(fi, 'w')
+ if not pi:
+ tcm_mod_err("Unable to open file: " + fi)
+
+ buf = "#include \n"
+ buf += "#include \n"
+ buf += "#include \n"
+ buf += "#include \n"
+ buf += "#include \n"
+ buf += "#include \n"
+ buf += "#include \n"
+ buf += "#include \n"
+ buf += "#include \n"
+ buf += "#include \n"
+ buf += "#include \n"
+ buf += "#include \n"
+ buf += "#include \n\n"
+ buf += "#include \n"
+ buf += "#include \n"
+ buf += "#include \n"
+ buf += "#include \n"
+ buf += "#include \n"
+ buf += "#include \n"
+ buf += "#include \n"
+ buf += "#include <" + fabric_mod_name + "_base.h>\n"
+ buf += "#include <" + fabric_mod_name + "_fabric.h>\n\n"
+
+ buf += "int " + fabric_mod_name + "_check_true(struct se_portal_group *se_tpg)\n"
+ buf += "{\n"
+ buf += " return 1;\n"
+ buf += "}\n\n"
+ bufi += "int " + fabric_mod_name + "_check_true(struct se_portal_group *);\n"
+
+ buf += "int " + fabric_mod_name + "_check_false(struct se_portal_group *se_tpg)\n"
+ buf += "{\n"
+ buf += " return 0;\n"
+ buf += "}\n\n"
+ bufi += "int " + fabric_mod_name + "_check_false(struct se_portal_group *);\n"
+
+ total_fabric_ops = len(fabric_ops)
+ i = 0
+
+ while i < total_fabric_ops:
+ fo = fabric_ops[i]
+ i += 1
+# print "fabric_ops: " + fo
+
+ if re.search('get_fabric_name', fo):
+ buf += "char *" + fabric_mod_name + "_get_fabric_name(void)\n"
+ buf += "{\n"
+ buf += " return \"" + fabric_mod_name[4:] + "\";\n"
+ buf += "}\n\n"
+ bufi += "char *" + fabric_mod_name + "_get_fabric_name(void);\n"
+ continue
+
+ if re.search('get_fabric_proto_ident', fo):
+ buf += "u8 " + fabric_mod_name + "_get_fabric_proto_ident(struct se_portal_group *se_tpg)\n"
+ buf += "{\n"
+ buf += " struct " + fabric_mod_name + "_tpg *tpg = container_of(se_tpg,\n"
+ buf += " struct " + fabric_mod_name + "_tpg, se_tpg);\n"
+ buf += " struct " + fabric_mod_name + "_" + fabric_mod_port + " *" + fabric_mod_port + " = tpg->" + fabric_mod_port + ";\n"
+ buf += " u8 proto_id;\n\n"
+ buf += " switch (" + fabric_mod_port + "->" + fabric_mod_port + "_proto_id) {\n"
+ if proto_ident == "FC":
+ buf += " case SCSI_PROTOCOL_FCP:\n"
+ buf += " default:\n"
+ buf += " proto_id = fc_get_fabric_proto_ident(se_tpg);\n"
+ buf += " break;\n"
+ elif proto_ident == "SAS":
+ buf += " case SCSI_PROTOCOL_SAS:\n"
+ buf += " default:\n"
+ buf += " proto_id = sas_get_fabric_proto_ident(se_tpg);\n"
+ buf += " break;\n"
+ elif proto_ident == "iSCSI":
+ buf += " case SCSI_PROTOCOL_ISCSI:\n"
+ buf += " default:\n"
+ buf += " proto_id = iscsi_get_fabric_proto_ident(se_tpg);\n"
+ buf += " break;\n"
+
+ buf += " }\n\n"
+ buf += " return proto_id;\n"
+ buf += "}\n\n"
+ bufi += "u8 " + fabric_mod_name + "_get_fabric_proto_ident(struct se_portal_group *);\n"
+
+ if re.search('get_wwn', fo):
+ buf += "char *" + fabric_mod_name + "_get_fabric_wwn(struct se_portal_group *se_tpg)\n"
+ buf += "{\n"
+ buf += " struct " + fabric_mod_name + "_tpg *tpg = container_of(se_tpg,\n"
+ buf += " struct " + fabric_mod_name + "_tpg, se_tpg);\n"
+ buf += " struct " + fabric_mod_name + "_" + fabric_mod_port + " *" + fabric_mod_port + " = tpg->" + fabric_mod_port + ";\n\n"
+ buf += " return &" + fabric_mod_port + "->" + fabric_mod_port + "_name[0];\n"
+ buf += "}\n\n"
+ bufi += "char *" + fabric_mod_name + "_get_fabric_wwn(struct se_portal_group *);\n"
+
+ if re.search('get_tag', fo):
+ buf += "u16 " + fabric_mod_name + "_get_tag(struct se_portal_group *se_tpg)\n"
+ buf += "{\n"
+ buf += " struct " + fabric_mod_name + "_tpg *tpg = container_of(se_tpg,\n"
+ buf += " struct " + fabric_mod_name + "_tpg, se_tpg);\n"
+ buf += " return tpg->" + fabric_mod_port + "_tpgt;\n"
+ buf += "}\n\n"
+ bufi += "u16 " + fabric_mod_name + "_get_tag(struct se_portal_group *);\n"
+
+ if re.search('get_default_depth', fo):
+ buf += "u32 " + fabric_mod_name + "_get_default_depth(struct se_portal_group *se_tpg)\n"
+ buf += "{\n"
+ buf += " return 1;\n"
+ buf += "}\n\n"
+ bufi += "u32 " + fabric_mod_name + "_get_default_depth(struct se_portal_group *);\n"
+
+ if re.search('get_pr_transport_id\)\(', fo):
+ buf += "u32 " + fabric_mod_name + "_get_pr_transport_id(\n"
+ buf += " struct se_portal_group *se_tpg,\n"
+ buf += " struct se_node_acl *se_nacl,\n"
+ buf += " struct t10_pr_registration *pr_reg,\n"
+ buf += " int *format_code,\n"
+ buf += " unsigned char *buf)\n"
+ buf += "{\n"
+ buf += " struct " + fabric_mod_name + "_tpg *tpg = container_of(se_tpg,\n"
+ buf += " struct " + fabric_mod_name + "_tpg, se_tpg);\n"
+ buf += " struct " + fabric_mod_name + "_" + fabric_mod_port + " *" + fabric_mod_port + " = tpg->" + fabric_mod_port + ";\n"
+ buf += " int ret = 0;\n\n"
+ buf += " switch (" + fabric_mod_port + "->" + fabric_mod_port + "_proto_id) {\n"
+ if proto_ident == "FC":
+ buf += " case SCSI_PROTOCOL_FCP:\n"
+ buf += " default:\n"
+ buf += " ret = fc_get_pr_transport_id(se_tpg, se_nacl, pr_reg,\n"
+ buf += " format_code, buf);\n"
+ buf += " break;\n"
+ elif proto_ident == "SAS":
+ buf += " case SCSI_PROTOCOL_SAS:\n"
+ buf += " default:\n"
+ buf += " ret = sas_get_pr_transport_id(se_tpg, se_nacl, pr_reg,\n"
+ buf += " format_code, buf);\n"
+ buf += " break;\n"
+ elif proto_ident == "iSCSI":
+ buf += " case SCSI_PROTOCOL_ISCSI:\n"
+ buf += " default:\n"
+ buf += " ret = iscsi_get_pr_transport_id(se_tpg, se_nacl, pr_reg,\n"
+ buf += " format_code, buf);\n"
+ buf += " break;\n"
+
+ buf += " }\n\n"
+ buf += " return ret;\n"
+ buf += "}\n\n"
+ bufi += "u32 " + fabric_mod_name + "_get_pr_transport_id(struct se_portal_group *,\n"
+ bufi += " struct se_node_acl *, struct t10_pr_registration *,\n"
+ bufi += " int *, unsigned char *);\n"
+
+ if re.search('get_pr_transport_id_len\)\(', fo):
+ buf += "u32 " + fabric_mod_name + "_get_pr_transport_id_len(\n"
+ buf += " struct se_portal_group *se_tpg,\n"
+ buf += " struct se_node_acl *se_nacl,\n"
+ buf += " struct t10_pr_registration *pr_reg,\n"
+ buf += " int *format_code)\n"
+ buf += "{\n"
+ buf += " struct " + fabric_mod_name + "_tpg *tpg = container_of(se_tpg,\n"
+ buf += " struct " + fabric_mod_name + "_tpg, se_tpg);\n"
+ buf += " struct " + fabric_mod_name + "_" + fabric_mod_port + " *" + fabric_mod_port + " = tpg->" + fabric_mod_port + ";\n"
+ buf += " int ret = 0;\n\n"
+ buf += " switch (" + fabric_mod_port + "->" + fabric_mod_port + "_proto_id) {\n"
+ if proto_ident == "FC":
+ buf += " case SCSI_PROTOCOL_FCP:\n"
+ buf += " default:\n"
+ buf += " ret = fc_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg,\n"
+ buf += " format_code);\n"
+ buf += " break;\n"
+ elif proto_ident == "SAS":
+ buf += " case SCSI_PROTOCOL_SAS:\n"
+ buf += " default:\n"
+ buf += " ret = sas_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg,\n"
+ buf += " format_code);\n"
+ buf += " break;\n"
+ elif proto_ident == "iSCSI":
+ buf += " case SCSI_PROTOCOL_ISCSI:\n"
+ buf += " default:\n"
+ buf += " ret = iscsi_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg,\n"
+ buf += " format_code);\n"
+ buf += " break;\n"
+
+
+ buf += " }\n\n"
+ buf += " return ret;\n"
+ buf += "}\n\n"
+ bufi += "u32 " + fabric_mod_name + "_get_pr_transport_id_len(struct se_portal_group *,\n"
+ bufi += " struct se_node_acl *, struct t10_pr_registration *,\n"
+ bufi += " int *);\n"
+
+ if re.search('parse_pr_out_transport_id\)\(', fo):
+ buf += "char *" + fabric_mod_name + "_parse_pr_out_transport_id(\n"
+ buf += " struct se_portal_group *se_tpg,\n"
+ buf += " const char *buf,\n"
+ buf += " u32 *out_tid_len,\n"
+ buf += " char **port_nexus_ptr)\n"
+ buf += "{\n"
+ buf += " struct " + fabric_mod_name + "_tpg *tpg = container_of(se_tpg,\n"
+ buf += " struct " + fabric_mod_name + "_tpg, se_tpg);\n"
+ buf += " struct " + fabric_mod_name + "_" + fabric_mod_port + " *" + fabric_mod_port + " = tpg->" + fabric_mod_port + ";\n"
+ buf += " char *tid = NULL;\n\n"
+ buf += " switch (" + fabric_mod_port + "->" + fabric_mod_port + "_proto_id) {\n"
+ if proto_ident == "FC":
+ buf += " case SCSI_PROTOCOL_FCP:\n"
+ buf += " default:\n"
+ buf += " tid = fc_parse_pr_out_transport_id(se_tpg, buf, out_tid_len,\n"
+ buf += " port_nexus_ptr);\n"
+ elif proto_ident == "SAS":
+ buf += " case SCSI_PROTOCOL_SAS:\n"
+ buf += " default:\n"
+ buf += " tid = sas_parse_pr_out_transport_id(se_tpg, buf, out_tid_len,\n"
+ buf += " port_nexus_ptr);\n"
+ elif proto_ident == "iSCSI":
+ buf += " case SCSI_PROTOCOL_ISCSI:\n"
+ buf += " default:\n"
+ buf += " tid = iscsi_parse_pr_out_transport_id(se_tpg, buf, out_tid_len,\n"
+ buf += " port_nexus_ptr);\n"
+
+ buf += " }\n\n"
+ buf += " return tid;\n"
+ buf += "}\n\n"
+ bufi += "char *" + fabric_mod_name + "_parse_pr_out_transport_id(struct se_portal_group *,\n"
+ bufi += " const char *, u32 *, char **);\n"
+
+ if re.search('alloc_fabric_acl\)\(', fo):
+ buf += "struct se_node_acl *" + fabric_mod_name + "_alloc_fabric_acl(struct se_portal_group *se_tpg)\n"
+ buf += "{\n"
+ buf += " struct " + fabric_mod_name + "_nacl *nacl;\n\n"
+ buf += " nacl = kzalloc(sizeof(struct " + fabric_mod_name + "_nacl), GFP_KERNEL);\n"
+ buf += " if (!(nacl)) {\n"
+ buf += " printk(KERN_ERR \"Unable to alocate struct " + fabric_mod_name + "_nacl\\n\");\n"
+ buf += " return NULL;\n"
+ buf += " }\n\n"
+ buf += " return &nacl->se_node_acl;\n"
+ buf += "}\n\n"
+ bufi += "struct se_node_acl *" + fabric_mod_name + "_alloc_fabric_acl(struct se_portal_group *);\n"
+
+ if re.search('release_fabric_acl\)\(', fo):
+ buf += "void " + fabric_mod_name + "_release_fabric_acl(\n"
+ buf += " struct se_portal_group *se_tpg,\n"
+ buf += " struct se_node_acl *se_nacl)\n"
+ buf += "{\n"
+ buf += " struct " + fabric_mod_name + "_nacl *nacl = container_of(se_nacl,\n"
+ buf += " struct " + fabric_mod_name + "_nacl, se_node_acl);\n"
+ buf += " kfree(nacl);\n"
+ buf += "}\n\n"
+ bufi += "void " + fabric_mod_name + "_release_fabric_acl(struct se_portal_group *,\n"
+ bufi += " struct se_node_acl *);\n"
+
+ if re.search('tpg_get_inst_index\)\(', fo):
+ buf += "u32 " + fabric_mod_name + "_tpg_get_inst_index(struct se_portal_group *se_tpg)\n"
+ buf += "{\n"
+ buf += " return 1;\n"
+ buf += "}\n\n"
+ bufi += "u32 " + fabric_mod_name + "_tpg_get_inst_index(struct se_portal_group *);\n"
+
+ if re.search('release_cmd_to_pool', fo):
+ buf += "void " + fabric_mod_name + "_release_cmd(struct se_cmd *se_cmd)\n"
+ buf += "{\n"
+ buf += " return;\n"
+ buf += "}\n\n"
+ bufi += "void " + fabric_mod_name + "_release_cmd(struct se_cmd *);\n"
+
+ if re.search('shutdown_session\)\(', fo):
+ buf += "int " + fabric_mod_name + "_shutdown_session(struct se_session *se_sess)\n"
+ buf += "{\n"
+ buf += " return 0;\n"
+ buf += "}\n\n"
+ bufi += "int " + fabric_mod_name + "_shutdown_session(struct se_session *);\n"
+
+ if re.search('close_session\)\(', fo):
+ buf += "void " + fabric_mod_name + "_close_session(struct se_session *se_sess)\n"
+ buf += "{\n"
+ buf += " return;\n"
+ buf += "}\n\n"
+ bufi += "void " + fabric_mod_name + "_close_session(struct se_session *);\n"
+
+ if re.search('stop_session\)\(', fo):
+ buf += "void " + fabric_mod_name + "_stop_session(struct se_session *se_sess, int sess_sleep , int conn_sleep)\n"
+ buf += "{\n"
+ buf += " return;\n"
+ buf += "}\n\n"
+ bufi += "void " + fabric_mod_name + "_stop_session(struct se_session *, int, int);\n"
+
+ if re.search('fall_back_to_erl0\)\(', fo):
+ buf += "void " + fabric_mod_name + "_reset_nexus(struct se_session *se_sess)\n"
+ buf += "{\n"
+ buf += " return;\n"
+ buf += "}\n\n"
+ bufi += "void " + fabric_mod_name + "_reset_nexus(struct se_session *);\n"
+
+ if re.search('sess_logged_in\)\(', fo):
+ buf += "int " + fabric_mod_name + "_sess_logged_in(struct se_session *se_sess)\n"
+ buf += "{\n"
+ buf += " return 0;\n"
+ buf += "}\n\n"
+ bufi += "int " + fabric_mod_name + "_sess_logged_in(struct se_session *);\n"
+
+ if re.search('sess_get_index\)\(', fo):
+ buf += "u32 " + fabric_mod_name + "_sess_get_index(struct se_session *se_sess)\n"
+ buf += "{\n"
+ buf += " return 0;\n"
+ buf += "}\n\n"
+ bufi += "u32 " + fabric_mod_name + "_sess_get_index(struct se_session *);\n"
+
+ if re.search('write_pending\)\(', fo):
+ buf += "int " + fabric_mod_name + "_write_pending(struct se_cmd *se_cmd)\n"
+ buf += "{\n"
+ buf += " return 0;\n"
+ buf += "}\n\n"
+ bufi += "int " + fabric_mod_name + "_write_pending(struct se_cmd *);\n"
+
+ if re.search('write_pending_status\)\(', fo):
+ buf += "int " + fabric_mod_name + "_write_pending_status(struct se_cmd *se_cmd)\n"
+ buf += "{\n"
+ buf += " return 0;\n"
+ buf += "}\n\n"
+ bufi += "int " + fabric_mod_name + "_write_pending_status(struct se_cmd *);\n"
+
+ if re.search('set_default_node_attributes\)\(', fo):
+ buf += "void " + fabric_mod_name + "_set_default_node_attrs(struct se_node_acl *nacl)\n"
+ buf += "{\n"
+ buf += " return;\n"
+ buf += "}\n\n"
+ bufi += "void " + fabric_mod_name + "_set_default_node_attrs(struct se_node_acl *);\n"
+
+ if re.search('get_task_tag\)\(', fo):
+ buf += "u32 " + fabric_mod_name + "_get_task_tag(struct se_cmd *se_cmd)\n"
+ buf += "{\n"
+ buf += " return 0;\n"
+ buf += "}\n\n"
+ bufi += "u32 " + fabric_mod_name + "_get_task_tag(struct se_cmd *);\n"
+
+ if re.search('get_cmd_state\)\(', fo):
+ buf += "int " + fabric_mod_name + "_get_cmd_state(struct se_cmd *se_cmd)\n"
+ buf += "{\n"
+ buf += " return 0;\n"
+ buf += "}\n\n"
+ bufi += "int " + fabric_mod_name + "_get_cmd_state(struct se_cmd *);\n"
+
+ if re.search('new_cmd_failure\)\(', fo):
+ buf += "void " + fabric_mod_name + "_new_cmd_failure(struct se_cmd *se_cmd)\n"
+ buf += "{\n"
+ buf += " return;\n"
+ buf += "}\n\n"
+ bufi += "void " + fabric_mod_name + "_new_cmd_failure(struct se_cmd *);\n"
+
+ if re.search('queue_data_in\)\(', fo):
+ buf += "int " + fabric_mod_name + "_queue_data_in(struct se_cmd *se_cmd)\n"
+ buf += "{\n"
+ buf += " return 0;\n"
+ buf += "}\n\n"
+ bufi += "int " + fabric_mod_name + "_queue_data_in(struct se_cmd *);\n"
+
+ if re.search('queue_status\)\(', fo):
+ buf += "int " + fabric_mod_name + "_queue_status(struct se_cmd *se_cmd)\n"
+ buf += "{\n"
+ buf += " return 0;\n"
+ buf += "}\n\n"
+ bufi += "int " + fabric_mod_name + "_queue_status(struct se_cmd *);\n"
+
+ if re.search('queue_tm_rsp\)\(', fo):
+ buf += "int " + fabric_mod_name + "_queue_tm_rsp(struct se_cmd *se_cmd)\n"
+ buf += "{\n"
+ buf += " return 0;\n"
+ buf += "}\n\n"
+ bufi += "int " + fabric_mod_name + "_queue_tm_rsp(struct se_cmd *);\n"
+
+ if re.search('get_fabric_sense_len\)\(', fo):
+ buf += "u16 " + fabric_mod_name + "_get_fabric_sense_len(void)\n"
+ buf += "{\n"
+ buf += " return 0;\n"
+ buf += "}\n\n"
+ bufi += "u16 " + fabric_mod_name + "_get_fabric_sense_len(void);\n"
+
+ if re.search('set_fabric_sense_len\)\(', fo):
+ buf += "u16 " + fabric_mod_name + "_set_fabric_sense_len(struct se_cmd *se_cmd, u32 sense_length)\n"
+ buf += "{\n"
+ buf += " return 0;\n"
+ buf += "}\n\n"
+ bufi += "u16 " + fabric_mod_name + "_set_fabric_sense_len(struct se_cmd *, u32);\n"
+
+ if re.search('is_state_remove\)\(', fo):
+ buf += "int " + fabric_mod_name + "_is_state_remove(struct se_cmd *se_cmd)\n"
+ buf += "{\n"
+ buf += " return 0;\n"
+ buf += "}\n\n"
+ bufi += "int " + fabric_mod_name + "_is_state_remove(struct se_cmd *);\n"
+
+ if re.search('pack_lun\)\(', fo):
+ buf += "u64 " + fabric_mod_name + "_pack_lun(unsigned int lun)\n"
+ buf += "{\n"
+ buf += " WARN_ON(lun >= 256);\n"
+ buf += " /* Caller wants this byte-swapped */\n"
+ buf += " return cpu_to_le64((lun & 0xff) << 8);\n"
+ buf += "}\n\n"
+ bufi += "u64 " + fabric_mod_name + "_pack_lun(unsigned int);\n"
+
+
+ ret = p.write(buf)
+ if ret:
+ tcm_mod_err("Unable to write f: " + f)
+
+ p.close()
+
+ ret = pi.write(bufi)
+ if ret:
+ tcm_mod_err("Unable to write fi: " + fi)
+
+ pi.close()
+ return
+
+def tcm_mod_build_kbuild(fabric_mod_dir_var, fabric_mod_name):
+
+ buf = ""
+ f = fabric_mod_dir_var + "/Kbuild"
+ print "Writing file: " + f
+
+ p = open(f, 'w')
+ if not p:
+ tcm_mod_err("Unable to open file: " + f)
+
+ buf = "EXTRA_CFLAGS += -I$(srctree)/drivers/target/ -I$(srctree)/include/ -I$(srctree)/drivers/scsi/ -I$(srctree)/include/scsi/ -I$(srctree)/drivers/target/" + fabric_mod_name + "\n\n"
+ buf += fabric_mod_name + "-objs := " + fabric_mod_name + "_fabric.o \\\n"
+ buf += " " + fabric_mod_name + "_configfs.o\n"
+ buf += "obj-$(CONFIG_" + fabric_mod_name.upper() + ") += " + fabric_mod_name + ".o\n"
+
+ ret = p.write(buf)
+ if ret:
+ tcm_mod_err("Unable to write f: " + f)
+
+ p.close()
+ return
+
+def tcm_mod_build_kconfig(fabric_mod_dir_var, fabric_mod_name):
+
+ buf = ""
+ f = fabric_mod_dir_var + "/Kconfig"
+ print "Writing file: " + f
+
+ p = open(f, 'w')
+ if not p:
+ tcm_mod_err("Unable to open file: " + f)
+
+ buf = "config " + fabric_mod_name.upper() + "\n"
+ buf += " tristate \"" + fabric_mod_name.upper() + " fabric module\"\n"
+ buf += " depends on TARGET_CORE && CONFIGFS_FS\n"
+ buf += " default n\n"
+ buf += " ---help---\n"
+ buf += " Say Y here to enable the " + fabric_mod_name.upper() + " fabric module\n"
+
+ ret = p.write(buf)
+ if ret:
+ tcm_mod_err("Unable to write f: " + f)
+
+ p.close()
+ return
+
+def tcm_mod_add_kbuild(tcm_dir, fabric_mod_name):
+ buf = "obj-$(CONFIG_" + fabric_mod_name.upper() + ") += " + fabric_mod_name.lower() + "/\n"
+ kbuild = tcm_dir + "/drivers/target/Kbuild"
+
+ f = open(kbuild, 'a')
+ f.write(buf)
+ f.close()
+ return
+
+def tcm_mod_add_kconfig(tcm_dir, fabric_mod_name):
+ buf = "source \"drivers/target/" + fabric_mod_name.lower() + "/Kconfig\"\n"
+ kconfig = tcm_dir + "/drivers/target/Kconfig"
+
+ f = open(kconfig, 'a')
+ f.write(buf)
+ f.close()
+ return
+
+def main(modname, proto_ident):
+# proto_ident = "FC"
+# proto_ident = "SAS"
+# proto_ident = "iSCSI"
+
+ tcm_dir = os.getcwd();
+ tcm_dir += "/../../"
+ print "tcm_dir: " + tcm_dir
+ fabric_mod_name = modname
+ fabric_mod_dir = tcm_dir + "drivers/target/" + fabric_mod_name
+ print "Set fabric_mod_name: " + fabric_mod_name
+ print "Set fabric_mod_dir: " + fabric_mod_dir
+ print "Using proto_ident: " + proto_ident
+
+ if proto_ident != "FC" and proto_ident != "SAS" and proto_ident != "iSCSI":
+ print "Unsupported proto_ident: " + proto_ident
+ sys.exit(1)
+
+ ret = tcm_mod_create_module_subdir(fabric_mod_dir)
+ if ret:
+ print "tcm_mod_create_module_subdir() failed because module already exists!"
+ sys.exit(1)
+
+ tcm_mod_build_base_includes(proto_ident, fabric_mod_dir, fabric_mod_name)
+ tcm_mod_scan_fabric_ops(tcm_dir)
+ tcm_mod_dump_fabric_ops(proto_ident, fabric_mod_dir, fabric_mod_name)
+ tcm_mod_build_configfs(proto_ident, fabric_mod_dir, fabric_mod_name)
+ tcm_mod_build_kbuild(fabric_mod_dir, fabric_mod_name)
+ tcm_mod_build_kconfig(fabric_mod_dir, fabric_mod_name)
+
+ input = raw_input("Would you like to add " + fabric_mod_name + "to drivers/target/Kbuild..? [yes,no]: ")
+ if input == "yes" or input == "y":
+ tcm_mod_add_kbuild(tcm_dir, fabric_mod_name)
+
+ input = raw_input("Would you like to add " + fabric_mod_name + "to drivers/target/Kconfig..? [yes,no]: ")
+ if input == "yes" or input == "y":
+ tcm_mod_add_kconfig(tcm_dir, fabric_mod_name)
+
+ return
+
+parser = optparse.OptionParser()
+parser.add_option('-m', '--modulename', help='Module name', dest='modname',
+ action='store', nargs=1, type='string')
+parser.add_option('-p', '--protoident', help='Protocol Ident', dest='protoident',
+ action='store', nargs=1, type='string')
+
+(opts, args) = parser.parse_args()
+
+mandatories = ['modname', 'protoident']
+for m in mandatories:
+ if not opts.__dict__[m]:
+ print "mandatory option is missing\n"
+ parser.print_help()
+ exit(-1)
+
+if __name__ == "__main__":
+
+ main(str(opts.modname), opts.protoident)
diff --git a/trunk/Documentation/target/tcm_mod_builder.txt b/trunk/Documentation/target/tcm_mod_builder.txt
new file mode 100644
index 000000000000..84533d8e747f
--- /dev/null
+++ b/trunk/Documentation/target/tcm_mod_builder.txt
@@ -0,0 +1,145 @@
+>>>>>>>>>> The TCM v4 fabric module script generator <<<<<<<<<<
+
+Greetings all,
+
+This document is intended to be a mini-HOWTO for using the tcm_mod_builder.py
+script to generate a brand new functional TCM v4 fabric .ko module of your very own,
+that once built can be immediately be loaded to start access the new TCM/ConfigFS
+fabric skeleton, by simply using:
+
+ modprobe $TCM_NEW_MOD
+ mkdir -p /sys/kernel/config/target/$TCM_NEW_MOD
+
+This script will create a new drivers/target/$TCM_NEW_MOD/, and will do the following
+
+ *) Generate new API callers for drivers/target/target_core_fabric_configs.c logic
+ ->make_nodeacl(), ->drop_nodeacl(), ->make_tpg(), ->drop_tpg()
+ ->make_wwn(), ->drop_wwn(). These are created into $TCM_NEW_MOD/$TCM_NEW_MOD_configfs.c
+ *) Generate basic infrastructure for loading/unloading LKMs and TCM/ConfigFS fabric module
+ using a skeleton struct target_core_fabric_ops API template.
+ *) Based on user defined T10 Proto_Ident for the new fabric module being built,
+ the TransportID / Initiator and Target WWPN related handlers for
+ SPC-3 persistent reservation are automatically generated in $TCM_NEW_MOD/$TCM_NEW_MOD_fabric.c
+ using drivers/target/target_core_fabric_lib.c logic.
+ *) NOP API calls for all other Data I/O path and fabric dependent attribute logic
+ in $TCM_NEW_MOD/$TCM_NEW_MOD_fabric.c
+
+tcm_mod_builder.py depends upon the mandatory '-p $PROTO_IDENT' and '-m
+$FABRIC_MOD_name' parameters, and actually running the script looks like:
+
+target:/mnt/sdb/lio-core-2.6.git/Documentation/target# python tcm_mod_builder.py -p iSCSI -m tcm_nab5000
+tcm_dir: /mnt/sdb/lio-core-2.6.git/Documentation/target/../../
+Set fabric_mod_name: tcm_nab5000
+Set fabric_mod_dir:
+/mnt/sdb/lio-core-2.6.git/Documentation/target/../../drivers/target/tcm_nab5000
+Using proto_ident: iSCSI
+Creating fabric_mod_dir:
+/mnt/sdb/lio-core-2.6.git/Documentation/target/../../drivers/target/tcm_nab5000
+Writing file:
+/mnt/sdb/lio-core-2.6.git/Documentation/target/../../drivers/target/tcm_nab5000/tcm_nab5000_base.h
+Using tcm_mod_scan_fabric_ops:
+/mnt/sdb/lio-core-2.6.git/Documentation/target/../../include/target/target_core_fabric_ops.h
+Writing file:
+/mnt/sdb/lio-core-2.6.git/Documentation/target/../../drivers/target/tcm_nab5000/tcm_nab5000_fabric.c
+Writing file:
+/mnt/sdb/lio-core-2.6.git/Documentation/target/../../drivers/target/tcm_nab5000/tcm_nab5000_fabric.h
+Writing file:
+/mnt/sdb/lio-core-2.6.git/Documentation/target/../../drivers/target/tcm_nab5000/tcm_nab5000_configfs.c
+Writing file:
+/mnt/sdb/lio-core-2.6.git/Documentation/target/../../drivers/target/tcm_nab5000/Kbuild
+Writing file:
+/mnt/sdb/lio-core-2.6.git/Documentation/target/../../drivers/target/tcm_nab5000/Kconfig
+Would you like to add tcm_nab5000to drivers/target/Kbuild..? [yes,no]: yes
+Would you like to add tcm_nab5000to drivers/target/Kconfig..? [yes,no]: yes
+
+At the end of tcm_mod_builder.py. the script will ask to add the following
+line to drivers/target/Kbuild:
+
+ obj-$(CONFIG_TCM_NAB5000) += tcm_nab5000/
+
+and the same for drivers/target/Kconfig:
+
+ source "drivers/target/tcm_nab5000/Kconfig"
+
+*) Run 'make menuconfig' and select the new CONFIG_TCM_NAB5000 item:
+
+ TCM_NAB5000 fabric module
+
+*) Build using 'make modules', once completed you will have:
+
+target:/mnt/sdb/lio-core-2.6.git# ls -la drivers/target/tcm_nab5000/
+total 1348
+drwxr-xr-x 2 root root 4096 2010-10-05 03:23 .
+drwxr-xr-x 9 root root 4096 2010-10-05 03:22 ..
+-rw-r--r-- 1 root root 282 2010-10-05 03:22 Kbuild
+-rw-r--r-- 1 root root 171 2010-10-05 03:22 Kconfig
+-rw-r--r-- 1 root root 49 2010-10-05 03:23 modules.order
+-rw-r--r-- 1 root root 738 2010-10-05 03:22 tcm_nab5000_base.h
+-rw-r--r-- 1 root root 9096 2010-10-05 03:22 tcm_nab5000_configfs.c
+-rw-r--r-- 1 root root 191200 2010-10-05 03:23 tcm_nab5000_configfs.o
+-rw-r--r-- 1 root root 40504 2010-10-05 03:23 .tcm_nab5000_configfs.o.cmd
+-rw-r--r-- 1 root root 5414 2010-10-05 03:22 tcm_nab5000_fabric.c
+-rw-r--r-- 1 root root 2016 2010-10-05 03:22 tcm_nab5000_fabric.h
+-rw-r--r-- 1 root root 190932 2010-10-05 03:23 tcm_nab5000_fabric.o
+-rw-r--r-- 1 root root 40713 2010-10-05 03:23 .tcm_nab5000_fabric.o.cmd
+-rw-r--r-- 1 root root 401861 2010-10-05 03:23 tcm_nab5000.ko
+-rw-r--r-- 1 root root 265 2010-10-05 03:23 .tcm_nab5000.ko.cmd
+-rw-r--r-- 1 root root 459 2010-10-05 03:23 tcm_nab5000.mod.c
+-rw-r--r-- 1 root root 23896 2010-10-05 03:23 tcm_nab5000.mod.o
+-rw-r--r-- 1 root root 22655 2010-10-05 03:23 .tcm_nab5000.mod.o.cmd
+-rw-r--r-- 1 root root 379022 2010-10-05 03:23 tcm_nab5000.o
+-rw-r--r-- 1 root root 211 2010-10-05 03:23 .tcm_nab5000.o.cmd
+
+*) Load the new module, create a lun_0 configfs group, and add new TCM Core
+ IBLOCK backstore symlink to port:
+
+target:/mnt/sdb/lio-core-2.6.git# insmod drivers/target/tcm_nab5000.ko
+target:/mnt/sdb/lio-core-2.6.git# mkdir -p /sys/kernel/config/target/nab5000/iqn.foo/tpgt_1/lun/lun_0
+target:/mnt/sdb/lio-core-2.6.git# cd /sys/kernel/config/target/nab5000/iqn.foo/tpgt_1/lun/lun_0/
+target:/sys/kernel/config/target/nab5000/iqn.foo/tpgt_1/lun/lun_0# ln -s /sys/kernel/config/target/core/iblock_0/lvm_test0 nab5000_port
+
+target:/sys/kernel/config/target/nab5000/iqn.foo/tpgt_1/lun/lun_0# cd -
+target:/mnt/sdb/lio-core-2.6.git# tree /sys/kernel/config/target/nab5000/
+/sys/kernel/config/target/nab5000/
+|-- discovery_auth
+|-- iqn.foo
+| `-- tpgt_1
+| |-- acls
+| |-- attrib
+| |-- lun
+| | `-- lun_0
+| | |-- alua_tg_pt_gp
+| | |-- alua_tg_pt_offline
+| | |-- alua_tg_pt_status
+| | |-- alua_tg_pt_write_md
+| | `-- nab5000_port -> ../../../../../../target/core/iblock_0/lvm_test0
+| |-- np
+| `-- param
+`-- version
+
+target:/mnt/sdb/lio-core-2.6.git# lsmod
+Module Size Used by
+tcm_nab5000 3935 4
+iscsi_target_mod 193211 0
+target_core_stgt 8090 0
+target_core_pscsi 11122 1
+target_core_file 9172 2
+target_core_iblock 9280 1
+target_core_mod 228575 31
+tcm_nab5000,iscsi_target_mod,target_core_stgt,target_core_pscsi,target_core_file,target_core_iblock
+libfc 73681 0
+scsi_debug 56265 0
+scsi_tgt 8666 1 target_core_stgt
+configfs 20644 2 target_core_mod
+
+----------------------------------------------------------------------
+
+Future TODO items:
+
+ *) Add more T10 proto_idents
+ *) Make tcm_mod_dump_fabric_ops() smarter and generate function pointer
+ defs directly from include/target/target_core_fabric_ops.h:struct target_core_fabric_ops
+ structure members.
+
+October 5th, 2010
+Nicholas A. Bellinger
diff --git a/trunk/Documentation/thermal/sysfs-api.txt b/trunk/Documentation/thermal/sysfs-api.txt
index cb3d15bc1aeb..b61e46f449aa 100644
--- a/trunk/Documentation/thermal/sysfs-api.txt
+++ b/trunk/Documentation/thermal/sysfs-api.txt
@@ -278,3 +278,15 @@ method, the sys I/F structure will be built like this:
|---name: acpitz
|---temp1_input: 37000
|---temp1_crit: 100000
+
+4. Event Notification
+
+The framework includes a simple notification mechanism, in the form of a
+netlink event. Netlink socket initialization is done during the _init_
+of the framework. Drivers which intend to use the notification mechanism
+just need to call generate_netlink_event() with two arguments viz
+(originator, event). Typically the originator will be an integer assigned
+to a thermal_zone_device when it registers itself with the framework. The
+event will be one of:{THERMAL_AUX0, THERMAL_AUX1, THERMAL_CRITICAL,
+THERMAL_DEV_FAULT}. Notification can be sent when the current temperature
+crosses any of the configured thresholds.
diff --git a/trunk/Documentation/vm/transhuge.txt b/trunk/Documentation/vm/transhuge.txt
new file mode 100644
index 000000000000..0924aaca3302
--- /dev/null
+++ b/trunk/Documentation/vm/transhuge.txt
@@ -0,0 +1,298 @@
+= Transparent Hugepage Support =
+
+== Objective ==
+
+Performance critical computing applications dealing with large memory
+working sets are already running on top of libhugetlbfs and in turn
+hugetlbfs. Transparent Hugepage Support is an alternative means of
+using huge pages for the backing of virtual memory with huge pages
+that supports the automatic promotion and demotion of page sizes and
+without the shortcomings of hugetlbfs.
+
+Currently it only works for anonymous memory mappings but in the
+future it can expand over the pagecache layer starting with tmpfs.
+
+The reason applications are running faster is because of two
+factors. The first factor is almost completely irrelevant and it's not
+of significant interest because it'll also have the downside of
+requiring larger clear-page copy-page in page faults which is a
+potentially negative effect. The first factor consists in taking a
+single page fault for each 2M virtual region touched by userland (so
+reducing the enter/exit kernel frequency by a 512 times factor). This
+only matters the first time the memory is accessed for the lifetime of
+a memory mapping. The second long lasting and much more important
+factor will affect all subsequent accesses to the memory for the whole
+runtime of the application. The second factor consist of two
+components: 1) the TLB miss will run faster (especially with
+virtualization using nested pagetables but almost always also on bare
+metal without virtualization) and 2) a single TLB entry will be
+mapping a much larger amount of virtual memory in turn reducing the
+number of TLB misses. With virtualization and nested pagetables the
+TLB can be mapped of larger size only if both KVM and the Linux guest
+are using hugepages but a significant speedup already happens if only
+one of the two is using hugepages just because of the fact the TLB
+miss is going to run faster.
+
+== Design ==
+
+- "graceful fallback": mm components which don't have transparent
+ hugepage knowledge fall back to breaking a transparent hugepage and
+ working on the regular pages and their respective regular pmd/pte
+ mappings
+
+- if a hugepage allocation fails because of memory fragmentation,
+ regular pages should be gracefully allocated instead and mixed in
+ the same vma without any failure or significant delay and without
+ userland noticing
+
+- if some task quits and more hugepages become available (either
+ immediately in the buddy or through the VM), guest physical memory
+ backed by regular pages should be relocated on hugepages
+ automatically (with khugepaged)
+
+- it doesn't require memory reservation and in turn it uses hugepages
+ whenever possible (the only possible reservation here is kernelcore=
+ to avoid unmovable pages to fragment all the memory but such a tweak
+ is not specific to transparent hugepage support and it's a generic
+ feature that applies to all dynamic high order allocations in the
+ kernel)
+
+- this initial support only offers the feature in the anonymous memory
+ regions but it'd be ideal to move it to tmpfs and the pagecache
+ later
+
+Transparent Hugepage Support maximizes the usefulness of free memory
+if compared to the reservation approach of hugetlbfs by allowing all
+unused memory to be used as cache or other movable (or even unmovable
+entities). It doesn't require reservation to prevent hugepage
+allocation failures to be noticeable from userland. It allows paging
+and all other advanced VM features to be available on the
+hugepages. It requires no modifications for applications to take
+advantage of it.
+
+Applications however can be further optimized to take advantage of
+this feature, like for example they've been optimized before to avoid
+a flood of mmap system calls for every malloc(4k). Optimizing userland
+is by far not mandatory and khugepaged already can take care of long
+lived page allocations even for hugepage unaware applications that
+deals with large amounts of memory.
+
+In certain cases when hugepages are enabled system wide, application
+may end up allocating more memory resources. An application may mmap a
+large region but only touch 1 byte of it, in that case a 2M page might
+be allocated instead of a 4k page for no good. This is why it's
+possible to disable hugepages system-wide and to only have them inside
+MADV_HUGEPAGE madvise regions.
+
+Embedded systems should enable hugepages only inside madvise regions
+to eliminate any risk of wasting any precious byte of memory and to
+only run faster.
+
+Applications that gets a lot of benefit from hugepages and that don't
+risk to lose memory by using hugepages, should use
+madvise(MADV_HUGEPAGE) on their critical mmapped regions.
+
+== sysfs ==
+
+Transparent Hugepage Support can be entirely disabled (mostly for
+debugging purposes) or only enabled inside MADV_HUGEPAGE regions (to
+avoid the risk of consuming more memory resources) or enabled system
+wide. This can be achieved with one of:
+
+echo always >/sys/kernel/mm/transparent_hugepage/enabled
+echo madvise >/sys/kernel/mm/transparent_hugepage/enabled
+echo never >/sys/kernel/mm/transparent_hugepage/enabled
+
+It's also possible to limit defrag efforts in the VM to generate
+hugepages in case they're not immediately free to madvise regions or
+to never try to defrag memory and simply fallback to regular pages
+unless hugepages are immediately available. Clearly if we spend CPU
+time to defrag memory, we would expect to gain even more by the fact
+we use hugepages later instead of regular pages. This isn't always
+guaranteed, but it may be more likely in case the allocation is for a
+MADV_HUGEPAGE region.
+
+echo always >/sys/kernel/mm/transparent_hugepage/defrag
+echo madvise >/sys/kernel/mm/transparent_hugepage/defrag
+echo never >/sys/kernel/mm/transparent_hugepage/defrag
+
+khugepaged will be automatically started when
+transparent_hugepage/enabled is set to "always" or "madvise, and it'll
+be automatically shutdown if it's set to "never".
+
+khugepaged runs usually at low frequency so while one may not want to
+invoke defrag algorithms synchronously during the page faults, it
+should be worth invoking defrag at least in khugepaged. However it's
+also possible to disable defrag in khugepaged:
+
+echo yes >/sys/kernel/mm/transparent_hugepage/khugepaged/defrag
+echo no >/sys/kernel/mm/transparent_hugepage/khugepaged/defrag
+
+You can also control how many pages khugepaged should scan at each
+pass:
+
+/sys/kernel/mm/transparent_hugepage/khugepaged/pages_to_scan
+
+and how many milliseconds to wait in khugepaged between each pass (you
+can set this to 0 to run khugepaged at 100% utilization of one core):
+
+/sys/kernel/mm/transparent_hugepage/khugepaged/scan_sleep_millisecs
+
+and how many milliseconds to wait in khugepaged if there's an hugepage
+allocation failure to throttle the next allocation attempt.
+
+/sys/kernel/mm/transparent_hugepage/khugepaged/alloc_sleep_millisecs
+
+The khugepaged progress can be seen in the number of pages collapsed:
+
+/sys/kernel/mm/transparent_hugepage/khugepaged/pages_collapsed
+
+for each pass:
+
+/sys/kernel/mm/transparent_hugepage/khugepaged/full_scans
+
+== Boot parameter ==
+
+You can change the sysfs boot time defaults of Transparent Hugepage
+Support by passing the parameter "transparent_hugepage=always" or
+"transparent_hugepage=madvise" or "transparent_hugepage=never"
+(without "") to the kernel command line.
+
+== Need of application restart ==
+
+The transparent_hugepage/enabled values only affect future
+behavior. So to make them effective you need to restart any
+application that could have been using hugepages. This also applies to
+the regions registered in khugepaged.
+
+== get_user_pages and follow_page ==
+
+get_user_pages and follow_page if run on a hugepage, will return the
+head or tail pages as usual (exactly as they would do on
+hugetlbfs). Most gup users will only care about the actual physical
+address of the page and its temporary pinning to release after the I/O
+is complete, so they won't ever notice the fact the page is huge. But
+if any driver is going to mangle over the page structure of the tail
+page (like for checking page->mapping or other bits that are relevant
+for the head page and not the tail page), it should be updated to jump
+to check head page instead (while serializing properly against
+split_huge_page() to avoid the head and tail pages to disappear from
+under it, see the futex code to see an example of that, hugetlbfs also
+needed special handling in futex code for similar reasons).
+
+NOTE: these aren't new constraints to the GUP API, and they match the
+same constrains that applies to hugetlbfs too, so any driver capable
+of handling GUP on hugetlbfs will also work fine on transparent
+hugepage backed mappings.
+
+In case you can't handle compound pages if they're returned by
+follow_page, the FOLL_SPLIT bit can be specified as parameter to
+follow_page, so that it will split the hugepages before returning
+them. Migration for example passes FOLL_SPLIT as parameter to
+follow_page because it's not hugepage aware and in fact it can't work
+at all on hugetlbfs (but it instead works fine on transparent
+hugepages thanks to FOLL_SPLIT). migration simply can't deal with
+hugepages being returned (as it's not only checking the pfn of the
+page and pinning it during the copy but it pretends to migrate the
+memory in regular page sizes and with regular pte/pmd mappings).
+
+== Optimizing the applications ==
+
+To be guaranteed that the kernel will map a 2M page immediately in any
+memory region, the mmap region has to be hugepage naturally
+aligned. posix_memalign() can provide that guarantee.
+
+== Hugetlbfs ==
+
+You can use hugetlbfs on a kernel that has transparent hugepage
+support enabled just fine as always. No difference can be noted in
+hugetlbfs other than there will be less overall fragmentation. All
+usual features belonging to hugetlbfs are preserved and
+unaffected. libhugetlbfs will also work fine as usual.
+
+== Graceful fallback ==
+
+Code walking pagetables but unware about huge pmds can simply call
+split_huge_page_pmd(mm, pmd) where the pmd is the one returned by
+pmd_offset. It's trivial to make the code transparent hugepage aware
+by just grepping for "pmd_offset" and adding split_huge_page_pmd where
+missing after pmd_offset returns the pmd. Thanks to the graceful
+fallback design, with a one liner change, you can avoid to write
+hundred if not thousand of lines of complex code to make your code
+hugepage aware.
+
+If you're not walking pagetables but you run into a physical hugepage
+but you can't handle it natively in your code, you can split it by
+calling split_huge_page(page). This is what the Linux VM does before
+it tries to swapout the hugepage for example.
+
+Example to make mremap.c transparent hugepage aware with a one liner
+change:
+
+diff --git a/mm/mremap.c b/mm/mremap.c
+--- a/mm/mremap.c
++++ b/mm/mremap.c
+@@ -41,6 +41,7 @@ static pmd_t *get_old_pmd(struct mm_stru
+ return NULL;
+
+ pmd = pmd_offset(pud, addr);
++ split_huge_page_pmd(mm, pmd);
+ if (pmd_none_or_clear_bad(pmd))
+ return NULL;
+
+== Locking in hugepage aware code ==
+
+We want as much code as possible hugepage aware, as calling
+split_huge_page() or split_huge_page_pmd() has a cost.
+
+To make pagetable walks huge pmd aware, all you need to do is to call
+pmd_trans_huge() on the pmd returned by pmd_offset. You must hold the
+mmap_sem in read (or write) mode to be sure an huge pmd cannot be
+created from under you by khugepaged (khugepaged collapse_huge_page
+takes the mmap_sem in write mode in addition to the anon_vma lock). If
+pmd_trans_huge returns false, you just fallback in the old code
+paths. If instead pmd_trans_huge returns true, you have to take the
+mm->page_table_lock and re-run pmd_trans_huge. Taking the
+page_table_lock will prevent the huge pmd to be converted into a
+regular pmd from under you (split_huge_page can run in parallel to the
+pagetable walk). If the second pmd_trans_huge returns false, you
+should just drop the page_table_lock and fallback to the old code as
+before. Otherwise you should run pmd_trans_splitting on the pmd. In
+case pmd_trans_splitting returns true, it means split_huge_page is
+already in the middle of splitting the page. So if pmd_trans_splitting
+returns true it's enough to drop the page_table_lock and call
+wait_split_huge_page and then fallback the old code paths. You are
+guaranteed by the time wait_split_huge_page returns, the pmd isn't
+huge anymore. If pmd_trans_splitting returns false, you can proceed to
+process the huge pmd and the hugepage natively. Once finished you can
+drop the page_table_lock.
+
+== compound_lock, get_user_pages and put_page ==
+
+split_huge_page internally has to distribute the refcounts in the head
+page to the tail pages before clearing all PG_head/tail bits from the
+page structures. It can do that easily for refcounts taken by huge pmd
+mappings. But the GUI API as created by hugetlbfs (that returns head
+and tail pages if running get_user_pages on an address backed by any
+hugepage), requires the refcount to be accounted on the tail pages and
+not only in the head pages, if we want to be able to run
+split_huge_page while there are gup pins established on any tail
+page. Failure to be able to run split_huge_page if there's any gup pin
+on any tail page, would mean having to split all hugepages upfront in
+get_user_pages which is unacceptable as too many gup users are
+performance critical and they must work natively on hugepages like
+they work natively on hugetlbfs already (hugetlbfs is simpler because
+hugetlbfs pages cannot be splitted so there wouldn't be requirement of
+accounting the pins on the tail pages for hugetlbfs). If we wouldn't
+account the gup refcounts on the tail pages during gup, we won't know
+anymore which tail page is pinned by gup and which is not while we run
+split_huge_page. But we still have to add the gup pin to the head page
+too, to know when we can free the compound page in case it's never
+splitted during its lifetime. That requires changing not just
+get_page, but put_page as well so that when put_page runs on a tail
+page (and only on a tail page) it will find its respective head page,
+and then it will decrease the head page refcount in addition to the
+tail page refcount. To obtain a head page reliably and to decrease its
+refcount without race conditions, put_page has to serialize against
+__split_huge_page_refcount using a special per-page lock called
+compound_lock.
diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS
index 3dd5c6fce989..1af022e63668 100644
--- a/trunk/MAINTAINERS
+++ b/trunk/MAINTAINERS
@@ -3684,7 +3684,7 @@ F: kernel/debug/
KMEMCHECK
M: Vegard Nossum
-M: Pekka Enberg
+M: Pekka Enberg
S: Maintained
F: Documentation/kmemcheck.txt
F: arch/x86/include/asm/kmemcheck.h
@@ -5272,8 +5272,7 @@ S: Supported
F: drivers/s390/net/
S390 ZCRYPT DRIVER
-M: Felix Beck
-M: Ralph Wuerthner
+M: Holger Dengler
M: linux390@de.ibm.com
L: linux-s390@vger.kernel.org
W: http://www.ibm.com/developerworks/linux/linux390/
@@ -5647,7 +5646,7 @@ F: drivers/net/sky2.*
SLAB ALLOCATOR
M: Christoph Lameter
-M: Pekka Enberg
+M: Pekka Enberg
M: Matt Mackall
L: linux-mm@kvack.org
S: Maintained
@@ -6592,13 +6591,12 @@ F: Documentation/i2c/busses/i2c-viapro
F: drivers/i2c/busses/i2c-viapro.c
VIA SD/MMC CARD CONTROLLER DRIVER
-M: Joseph Chan
+M: Bruce Chang
M: Harald Welte
S: Maintained
F: drivers/mmc/host/via-sdmmc.c
VIA UNICHROME(PRO)/CHROME9 FRAMEBUFFER DRIVER
-M: Joseph Chan
M: Florian Tobias Schandinat
L: linux-fbdev@vger.kernel.org
S: Maintained
diff --git a/trunk/arch/alpha/include/asm/mman.h b/trunk/arch/alpha/include/asm/mman.h
index 99c56d47879d..72db984f8781 100644
--- a/trunk/arch/alpha/include/asm/mman.h
+++ b/trunk/arch/alpha/include/asm/mman.h
@@ -53,6 +53,9 @@
#define MADV_MERGEABLE 12 /* KSM may merge identical pages */
#define MADV_UNMERGEABLE 13 /* KSM may not merge identical pages */
+#define MADV_HUGEPAGE 14 /* Worth backing with hugepages */
+#define MADV_NOHUGEPAGE 15 /* Not worth backing with hugepages */
+
/* compatibility flags */
#define MAP_FILE 0
diff --git a/trunk/arch/arm/Kconfig b/trunk/arch/arm/Kconfig
index e2f801167593..5cff165b7eb0 100644
--- a/trunk/arch/arm/Kconfig
+++ b/trunk/arch/arm/Kconfig
@@ -26,6 +26,8 @@ config ARM
select HAVE_REGS_AND_STACK_ACCESS_API
select HAVE_HW_BREAKPOINT if (PERF_EVENTS && (CPU_V6 || CPU_V7))
select HAVE_C_RECORDMCOUNT
+ select HAVE_GENERIC_HARDIRQS
+ select HAVE_SPARSE_IRQ
help
The ARM series is a line of low-power-consumption RISC chip designs
licensed by ARM Ltd and targeted at embedded applications and
@@ -97,10 +99,6 @@ config MCA
(and especially the web page given
there) before attempting to build an MCA bus kernel.
-config GENERIC_HARDIRQS
- bool
- default y
-
config STACKTRACE_SUPPORT
bool
default y
@@ -180,9 +178,6 @@ config FIQ
config ARCH_MTD_XIP
bool
-config GENERIC_HARDIRQS_NO__DO_IRQ
- def_bool y
-
config ARM_L1_CACHE_SHIFT_6
bool
help
@@ -368,7 +363,7 @@ config ARCH_MXS
bool "Freescale MXS-based"
select GENERIC_CLOCKEVENTS
select ARCH_REQUIRE_GPIOLIB
- select COMMON_CLKDEV
+ select CLKDEV_LOOKUP
help
Support for Freescale MXS-based family of processors
@@ -771,6 +766,7 @@ config ARCH_S5PV310
select ARCH_SPARSEMEM_ENABLE
select GENERIC_GPIO
select HAVE_CLK
+ select ARCH_HAS_CPUFREQ
select GENERIC_CLOCKEVENTS
select HAVE_S3C_RTC if RTC_CLASS
select HAVE_S3C2410_I2C if I2C
@@ -1281,7 +1277,7 @@ config SMP
config SMP_ON_UP
bool "Allow booting SMP kernel on uniprocessor systems (EXPERIMENTAL)"
depends on EXPERIMENTAL
- depends on SMP && !XIP
+ depends on SMP && !XIP_KERNEL
default y
help
SMP kernels contain instructions which fail on non-SMP processors.
@@ -1452,15 +1448,6 @@ config HW_PERF_EVENTS
Enable hardware performance counter support for perf events. If
disabled, perf events will use software events only.
-config SPARSE_IRQ
- def_bool n
- help
- This enables support for sparse irqs. This is useful in general
- as most CPUs have a fairly sparse array of IRQ vectors, which
- the irq_desc then maps directly on to. Systems with a high
- number of off-chip IRQs will want to treat this as
- experimental until they have been independently verified.
-
source "mm/Kconfig"
config FORCE_MAX_ZONEORDER
diff --git a/trunk/arch/arm/common/gic.c b/trunk/arch/arm/common/gic.c
index 0b89ef001330..224377211151 100644
--- a/trunk/arch/arm/common/gic.c
+++ b/trunk/arch/arm/common/gic.c
@@ -50,57 +50,56 @@ struct gic_chip_data {
static struct gic_chip_data gic_data[MAX_GIC_NR] __read_mostly;
-static inline void __iomem *gic_dist_base(unsigned int irq)
+static inline void __iomem *gic_dist_base(struct irq_data *d)
{
- struct gic_chip_data *gic_data = get_irq_chip_data(irq);
+ struct gic_chip_data *gic_data = irq_data_get_irq_chip_data(d);
return gic_data->dist_base;
}
-static inline void __iomem *gic_cpu_base(unsigned int irq)
+static inline void __iomem *gic_cpu_base(struct irq_data *d)
{
- struct gic_chip_data *gic_data = get_irq_chip_data(irq);
+ struct gic_chip_data *gic_data = irq_data_get_irq_chip_data(d);
return gic_data->cpu_base;
}
-static inline unsigned int gic_irq(unsigned int irq)
+static inline unsigned int gic_irq(struct irq_data *d)
{
- struct gic_chip_data *gic_data = get_irq_chip_data(irq);
- return irq - gic_data->irq_offset;
+ struct gic_chip_data *gic_data = irq_data_get_irq_chip_data(d);
+ return d->irq - gic_data->irq_offset;
}
/*
* Routines to acknowledge, disable and enable interrupts
*/
-static void gic_ack_irq(unsigned int irq)
+static void gic_ack_irq(struct irq_data *d)
{
-
spin_lock(&irq_controller_lock);
- writel(gic_irq(irq), gic_cpu_base(irq) + GIC_CPU_EOI);
+ writel(gic_irq(d), gic_cpu_base(d) + GIC_CPU_EOI);
spin_unlock(&irq_controller_lock);
}
-static void gic_mask_irq(unsigned int irq)
+static void gic_mask_irq(struct irq_data *d)
{
- u32 mask = 1 << (irq % 32);
+ u32 mask = 1 << (d->irq % 32);
spin_lock(&irq_controller_lock);
- writel(mask, gic_dist_base(irq) + GIC_DIST_ENABLE_CLEAR + (gic_irq(irq) / 32) * 4);
+ writel(mask, gic_dist_base(d) + GIC_DIST_ENABLE_CLEAR + (gic_irq(d) / 32) * 4);
spin_unlock(&irq_controller_lock);
}
-static void gic_unmask_irq(unsigned int irq)
+static void gic_unmask_irq(struct irq_data *d)
{
- u32 mask = 1 << (irq % 32);
+ u32 mask = 1 << (d->irq % 32);
spin_lock(&irq_controller_lock);
- writel(mask, gic_dist_base(irq) + GIC_DIST_ENABLE_SET + (gic_irq(irq) / 32) * 4);
+ writel(mask, gic_dist_base(d) + GIC_DIST_ENABLE_SET + (gic_irq(d) / 32) * 4);
spin_unlock(&irq_controller_lock);
}
-static int gic_set_type(unsigned int irq, unsigned int type)
+static int gic_set_type(struct irq_data *d, unsigned int type)
{
- void __iomem *base = gic_dist_base(irq);
- unsigned int gicirq = gic_irq(irq);
+ void __iomem *base = gic_dist_base(d);
+ unsigned int gicirq = gic_irq(d);
u32 enablemask = 1 << (gicirq % 32);
u32 enableoff = (gicirq / 32) * 4;
u32 confmask = 0x2 << ((gicirq % 16) * 2);
@@ -143,21 +142,22 @@ static int gic_set_type(unsigned int irq, unsigned int type)
}
#ifdef CONFIG_SMP
-static int gic_set_cpu(unsigned int irq, const struct cpumask *mask_val)
+static int
+gic_set_cpu(struct irq_data *d, const struct cpumask *mask_val, bool force)
{
- void __iomem *reg = gic_dist_base(irq) + GIC_DIST_TARGET + (gic_irq(irq) & ~3);
- unsigned int shift = (irq % 4) * 8;
+ void __iomem *reg = gic_dist_base(d) + GIC_DIST_TARGET + (gic_irq(d) & ~3);
+ unsigned int shift = (d->irq % 4) * 8;
unsigned int cpu = cpumask_first(mask_val);
u32 val;
struct irq_desc *desc;
spin_lock(&irq_controller_lock);
- desc = irq_to_desc(irq);
+ desc = irq_to_desc(d->irq);
if (desc == NULL) {
spin_unlock(&irq_controller_lock);
return -EINVAL;
}
- desc->node = cpu;
+ d->node = cpu;
val = readl(reg) & ~(0xff << shift);
val |= 1 << (cpu + shift);
writel(val, reg);
@@ -175,7 +175,7 @@ static void gic_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)
unsigned long status;
/* primary controller ack'ing */
- chip->ack(irq);
+ chip->irq_ack(&desc->irq_data);
spin_lock(&irq_controller_lock);
status = readl(chip_data->cpu_base + GIC_CPU_INTACK);
@@ -193,17 +193,17 @@ static void gic_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)
out:
/* primary controller unmasking */
- chip->unmask(irq);
+ chip->irq_unmask(&desc->irq_data);
}
static struct irq_chip gic_chip = {
- .name = "GIC",
- .ack = gic_ack_irq,
- .mask = gic_mask_irq,
- .unmask = gic_unmask_irq,
- .set_type = gic_set_type,
+ .name = "GIC",
+ .irq_ack = gic_ack_irq,
+ .irq_mask = gic_mask_irq,
+ .irq_unmask = gic_unmask_irq,
+ .irq_set_type = gic_set_type,
#ifdef CONFIG_SMP
- .set_affinity = gic_set_cpu,
+ .irq_set_affinity = gic_set_cpu,
#endif
};
@@ -337,7 +337,7 @@ void __cpuinit gic_enable_ppi(unsigned int irq)
local_irq_save(flags);
irq_to_desc(irq)->status |= IRQ_NOPROBE;
- gic_unmask_irq(irq);
+ gic_unmask_irq(irq_get_irq_data(irq));
local_irq_restore(flags);
}
diff --git a/trunk/arch/arm/common/it8152.c b/trunk/arch/arm/common/it8152.c
index 665ebf7e62a6..fcddd48fe9da 100644
--- a/trunk/arch/arm/common/it8152.c
+++ b/trunk/arch/arm/common/it8152.c
@@ -31,8 +31,10 @@
#define MAX_SLOTS 21
-static void it8152_mask_irq(unsigned int irq)
+static void it8152_mask_irq(struct irq_data *d)
{
+ unsigned int irq = d->irq;
+
if (irq >= IT8152_LD_IRQ(0)) {
__raw_writel((__raw_readl(IT8152_INTC_LDCNIMR) |
(1 << (irq - IT8152_LD_IRQ(0)))),
@@ -48,8 +50,10 @@ static void it8152_mask_irq(unsigned int irq)
}
}
-static void it8152_unmask_irq(unsigned int irq)
+static void it8152_unmask_irq(struct irq_data *d)
{
+ unsigned int irq = d->irq;
+
if (irq >= IT8152_LD_IRQ(0)) {
__raw_writel((__raw_readl(IT8152_INTC_LDCNIMR) &
~(1 << (irq - IT8152_LD_IRQ(0)))),
@@ -67,9 +71,9 @@ static void it8152_unmask_irq(unsigned int irq)
static struct irq_chip it8152_irq_chip = {
.name = "it8152",
- .ack = it8152_mask_irq,
- .mask = it8152_mask_irq,
- .unmask = it8152_unmask_irq,
+ .irq_ack = it8152_mask_irq,
+ .irq_mask = it8152_mask_irq,
+ .irq_unmask = it8152_unmask_irq,
};
void it8152_init_irq(void)
diff --git a/trunk/arch/arm/common/locomo.c b/trunk/arch/arm/common/locomo.c
index 9dff07c80ddb..a026a6bf4892 100644
--- a/trunk/arch/arm/common/locomo.c
+++ b/trunk/arch/arm/common/locomo.c
@@ -144,7 +144,7 @@ static void locomo_handler(unsigned int irq, struct irq_desc *desc)
int req, i;
/* Acknowledge the parent IRQ */
- desc->chip->ack(irq);
+ desc->irq_data.chip->irq_ack(&desc->irq_data);
/* check why this interrupt was generated */
req = locomo_readl(lchip->base + LOCOMO_ICR) & 0x0f00;
@@ -161,33 +161,33 @@ static void locomo_handler(unsigned int irq, struct irq_desc *desc)
}
}
-static void locomo_ack_irq(unsigned int irq)
+static void locomo_ack_irq(struct irq_data *d)
{
}
-static void locomo_mask_irq(unsigned int irq)
+static void locomo_mask_irq(struct irq_data *d)
{
- struct locomo *lchip = get_irq_chip_data(irq);
+ struct locomo *lchip = irq_data_get_irq_chip_data(d);
unsigned int r;
r = locomo_readl(lchip->base + LOCOMO_ICR);
- r &= ~(0x0010 << (irq - lchip->irq_base));
+ r &= ~(0x0010 << (d->irq - lchip->irq_base));
locomo_writel(r, lchip->base + LOCOMO_ICR);
}
-static void locomo_unmask_irq(unsigned int irq)
+static void locomo_unmask_irq(struct irq_data *d)
{
- struct locomo *lchip = get_irq_chip_data(irq);
+ struct locomo *lchip = irq_data_get_irq_chip_data(d);
unsigned int r;
r = locomo_readl(lchip->base + LOCOMO_ICR);
- r |= (0x0010 << (irq - lchip->irq_base));
+ r |= (0x0010 << (d->irq - lchip->irq_base));
locomo_writel(r, lchip->base + LOCOMO_ICR);
}
static struct irq_chip locomo_chip = {
- .name = "LOCOMO",
- .ack = locomo_ack_irq,
- .mask = locomo_mask_irq,
- .unmask = locomo_unmask_irq,
+ .name = "LOCOMO",
+ .irq_ack = locomo_ack_irq,
+ .irq_mask = locomo_mask_irq,
+ .irq_unmask = locomo_unmask_irq,
};
static void locomo_setup_irq(struct locomo *lchip)
diff --git a/trunk/arch/arm/common/sa1111.c b/trunk/arch/arm/common/sa1111.c
index c0258a8c103b..eb9796b0dab2 100644
--- a/trunk/arch/arm/common/sa1111.c
+++ b/trunk/arch/arm/common/sa1111.c
@@ -210,7 +210,7 @@ sa1111_irq_handler(unsigned int irq, struct irq_desc *desc)
sa1111_writel(stat0, mapbase + SA1111_INTSTATCLR0);
- desc->chip->ack(irq);
+ desc->irq_data.chip->irq_ack(&desc->irq_data);
sa1111_writel(stat1, mapbase + SA1111_INTSTATCLR1);
@@ -228,35 +228,35 @@ sa1111_irq_handler(unsigned int irq, struct irq_desc *desc)
generic_handle_irq(i + sachip->irq_base);
/* For level-based interrupts */
- desc->chip->unmask(irq);
+ desc->irq_data.chip->irq_unmask(&desc->irq_data);
}
#define SA1111_IRQMASK_LO(x) (1 << (x - sachip->irq_base))
#define SA1111_IRQMASK_HI(x) (1 << (x - sachip->irq_base - 32))
-static void sa1111_ack_irq(unsigned int irq)
+static void sa1111_ack_irq(struct irq_data *d)
{
}
-static void sa1111_mask_lowirq(unsigned int irq)
+static void sa1111_mask_lowirq(struct irq_data *d)
{
- struct sa1111 *sachip = get_irq_chip_data(irq);
+ struct sa1111 *sachip = irq_data_get_irq_chip_data(d);
void __iomem *mapbase = sachip->base + SA1111_INTC;
unsigned long ie0;
ie0 = sa1111_readl(mapbase + SA1111_INTEN0);
- ie0 &= ~SA1111_IRQMASK_LO(irq);
+ ie0 &= ~SA1111_IRQMASK_LO(d->irq);
writel(ie0, mapbase + SA1111_INTEN0);
}
-static void sa1111_unmask_lowirq(unsigned int irq)
+static void sa1111_unmask_lowirq(struct irq_data *d)
{
- struct sa1111 *sachip = get_irq_chip_data(irq);
+ struct sa1111 *sachip = irq_data_get_irq_chip_data(d);
void __iomem *mapbase = sachip->base + SA1111_INTC;
unsigned long ie0;
ie0 = sa1111_readl(mapbase + SA1111_INTEN0);
- ie0 |= SA1111_IRQMASK_LO(irq);
+ ie0 |= SA1111_IRQMASK_LO(d->irq);
sa1111_writel(ie0, mapbase + SA1111_INTEN0);
}
@@ -267,11 +267,11 @@ static void sa1111_unmask_lowirq(unsigned int irq)
* be triggered. In fact, its very difficult, if not impossible to get
* INTSET to re-trigger the interrupt.
*/
-static int sa1111_retrigger_lowirq(unsigned int irq)
+static int sa1111_retrigger_lowirq(struct irq_data *d)
{
- struct sa1111 *sachip = get_irq_chip_data(irq);
+ struct sa1111 *sachip = irq_data_get_irq_chip_data(d);
void __iomem *mapbase = sachip->base + SA1111_INTC;
- unsigned int mask = SA1111_IRQMASK_LO(irq);
+ unsigned int mask = SA1111_IRQMASK_LO(d->irq);
unsigned long ip0;
int i;
@@ -279,21 +279,21 @@ static int sa1111_retrigger_lowirq(unsigned int irq)
for (i = 0; i < 8; i++) {
sa1111_writel(ip0 ^ mask, mapbase + SA1111_INTPOL0);
sa1111_writel(ip0, mapbase + SA1111_INTPOL0);
- if (sa1111_readl(mapbase + SA1111_INTSTATCLR1) & mask)
+ if (sa1111_readl(mapbase + SA1111_INTSTATCLR0) & mask)
break;
}
if (i == 8)
printk(KERN_ERR "Danger Will Robinson: failed to "
- "re-trigger IRQ%d\n", irq);
+ "re-trigger IRQ%d\n", d->irq);
return i == 8 ? -1 : 0;
}
-static int sa1111_type_lowirq(unsigned int irq, unsigned int flags)
+static int sa1111_type_lowirq(struct irq_data *d, unsigned int flags)
{
- struct sa1111 *sachip = get_irq_chip_data(irq);
+ struct sa1111 *sachip = irq_data_get_irq_chip_data(d);
void __iomem *mapbase = sachip->base + SA1111_INTC;
- unsigned int mask = SA1111_IRQMASK_LO(irq);
+ unsigned int mask = SA1111_IRQMASK_LO(d->irq);
unsigned long ip0;
if (flags == IRQ_TYPE_PROBE)
@@ -313,11 +313,11 @@ static int sa1111_type_lowirq(unsigned int irq, unsigned int flags)
return 0;
}
-static int sa1111_wake_lowirq(unsigned int irq, unsigned int on)
+static int sa1111_wake_lowirq(struct irq_data *d, unsigned int on)
{
- struct sa1111 *sachip = get_irq_chip_data(irq);
+ struct sa1111 *sachip = irq_data_get_irq_chip_data(d);
void __iomem *mapbase = sachip->base + SA1111_INTC;
- unsigned int mask = SA1111_IRQMASK_LO(irq);
+ unsigned int mask = SA1111_IRQMASK_LO(d->irq);
unsigned long we0;
we0 = sa1111_readl(mapbase + SA1111_WAKEEN0);
@@ -332,33 +332,33 @@ static int sa1111_wake_lowirq(unsigned int irq, unsigned int on)
static struct irq_chip sa1111_low_chip = {
.name = "SA1111-l",
- .ack = sa1111_ack_irq,
- .mask = sa1111_mask_lowirq,
- .unmask = sa1111_unmask_lowirq,
- .retrigger = sa1111_retrigger_lowirq,
- .set_type = sa1111_type_lowirq,
- .set_wake = sa1111_wake_lowirq,
+ .irq_ack = sa1111_ack_irq,
+ .irq_mask = sa1111_mask_lowirq,
+ .irq_unmask = sa1111_unmask_lowirq,
+ .irq_retrigger = sa1111_retrigger_lowirq,
+ .irq_set_type = sa1111_type_lowirq,
+ .irq_set_wake = sa1111_wake_lowirq,
};
-static void sa1111_mask_highirq(unsigned int irq)
+static void sa1111_mask_highirq(struct irq_data *d)
{
- struct sa1111 *sachip = get_irq_chip_data(irq);
+ struct sa1111 *sachip = irq_data_get_irq_chip_data(d);
void __iomem *mapbase = sachip->base + SA1111_INTC;
unsigned long ie1;
ie1 = sa1111_readl(mapbase + SA1111_INTEN1);
- ie1 &= ~SA1111_IRQMASK_HI(irq);
+ ie1 &= ~SA1111_IRQMASK_HI(d->irq);
sa1111_writel(ie1, mapbase + SA1111_INTEN1);
}
-static void sa1111_unmask_highirq(unsigned int irq)
+static void sa1111_unmask_highirq(struct irq_data *d)
{
- struct sa1111 *sachip = get_irq_chip_data(irq);
+ struct sa1111 *sachip = irq_data_get_irq_chip_data(d);
void __iomem *mapbase = sachip->base + SA1111_INTC;
unsigned long ie1;
ie1 = sa1111_readl(mapbase + SA1111_INTEN1);
- ie1 |= SA1111_IRQMASK_HI(irq);
+ ie1 |= SA1111_IRQMASK_HI(d->irq);
sa1111_writel(ie1, mapbase + SA1111_INTEN1);
}
@@ -369,11 +369,11 @@ static void sa1111_unmask_highirq(unsigned int irq)
* be triggered. In fact, its very difficult, if not impossible to get
* INTSET to re-trigger the interrupt.
*/
-static int sa1111_retrigger_highirq(unsigned int irq)
+static int sa1111_retrigger_highirq(struct irq_data *d)
{
- struct sa1111 *sachip = get_irq_chip_data(irq);
+ struct sa1111 *sachip = irq_data_get_irq_chip_data(d);
void __iomem *mapbase = sachip->base + SA1111_INTC;
- unsigned int mask = SA1111_IRQMASK_HI(irq);
+ unsigned int mask = SA1111_IRQMASK_HI(d->irq);
unsigned long ip1;
int i;
@@ -387,15 +387,15 @@ static int sa1111_retrigger_highirq(unsigned int irq)
if (i == 8)
printk(KERN_ERR "Danger Will Robinson: failed to "
- "re-trigger IRQ%d\n", irq);
+ "re-trigger IRQ%d\n", d->irq);
return i == 8 ? -1 : 0;
}
-static int sa1111_type_highirq(unsigned int irq, unsigned int flags)
+static int sa1111_type_highirq(struct irq_data *d, unsigned int flags)
{
- struct sa1111 *sachip = get_irq_chip_data(irq);
+ struct sa1111 *sachip = irq_data_get_irq_chip_data(d);
void __iomem *mapbase = sachip->base + SA1111_INTC;
- unsigned int mask = SA1111_IRQMASK_HI(irq);
+ unsigned int mask = SA1111_IRQMASK_HI(d->irq);
unsigned long ip1;
if (flags == IRQ_TYPE_PROBE)
@@ -415,11 +415,11 @@ static int sa1111_type_highirq(unsigned int irq, unsigned int flags)
return 0;
}
-static int sa1111_wake_highirq(unsigned int irq, unsigned int on)
+static int sa1111_wake_highirq(struct irq_data *d, unsigned int on)
{
- struct sa1111 *sachip = get_irq_chip_data(irq);
+ struct sa1111 *sachip = irq_data_get_irq_chip_data(d);
void __iomem *mapbase = sachip->base + SA1111_INTC;
- unsigned int mask = SA1111_IRQMASK_HI(irq);
+ unsigned int mask = SA1111_IRQMASK_HI(d->irq);
unsigned long we1;
we1 = sa1111_readl(mapbase + SA1111_WAKEEN1);
@@ -434,12 +434,12 @@ static int sa1111_wake_highirq(unsigned int irq, unsigned int on)
static struct irq_chip sa1111_high_chip = {
.name = "SA1111-h",
- .ack = sa1111_ack_irq,
- .mask = sa1111_mask_highirq,
- .unmask = sa1111_unmask_highirq,
- .retrigger = sa1111_retrigger_highirq,
- .set_type = sa1111_type_highirq,
- .set_wake = sa1111_wake_highirq,
+ .irq_ack = sa1111_ack_irq,
+ .irq_mask = sa1111_mask_highirq,
+ .irq_unmask = sa1111_unmask_highirq,
+ .irq_retrigger = sa1111_retrigger_highirq,
+ .irq_set_type = sa1111_type_highirq,
+ .irq_set_wake = sa1111_wake_highirq,
};
static void sa1111_setup_irq(struct sa1111 *sachip)
diff --git a/trunk/arch/arm/common/vic.c b/trunk/arch/arm/common/vic.c
index cb660bc54d7a..ae5fe7292e0d 100644
--- a/trunk/arch/arm/common/vic.c
+++ b/trunk/arch/arm/common/vic.c
@@ -204,26 +204,26 @@ static void __init vic_pm_register(void __iomem *base, unsigned int irq, u32 res
static inline void vic_pm_register(void __iomem *base, unsigned int irq, u32 arg1) { }
#endif /* CONFIG_PM */
-static void vic_ack_irq(unsigned int irq)
+static void vic_ack_irq(struct irq_data *d)
{
- void __iomem *base = get_irq_chip_data(irq);
- irq &= 31;
+ void __iomem *base = irq_data_get_irq_chip_data(d);
+ unsigned int irq = d->irq & 31;
writel(1 << irq, base + VIC_INT_ENABLE_CLEAR);
/* moreover, clear the soft-triggered, in case it was the reason */
writel(1 << irq, base + VIC_INT_SOFT_CLEAR);
}
-static void vic_mask_irq(unsigned int irq)
+static void vic_mask_irq(struct irq_data *d)
{
- void __iomem *base = get_irq_chip_data(irq);
- irq &= 31;
+ void __iomem *base = irq_data_get_irq_chip_data(d);
+ unsigned int irq = d->irq & 31;
writel(1 << irq, base + VIC_INT_ENABLE_CLEAR);
}
-static void vic_unmask_irq(unsigned int irq)
+static void vic_unmask_irq(struct irq_data *d)
{
- void __iomem *base = get_irq_chip_data(irq);
- irq &= 31;
+ void __iomem *base = irq_data_get_irq_chip_data(d);
+ unsigned int irq = d->irq & 31;
writel(1 << irq, base + VIC_INT_ENABLE);
}
@@ -242,10 +242,10 @@ static struct vic_device *vic_from_irq(unsigned int irq)
return NULL;
}
-static int vic_set_wake(unsigned int irq, unsigned int on)
+static int vic_set_wake(struct irq_data *d, unsigned int on)
{
- struct vic_device *v = vic_from_irq(irq);
- unsigned int off = irq & 31;
+ struct vic_device *v = vic_from_irq(d->irq);
+ unsigned int off = d->irq & 31;
u32 bit = 1 << off;
if (!v)
@@ -267,10 +267,10 @@ static int vic_set_wake(unsigned int irq, unsigned int on)
static struct irq_chip vic_chip = {
.name = "VIC",
- .ack = vic_ack_irq,
- .mask = vic_mask_irq,
- .unmask = vic_unmask_irq,
- .set_wake = vic_set_wake,
+ .irq_ack = vic_ack_irq,
+ .irq_mask = vic_mask_irq,
+ .irq_unmask = vic_unmask_irq,
+ .irq_set_wake = vic_set_wake,
};
static void __init vic_disable(void __iomem *base)
diff --git a/trunk/arch/arm/include/asm/bitops.h b/trunk/arch/arm/include/asm/bitops.h
index 338ff19ae447..7b1bb2bbaf88 100644
--- a/trunk/arch/arm/include/asm/bitops.h
+++ b/trunk/arch/arm/include/asm/bitops.h
@@ -285,7 +285,7 @@ static inline int fls(int x)
if (__builtin_constant_p(x))
return constant_fls(x);
- asm("clz\t%0, %1" : "=r" (ret) : "r" (x) : "cc");
+ asm("clz\t%0, %1" : "=r" (ret) : "r" (x));
ret = 32 - ret;
return ret;
}
diff --git a/trunk/arch/arm/include/asm/sched_clock.h b/trunk/arch/arm/include/asm/sched_clock.h
index a84628be1a7b..c8e6ddf3e860 100644
--- a/trunk/arch/arm/include/asm/sched_clock.h
+++ b/trunk/arch/arm/include/asm/sched_clock.h
@@ -115,4 +115,6 @@ static inline void init_fixed_sched_clock(struct clock_data *cd,
}
}
+extern void sched_clock_postinit(void);
+
#endif
diff --git a/trunk/arch/arm/kernel/ecard.c b/trunk/arch/arm/kernel/ecard.c
index eed2f795e1b3..2ad62df37730 100644
--- a/trunk/arch/arm/kernel/ecard.c
+++ b/trunk/arch/arm/kernel/ecard.c
@@ -443,40 +443,40 @@ static expansioncard_ops_t ecard_default_ops = {
*
* They are not meant to be called directly, but via enable/disable_irq.
*/
-static void ecard_irq_unmask(unsigned int irqnr)
+static void ecard_irq_unmask(struct irq_data *d)
{
- ecard_t *ec = slot_to_ecard(irqnr - 32);
+ ecard_t *ec = slot_to_ecard(d->irq - 32);
if (ec) {
if (!ec->ops)
ec->ops = &ecard_default_ops;
if (ec->claimed && ec->ops->irqenable)
- ec->ops->irqenable(ec, irqnr);
+ ec->ops->irqenable(ec, d->irq);
else
printk(KERN_ERR "ecard: rejecting request to "
- "enable IRQs for %d\n", irqnr);
+ "enable IRQs for %d\n", d->irq);
}
}
-static void ecard_irq_mask(unsigned int irqnr)
+static void ecard_irq_mask(struct irq_data *d)
{
- ecard_t *ec = slot_to_ecard(irqnr - 32);
+ ecard_t *ec = slot_to_ecard(d->irq - 32);
if (ec) {
if (!ec->ops)
ec->ops = &ecard_default_ops;
if (ec->ops && ec->ops->irqdisable)
- ec->ops->irqdisable(ec, irqnr);
+ ec->ops->irqdisable(ec, d->irq);
}
}
static struct irq_chip ecard_chip = {
- .name = "ECARD",
- .ack = ecard_irq_mask,
- .mask = ecard_irq_mask,
- .unmask = ecard_irq_unmask,
+ .name = "ECARD",
+ .irq_ack = ecard_irq_mask,
+ .irq_mask = ecard_irq_mask,
+ .irq_unmask = ecard_irq_unmask,
};
void ecard_enablefiq(unsigned int fiqnr)
@@ -551,7 +551,7 @@ static void ecard_check_lockup(struct irq_desc *desc)
printk(KERN_ERR "\nInterrupt lockup detected - "
"disabling all expansion card interrupts\n");
- desc->chip->mask(IRQ_EXPANSIONCARD);
+ desc->irq_data.chip->irq_mask(&desc->irq_data);
ecard_dump_irq_state();
}
} else
@@ -574,7 +574,7 @@ ecard_irq_handler(unsigned int irq, struct irq_desc *desc)
ecard_t *ec;
int called = 0;
- desc->chip->mask(irq);
+ desc->irq_data.chip->irq_mask(&desc->irq_data);
for (ec = cards; ec; ec = ec->next) {
int pending;
@@ -591,7 +591,7 @@ ecard_irq_handler(unsigned int irq, struct irq_desc *desc)
called ++;
}
}
- desc->chip->unmask(irq);
+ desc->irq_data.chip->irq_unmask(&desc->irq_data);
if (called == 0)
ecard_check_lockup(desc);
diff --git a/trunk/arch/arm/kernel/head-common.S b/trunk/arch/arm/kernel/head-common.S
index bbecaac1e013..8f57515bbdb0 100644
--- a/trunk/arch/arm/kernel/head-common.S
+++ b/trunk/arch/arm/kernel/head-common.S
@@ -60,6 +60,8 @@ str_a1: .asciz "\nError: unrecognized/unsupported machine ID (r1 = 0x"
str_a2: .asciz ").\n\nAvailable machine support:\n\nID (hex)\tNAME\n"
str_a3: .asciz "\nPlease check your kernel config and/or bootloader.\n"
.align
+#else
+ b __error
#endif
/*
diff --git a/trunk/arch/arm/kernel/irq.c b/trunk/arch/arm/kernel/irq.c
index 8135438b8818..28536e352deb 100644
--- a/trunk/arch/arm/kernel/irq.c
+++ b/trunk/arch/arm/kernel/irq.c
@@ -88,7 +88,7 @@ int show_interrupts(struct seq_file *p, void *v)
seq_printf(p, "%*d: ", prec, i);
for_each_present_cpu(cpu)
seq_printf(p, "%10u ", kstat_irqs_cpu(i, cpu));
- seq_printf(p, " %10s", desc->chip->name ? : "-");
+ seq_printf(p, " %10s", desc->irq_data.chip->name ? : "-");
seq_printf(p, " %s", action->name);
for (action = action->next; action; action = action->next)
seq_printf(p, ", %s", action->name);
@@ -181,10 +181,11 @@ int __init arch_probe_nr_irqs(void)
static void route_irq(struct irq_desc *desc, unsigned int irq, unsigned int cpu)
{
- pr_debug("IRQ%u: moving from cpu%u to cpu%u\n", irq, desc->node, cpu);
+ pr_debug("IRQ%u: moving from cpu%u to cpu%u\n", irq, desc->irq_data.node, cpu);
raw_spin_lock_irq(&desc->lock);
- desc->chip->set_affinity(irq, cpumask_of(cpu));
+ desc->irq_data.chip->irq_set_affinity(&desc->irq_data,
+ cpumask_of(cpu), false);
raw_spin_unlock_irq(&desc->lock);
}
@@ -199,16 +200,18 @@ void migrate_irqs(void)
struct irq_desc *desc;
for_each_irq_desc(i, desc) {
- if (desc->node == cpu) {
- unsigned int newcpu = cpumask_any_and(desc->affinity,
+ struct irq_data *d = &desc->irq_data;
+
+ if (d->node == cpu) {
+ unsigned int newcpu = cpumask_any_and(d->affinity,
cpu_online_mask);
if (newcpu >= nr_cpu_ids) {
if (printk_ratelimit())
printk(KERN_INFO "IRQ%u no longer affine to CPU%u\n",
i, cpu);
- cpumask_setall(desc->affinity);
- newcpu = cpumask_any_and(desc->affinity,
+ cpumask_setall(d->affinity);
+ newcpu = cpumask_any_and(d->affinity,
cpu_online_mask);
}
diff --git a/trunk/arch/arm/kernel/module.c b/trunk/arch/arm/kernel/module.c
index 0c1bb68ff4a8..2cfe8161b478 100644
--- a/trunk/arch/arm/kernel/module.c
+++ b/trunk/arch/arm/kernel/module.c
@@ -38,17 +38,9 @@
#ifdef CONFIG_MMU
void *module_alloc(unsigned long size)
{
- struct vm_struct *area;
-
- size = PAGE_ALIGN(size);
- if (!size)
- return NULL;
-
- area = __get_vm_area(size, VM_ALLOC, MODULES_VADDR, MODULES_END);
- if (!area)
- return NULL;
-
- return __vmalloc_area(area, GFP_KERNEL, PAGE_KERNEL_EXEC);
+ return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END,
+ GFP_KERNEL, PAGE_KERNEL_EXEC, -1,
+ __builtin_return_address(0));
}
#else /* CONFIG_MMU */
void *module_alloc(unsigned long size)
diff --git a/trunk/arch/arm/kernel/process.c b/trunk/arch/arm/kernel/process.c
index e76fcaadce03..94bbedbed639 100644
--- a/trunk/arch/arm/kernel/process.c
+++ b/trunk/arch/arm/kernel/process.c
@@ -483,6 +483,7 @@ unsigned long arch_randomize_brk(struct mm_struct *mm)
return randomize_range(mm->brk, range_end, 0) ? : mm->brk;
}
+#ifdef CONFIG_MMU
/*
* The vectors page is always readable from user space for the
* atomic helpers and the signal restart code. Let's declare a mapping
@@ -503,3 +504,4 @@ const char *arch_vma_name(struct vm_area_struct *vma)
{
return (vma->vm_start == 0xffff0000) ? "[vectors]" : NULL;
}
+#endif
diff --git a/trunk/arch/arm/kernel/sched_clock.c b/trunk/arch/arm/kernel/sched_clock.c
index 2cdcc9287c74..9a46370fe9da 100644
--- a/trunk/arch/arm/kernel/sched_clock.c
+++ b/trunk/arch/arm/kernel/sched_clock.c
@@ -34,7 +34,7 @@ void __init init_sched_clock(struct clock_data *cd, void (*update)(void),
sched_clock_update_fn = update;
/* calculate the mult/shift to convert counter ticks to ns. */
- clocks_calc_mult_shift(&cd->mult, &cd->shift, rate, NSEC_PER_SEC, 60);
+ clocks_calc_mult_shift(&cd->mult, &cd->shift, rate, NSEC_PER_SEC, 0);
r = rate;
if (r >= 4000000) {
@@ -60,10 +60,15 @@ void __init init_sched_clock(struct clock_data *cd, void (*update)(void),
* sets the initial epoch.
*/
sched_clock_timer.data = msecs_to_jiffies(w - (w / 10));
- sched_clock_poll(sched_clock_timer.data);
+ update();
/*
* Ensure that sched_clock() starts off at 0ns
*/
cd->epoch_ns = 0;
}
+
+void __init sched_clock_postinit(void)
+{
+ sched_clock_poll(sched_clock_timer.data);
+}
diff --git a/trunk/arch/arm/kernel/setup.c b/trunk/arch/arm/kernel/setup.c
index 3455ad33de4c..420b8d6485d6 100644
--- a/trunk/arch/arm/kernel/setup.c
+++ b/trunk/arch/arm/kernel/setup.c
@@ -518,25 +518,21 @@ setup_ramdisk(int doload, int prompt, int image_start, unsigned int rd_sz)
#endif
}
-static void __init
-request_standard_resources(struct meminfo *mi, struct machine_desc *mdesc)
+static void __init request_standard_resources(struct machine_desc *mdesc)
{
+ struct memblock_region *region;
struct resource *res;
- int i;
kernel_code.start = virt_to_phys(_text);
kernel_code.end = virt_to_phys(_etext - 1);
kernel_data.start = virt_to_phys(_sdata);
kernel_data.end = virt_to_phys(_end - 1);
- for (i = 0; i < mi->nr_banks; i++) {
- if (mi->bank[i].size == 0)
- continue;
-
+ for_each_memblock(memory, region) {
res = alloc_bootmem_low(sizeof(*res));
res->name = "System RAM";
- res->start = mi->bank[i].start;
- res->end = mi->bank[i].start + mi->bank[i].size - 1;
+ res->start = __pfn_to_phys(memblock_region_memory_base_pfn(region));
+ res->end = __pfn_to_phys(memblock_region_memory_end_pfn(region)) - 1;
res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
request_resource(&iomem_resource, res);
@@ -650,15 +646,17 @@ static int __init parse_tag_revision(const struct tag *tag)
__tagtable(ATAG_REVISION, parse_tag_revision);
-#ifndef CONFIG_CMDLINE_FORCE
static int __init parse_tag_cmdline(const struct tag *tag)
{
+#ifndef CONFIG_CMDLINE_FORCE
strlcpy(default_command_line, tag->u.cmdline.cmdline, COMMAND_LINE_SIZE);
+#else
+ pr_warning("Ignoring tag cmdline (using the default kernel command line)\n");
+#endif /* CONFIG_CMDLINE_FORCE */
return 0;
}
__tagtable(ATAG_CMDLINE, parse_tag_cmdline);
-#endif /* CONFIG_CMDLINE_FORCE */
/*
* Scan the tag table for this tag, and call its parse function.
@@ -857,7 +855,7 @@ void __init setup_arch(char **cmdline_p)
arm_memblock_init(&meminfo, mdesc);
paging_init(mdesc);
- request_standard_resources(&meminfo, mdesc);
+ request_standard_resources(mdesc);
#ifdef CONFIG_SMP
if (is_smp())
diff --git a/trunk/arch/arm/kernel/smp_twd.c b/trunk/arch/arm/kernel/smp_twd.c
index dd790745b3ef..fd9156698ab9 100644
--- a/trunk/arch/arm/kernel/smp_twd.c
+++ b/trunk/arch/arm/kernel/smp_twd.c
@@ -114,7 +114,7 @@ static void __cpuinit twd_calibrate_rate(void)
twd_timer_rate = (0xFFFFFFFFU - count) * (HZ / 5);
printk("%lu.%02luMHz.\n", twd_timer_rate / 1000000,
- (twd_timer_rate / 100000) % 100);
+ (twd_timer_rate / 1000000) % 100);
}
load = twd_timer_rate / HZ;
diff --git a/trunk/arch/arm/kernel/stacktrace.c b/trunk/arch/arm/kernel/stacktrace.c
index c2e112e1a05f..381d23a497c1 100644
--- a/trunk/arch/arm/kernel/stacktrace.c
+++ b/trunk/arch/arm/kernel/stacktrace.c
@@ -94,10 +94,13 @@ void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
if (tsk != current) {
#ifdef CONFIG_SMP
/*
- * What guarantees do we have here that 'tsk'
- * is not running on another CPU?
+ * What guarantees do we have here that 'tsk' is not
+ * running on another CPU? For now, ignore it as we
+ * can't guarantee we won't explode.
*/
- BUG();
+ if (trace->nr_entries < trace->max_entries)
+ trace->entries[trace->nr_entries++] = ULONG_MAX;
+ return;
#else
data.no_sched_functions = 1;
frame.fp = thread_saved_fp(tsk);
diff --git a/trunk/arch/arm/kernel/time.c b/trunk/arch/arm/kernel/time.c
index f1e2eb19a67d..3d76bf233734 100644
--- a/trunk/arch/arm/kernel/time.c
+++ b/trunk/arch/arm/kernel/time.c
@@ -29,6 +29,7 @@
#include
#include
+#include
#include
#include
#include
@@ -163,5 +164,8 @@ void __init time_init(void)
{
system_timer = machine_desc->timer;
system_timer->init();
+#ifdef CONFIG_HAVE_SCHED_CLOCK
+ sched_clock_postinit();
+#endif
}
diff --git a/trunk/arch/arm/lib/delay.S b/trunk/arch/arm/lib/delay.S
index 8d6a8762ab88..3c9a05c8d20b 100644
--- a/trunk/arch/arm/lib/delay.S
+++ b/trunk/arch/arm/lib/delay.S
@@ -25,11 +25,15 @@ ENTRY(__udelay)
ldr r2, .LC1
mul r0, r2, r0
ENTRY(__const_udelay) @ 0 <= r0 <= 0x7fffff06
+ mov r1, #-1
ldr r2, .LC0
ldr r2, [r2] @ max = 0x01ffffff
+ add r0, r0, r1, lsr #32-14
mov r0, r0, lsr #14 @ max = 0x0001ffff
+ add r2, r2, r1, lsr #32-10
mov r2, r2, lsr #10 @ max = 0x00007fff
mul r0, r2, r0 @ max = 2^32-1
+ add r0, r0, r1, lsr #32-6
movs r0, r0, lsr #6
moveq pc, lr
diff --git a/trunk/arch/arm/mach-aaec2000/core.c b/trunk/arch/arm/mach-aaec2000/core.c
index 3ef68330452a..f8465bd17e67 100644
--- a/trunk/arch/arm/mach-aaec2000/core.c
+++ b/trunk/arch/arm/mach-aaec2000/core.c
@@ -68,25 +68,25 @@ void __init aaec2000_map_io(void)
/*
* Interrupt handling routines
*/
-static void aaec2000_int_ack(unsigned int irq)
+static void aaec2000_int_ack(struct irq_data *d)
{
- IRQ_INTSR = 1 << irq;
+ IRQ_INTSR = 1 << d->irq;
}
-static void aaec2000_int_mask(unsigned int irq)
+static void aaec2000_int_mask(struct irq_data *d)
{
- IRQ_INTENC |= (1 << irq);
+ IRQ_INTENC |= (1 << d->irq);
}
-static void aaec2000_int_unmask(unsigned int irq)
+static void aaec2000_int_unmask(struct irq_data *d)
{
- IRQ_INTENS |= (1 << irq);
+ IRQ_INTENS |= (1 << d->irq);
}
static struct irq_chip aaec2000_irq_chip = {
- .ack = aaec2000_int_ack,
- .mask = aaec2000_int_mask,
- .unmask = aaec2000_int_unmask,
+ .irq_ack = aaec2000_int_ack,
+ .irq_mask = aaec2000_int_mask,
+ .irq_unmask = aaec2000_int_unmask,
};
void __init aaec2000_init_irq(void)
diff --git a/trunk/arch/arm/mach-at91/Kconfig b/trunk/arch/arm/mach-at91/Kconfig
index c015b684b4fe..19390231a0e9 100644
--- a/trunk/arch/arm/mach-at91/Kconfig
+++ b/trunk/arch/arm/mach-at91/Kconfig
@@ -362,6 +362,12 @@ config MACH_CPU9G20
Select this if you are using a Eukrea Electromatique's
CPU9G20 Board
+config MACH_ACMENETUSFOXG20
+ bool "Acme Systems srl FOX Board G20"
+ help
+ Select this if you are using Acme Systems
+ FOX Board G20
+
config MACH_PORTUXG20
bool "taskit PortuxG20"
help
@@ -381,6 +387,13 @@ config MACH_PCONTROL_G20
Select this if you are using taskit's Stamp9G20 CPU module on this
carrier board, beeing the decentralized unit of a building automation
system; featuring nvram, eth-switch, iso-rs485, display, io
+
+config MACH_GSIA18S
+ bool "GS_IA18_S board"
+ help
+ This enables support for the GS_IA18_S board
+ produced by GeoSIG Ltd company. This is an internet accelerograph.
+
endif
if (ARCH_AT91SAM9260 || ARCH_AT91SAM9G20)
diff --git a/trunk/arch/arm/mach-at91/Makefile b/trunk/arch/arm/mach-at91/Makefile
index d13add71f72a..a83835e0c185 100644
--- a/trunk/arch/arm/mach-at91/Makefile
+++ b/trunk/arch/arm/mach-at91/Makefile
@@ -63,9 +63,11 @@ obj-$(CONFIG_MACH_AT91SAM9RLEK) += board-sam9rlek.o
# AT91SAM9G20 board-specific support
obj-$(CONFIG_MACH_AT91SAM9G20EK) += board-sam9g20ek.o
obj-$(CONFIG_MACH_CPU9G20) += board-cpu9krea.o
+obj-$(CONFIG_MACH_ACMENETUSFOXG20) += board-foxg20.o
obj-$(CONFIG_MACH_STAMP9G20) += board-stamp9g20.o
obj-$(CONFIG_MACH_PORTUXG20) += board-stamp9g20.o
obj-$(CONFIG_MACH_PCONTROL_G20) += board-pcontrol-g20.o board-stamp9g20.o
+obj-$(CONFIG_MACH_GSIA18S) += board-gsia18s.o board-stamp9g20.o
# AT91SAM9260/AT91SAM9G20 board-specific support
obj-$(CONFIG_MACH_SNAPPER_9260) += board-snapper9260.o
diff --git a/trunk/arch/arm/mach-at91/board-foxg20.c b/trunk/arch/arm/mach-at91/board-foxg20.c
new file mode 100644
index 000000000000..dfc7dfe738e4
--- /dev/null
+++ b/trunk/arch/arm/mach-at91/board-foxg20.c
@@ -0,0 +1,274 @@
+/*
+ * Copyright (C) 2005 SAN People
+ * Copyright (C) 2008 Atmel
+ * Copyright (C) 2010 Lee McLoughlin - lee@lmmrtech.com
+ * Copyright (C) 2010 Sergio Tanzilli - tanzilli@acmesystems.it
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+#include
+#include
+
+#include "sam9_smc.h"
+#include "generic.h"
+
+/*
+ * The FOX Board G20 hardware comes as the "Netus G20" board with
+ * just the cpu, ram, dataflash and two header connectors.
+ * This is plugged into the FOX Board which provides the ethernet,
+ * usb, rtc, leds, switch, ...
+ *
+ * For more info visit: http://www.acmesystems.it/foxg20
+ */
+
+
+static void __init foxg20_map_io(void)
+{
+ /* Initialize processor: 18.432 MHz crystal */
+ at91sam9260_initialize(18432000);
+
+ /* DBGU on ttyS0. (Rx & Tx only) */
+ at91_register_uart(0, 0, 0);
+
+ /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
+ at91_register_uart(AT91SAM9260_ID_US0, 1,
+ ATMEL_UART_CTS
+ | ATMEL_UART_RTS
+ | ATMEL_UART_DTR
+ | ATMEL_UART_DSR
+ | ATMEL_UART_DCD
+ | ATMEL_UART_RI);
+
+ /* USART1 on ttyS2. (Rx, Tx, RTS, CTS) */
+ at91_register_uart(AT91SAM9260_ID_US1, 2,
+ ATMEL_UART_CTS
+ | ATMEL_UART_RTS);
+
+ /* USART2 on ttyS3. (Rx & Tx only) */
+ at91_register_uart(AT91SAM9260_ID_US2, 3, 0);
+
+ /* USART3 on ttyS4. (Rx, Tx, RTS, CTS) */
+ at91_register_uart(AT91SAM9260_ID_US3, 4,
+ ATMEL_UART_CTS
+ | ATMEL_UART_RTS);
+
+ /* USART4 on ttyS5. (Rx & Tx only) */
+ at91_register_uart(AT91SAM9260_ID_US4, 5, 0);
+
+ /* USART5 on ttyS6. (Rx & Tx only) */
+ at91_register_uart(AT91SAM9260_ID_US5, 6, 0);
+
+ /* set serial console to ttyS0 (ie, DBGU) */
+ at91_set_serial_console(0);
+
+ /* Set the internal pull-up resistor on DRXD */
+ at91_set_A_periph(AT91_PIN_PB14, 1);
+
+}
+
+static void __init foxg20_init_irq(void)
+{
+ at91sam9260_init_interrupts(NULL);
+}
+
+
+/*
+ * USB Host port
+ */
+static struct at91_usbh_data __initdata foxg20_usbh_data = {
+ .ports = 2,
+};
+
+/*
+ * USB Device port
+ */
+static struct at91_udc_data __initdata foxg20_udc_data = {
+ .vbus_pin = AT91_PIN_PC6,
+ .pullup_pin = 0, /* pull-up driven by UDC */
+};
+
+
+/*
+ * SPI devices.
+ */
+static struct spi_board_info foxg20_spi_devices[] = {
+#if !defined(CONFIG_MMC_AT91)
+ {
+ .modalias = "mtd_dataflash",
+ .chip_select = 1,
+ .max_speed_hz = 15 * 1000 * 1000,
+ .bus_num = 0,
+ },
+#endif
+};
+
+
+/*
+ * MACB Ethernet device
+ */
+static struct at91_eth_data __initdata foxg20_macb_data = {
+ .phy_irq_pin = AT91_PIN_PA7,
+ .is_rmii = 1,
+};
+
+/*
+ * MCI (SD/MMC)
+ * det_pin, wp_pin and vcc_pin are not connected
+ */
+static struct at91_mmc_data __initdata foxg20_mmc_data = {
+ .slot_b = 1,
+ .wire4 = 1,
+};
+
+
+/*
+ * LEDs
+ */
+static struct gpio_led foxg20_leds[] = {
+ { /* user led, red */
+ .name = "user_led",
+ .gpio = AT91_PIN_PC7,
+ .active_low = 0,
+ .default_trigger = "heartbeat",
+ },
+};
+
+
+/*
+ * GPIO Buttons
+ */
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+static struct gpio_keys_button foxg20_buttons[] = {
+ {
+ .gpio = AT91_PIN_PC4,
+ .code = BTN_1,
+ .desc = "Button 1",
+ .active_low = 1,
+ .wakeup = 1,
+ },
+};
+
+static struct gpio_keys_platform_data foxg20_button_data = {
+ .buttons = foxg20_buttons,
+ .nbuttons = ARRAY_SIZE(foxg20_buttons),
+};
+
+static struct platform_device foxg20_button_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &foxg20_button_data,
+ }
+};
+
+static void __init foxg20_add_device_buttons(void)
+{
+ at91_set_gpio_input(AT91_PIN_PC4, 1); /* btn1 */
+ at91_set_deglitch(AT91_PIN_PC4, 1);
+
+ platform_device_register(&foxg20_button_device);
+}
+#else
+static void __init foxg20_add_device_buttons(void) {}
+#endif
+
+
+#if defined(CONFIG_W1_MASTER_GPIO) || defined(CONFIG_W1_MASTER_GPIO_MODULE)
+static struct w1_gpio_platform_data w1_gpio_pdata = {
+ /* If you choose to use a pin other than PB16 it needs to be 3.3V */
+ .pin = AT91_PIN_PB16,
+ .is_open_drain = 1,
+};
+
+static struct platform_device w1_device = {
+ .name = "w1-gpio",
+ .id = -1,
+ .dev.platform_data = &w1_gpio_pdata,
+};
+
+static void __init at91_add_device_w1(void)
+{
+ at91_set_GPIO_periph(w1_gpio_pdata.pin, 1);
+ at91_set_multi_drive(w1_gpio_pdata.pin, 1);
+ platform_device_register(&w1_device);
+}
+
+#endif
+
+
+static struct i2c_board_info __initdata foxg20_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("24c512", 0x50),
+ },
+};
+
+
+static void __init foxg20_board_init(void)
+{
+ /* Serial */
+ at91_add_device_serial();
+ /* USB Host */
+ at91_add_device_usbh(&foxg20_usbh_data);
+ /* USB Device */
+ at91_add_device_udc(&foxg20_udc_data);
+ /* SPI */
+ at91_add_device_spi(foxg20_spi_devices, ARRAY_SIZE(foxg20_spi_devices));
+ /* Ethernet */
+ at91_add_device_eth(&foxg20_macb_data);
+ /* MMC */
+ at91_add_device_mmc(0, &foxg20_mmc_data);
+ /* I2C */
+ at91_add_device_i2c(foxg20_i2c_devices, ARRAY_SIZE(foxg20_i2c_devices));
+ /* LEDs */
+ at91_gpio_leds(foxg20_leds, ARRAY_SIZE(foxg20_leds));
+ /* Push Buttons */
+ foxg20_add_device_buttons();
+#if defined(CONFIG_W1_MASTER_GPIO) || defined(CONFIG_W1_MASTER_GPIO_MODULE)
+ at91_add_device_w1();
+#endif
+}
+
+MACHINE_START(ACMENETUSFOXG20, "Acme Systems srl FOX Board G20")
+ /* Maintainer: Sergio Tanzilli */
+ .boot_params = AT91_SDRAM_BASE + 0x100,
+ .timer = &at91sam926x_timer,
+ .map_io = foxg20_map_io,
+ .init_irq = foxg20_init_irq,
+ .init_machine = foxg20_board_init,
+MACHINE_END
diff --git a/trunk/arch/arm/mach-at91/board-gsia18s.c b/trunk/arch/arm/mach-at91/board-gsia18s.c
new file mode 100644
index 000000000000..bc28136ee249
--- /dev/null
+++ b/trunk/arch/arm/mach-at91/board-gsia18s.c
@@ -0,0 +1,584 @@
+/*
+ * Copyright (C) 2010 Christian Glindkamp
+ * taskit GmbH
+ * 2010 Igor Plyatov
+ * GeoSIG Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+#include
+#include
+#include
+#include
+
+#include "sam9_smc.h"
+#include "generic.h"
+
+static void __init gsia18s_map_io(void)
+{
+ stamp9g20_map_io();
+
+ /*
+ * USART0 on ttyS1 (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI).
+ * Used for Internal Analog Modem.
+ */
+ at91_register_uart(AT91SAM9260_ID_US0, 1,
+ ATMEL_UART_CTS | ATMEL_UART_RTS |
+ ATMEL_UART_DTR | ATMEL_UART_DSR |
+ ATMEL_UART_DCD | ATMEL_UART_RI);
+ /*
+ * USART1 on ttyS2 (Rx, Tx, CTS, RTS).
+ * Used for GPS or WiFi or Data stream.
+ */
+ at91_register_uart(AT91SAM9260_ID_US1, 2,
+ ATMEL_UART_CTS | ATMEL_UART_RTS);
+ /*
+ * USART2 on ttyS3 (Rx, Tx, CTS, RTS).
+ * Used for External Modem.
+ */
+ at91_register_uart(AT91SAM9260_ID_US2, 3,
+ ATMEL_UART_CTS | ATMEL_UART_RTS);
+ /*
+ * USART3 on ttyS4 (Rx, Tx, RTS).
+ * Used for RS-485.
+ */
+ at91_register_uart(AT91SAM9260_ID_US3, 4, ATMEL_UART_RTS);
+
+ /*
+ * USART4 on ttyS5 (Rx, Tx).
+ * Used for TRX433 Radio Module.
+ */
+ at91_register_uart(AT91SAM9260_ID_US4, 5, 0);
+}
+
+static void __init init_irq(void)
+{
+ at91sam9260_init_interrupts(NULL);
+}
+
+/*
+ * Two USB Host ports
+ */
+static struct at91_usbh_data __initdata usbh_data = {
+ .ports = 2,
+};
+
+/*
+ * USB Device port
+ */
+static struct at91_udc_data __initdata udc_data = {
+ .vbus_pin = AT91_PIN_PA22,
+ .pullup_pin = 0, /* pull-up driven by UDC */
+};
+
+/*
+ * MACB Ethernet device
+ */
+static struct at91_eth_data __initdata macb_data = {
+ .phy_irq_pin = AT91_PIN_PA28,
+ .is_rmii = 1,
+};
+
+/*
+ * LEDs and GPOs
+ */
+static struct gpio_led gpio_leds[] = {
+ {
+ .name = "gpo:spi1reset",
+ .gpio = AT91_PIN_PC1,
+ .active_low = 0,
+ .default_trigger = "none",
+ .default_state = LEDS_GPIO_DEFSTATE_OFF,
+ },
+ {
+ .name = "gpo:trig_net_out",
+ .gpio = AT91_PIN_PB20,
+ .active_low = 0,
+ .default_trigger = "none",
+ .default_state = LEDS_GPIO_DEFSTATE_OFF,
+ },
+ {
+ .name = "gpo:trig_net_dir",
+ .gpio = AT91_PIN_PB19,
+ .active_low = 0,
+ .default_trigger = "none",
+ .default_state = LEDS_GPIO_DEFSTATE_OFF,
+ },
+ {
+ .name = "gpo:charge_dis",
+ .gpio = AT91_PIN_PC2,
+ .active_low = 0,
+ .default_trigger = "none",
+ .default_state = LEDS_GPIO_DEFSTATE_OFF,
+ },
+ {
+ .name = "led:event",
+ .gpio = AT91_PIN_PB17,
+ .active_low = 1,
+ .default_trigger = "none",
+ .default_state = LEDS_GPIO_DEFSTATE_OFF,
+ },
+ {
+ .name = "led:lan",
+ .gpio = AT91_PIN_PB18,
+ .active_low = 1,
+ .default_trigger = "none",
+ .default_state = LEDS_GPIO_DEFSTATE_OFF,
+ },
+ {
+ .name = "led:error",
+ .gpio = AT91_PIN_PB16,
+ .active_low = 1,
+ .default_trigger = "none",
+ .default_state = LEDS_GPIO_DEFSTATE_ON,
+ }
+};
+
+static struct gpio_led_platform_data gpio_led_info = {
+ .leds = gpio_leds,
+ .num_leds = ARRAY_SIZE(gpio_leds),
+};
+
+static struct platform_device leds = {
+ .name = "leds-gpio",
+ .id = 0,
+ .dev = {
+ .platform_data = &gpio_led_info,
+ }
+};
+
+static void __init gsia18s_leds_init(void)
+{
+ platform_device_register(&leds);
+}
+
+/* PCF8574 0x20 GPIO - U1 on the GS_IA18-CB_V3 board */
+static struct gpio_led pcf_gpio_leds1[] = {
+ { /* bit 0 */
+ .name = "gpo:hdc_power",
+ .gpio = PCF_GPIO_HDC_POWER,
+ .active_low = 0,
+ .default_trigger = "none",
+ .default_state = LEDS_GPIO_DEFSTATE_OFF,
+ },
+ { /* bit 1 */
+ .name = "gpo:wifi_setup",
+ .gpio = PCF_GPIO_WIFI_SETUP,
+ .active_low = 1,
+ .default_trigger = "none",
+ .default_state = LEDS_GPIO_DEFSTATE_OFF,
+ },
+ { /* bit 2 */
+ .name = "gpo:wifi_enable",
+ .gpio = PCF_GPIO_WIFI_ENABLE,
+ .active_low = 1,
+ .default_trigger = "none",
+ .default_state = LEDS_GPIO_DEFSTATE_OFF,
+ },
+ { /* bit 3 */
+ .name = "gpo:wifi_reset",
+ .gpio = PCF_GPIO_WIFI_RESET,
+ .active_low = 1,
+ .default_trigger = "none",
+ .default_state = LEDS_GPIO_DEFSTATE_ON,
+ },
+ /* bit 4 used as GPI */
+ { /* bit 5 */
+ .name = "gpo:gps_setup",
+ .gpio = PCF_GPIO_GPS_SETUP,
+ .active_low = 1,
+ .default_trigger = "none",
+ .default_state = LEDS_GPIO_DEFSTATE_OFF,
+ },
+ { /* bit 6 */
+ .name = "gpo:gps_standby",
+ .gpio = PCF_GPIO_GPS_STANDBY,
+ .active_low = 0,
+ .default_trigger = "none",
+ .default_state = LEDS_GPIO_DEFSTATE_ON,
+ },
+ { /* bit 7 */
+ .name = "gpo:gps_power",
+ .gpio = PCF_GPIO_GPS_POWER,
+ .active_low = 0,
+ .default_trigger = "none",
+ .default_state = LEDS_GPIO_DEFSTATE_OFF,
+ }
+};
+
+static struct gpio_led_platform_data pcf_gpio_led_info1 = {
+ .leds = pcf_gpio_leds1,
+ .num_leds = ARRAY_SIZE(pcf_gpio_leds1),
+};
+
+static struct platform_device pcf_leds1 = {
+ .name = "leds-gpio", /* GS_IA18-CB_board */
+ .id = 1,
+ .dev = {
+ .platform_data = &pcf_gpio_led_info1,
+ }
+};
+
+/* PCF8574 0x22 GPIO - U1 on the GS_2G_OPT1-A_V0 board (Alarm) */
+static struct gpio_led pcf_gpio_leds2[] = {
+ { /* bit 0 */
+ .name = "gpo:alarm_1",
+ .gpio = PCF_GPIO_ALARM1,
+ .active_low = 1,
+ .default_trigger = "none",
+ .default_state = LEDS_GPIO_DEFSTATE_OFF,
+ },
+ { /* bit 1 */
+ .name = "gpo:alarm_2",
+ .gpio = PCF_GPIO_ALARM2,
+ .active_low = 1,
+ .default_trigger = "none",
+ .default_state = LEDS_GPIO_DEFSTATE_OFF,
+ },
+ { /* bit 2 */
+ .name = "gpo:alarm_3",
+ .gpio = PCF_GPIO_ALARM3,
+ .active_low = 1,
+ .default_trigger = "none",
+ .default_state = LEDS_GPIO_DEFSTATE_OFF,
+ },
+ { /* bit 3 */
+ .name = "gpo:alarm_4",
+ .gpio = PCF_GPIO_ALARM4,
+ .active_low = 1,
+ .default_trigger = "none",
+ .default_state = LEDS_GPIO_DEFSTATE_OFF,
+ },
+ /* bits 4, 5, 6 not used */
+ { /* bit 7 */
+ .name = "gpo:alarm_v_relay_on",
+ .gpio = PCF_GPIO_ALARM_V_RELAY_ON,
+ .active_low = 0,
+ .default_trigger = "none",
+ .default_state = LEDS_GPIO_DEFSTATE_OFF,
+ },
+};
+
+static struct gpio_led_platform_data pcf_gpio_led_info2 = {
+ .leds = pcf_gpio_leds2,
+ .num_leds = ARRAY_SIZE(pcf_gpio_leds2),
+};
+
+static struct platform_device pcf_leds2 = {
+ .name = "leds-gpio",
+ .id = 2,
+ .dev = {
+ .platform_data = &pcf_gpio_led_info2,
+ }
+};
+
+/* PCF8574 0x24 GPIO U1 on the GS_2G-OPT23-A_V0 board (Modem) */
+static struct gpio_led pcf_gpio_leds3[] = {
+ { /* bit 0 */
+ .name = "gpo:modem_power",
+ .gpio = PCF_GPIO_MODEM_POWER,
+ .active_low = 1,
+ .default_trigger = "none",
+ .default_state = LEDS_GPIO_DEFSTATE_OFF,
+ },
+ /* bits 1 and 2 not used */
+ { /* bit 3 */
+ .name = "gpo:modem_reset",
+ .gpio = PCF_GPIO_MODEM_RESET,
+ .active_low = 1,
+ .default_trigger = "none",
+ .default_state = LEDS_GPIO_DEFSTATE_ON,
+ },
+ /* bits 4, 5 and 6 not used */
+ { /* bit 7 */
+ .name = "gpo:trx_reset",
+ .gpio = PCF_GPIO_TRX_RESET,
+ .active_low = 1,
+ .default_trigger = "none",
+ .default_state = LEDS_GPIO_DEFSTATE_ON,
+ }
+};
+
+static struct gpio_led_platform_data pcf_gpio_led_info3 = {
+ .leds = pcf_gpio_leds3,
+ .num_leds = ARRAY_SIZE(pcf_gpio_leds3),
+};
+
+static struct platform_device pcf_leds3 = {
+ .name = "leds-gpio",
+ .id = 3,
+ .dev = {
+ .platform_data = &pcf_gpio_led_info3,
+ }
+};
+
+static void __init gsia18s_pcf_leds_init(void)
+{
+ platform_device_register(&pcf_leds1);
+ platform_device_register(&pcf_leds2);
+ platform_device_register(&pcf_leds3);
+}
+
+/*
+ * SPI busses.
+ */
+static struct spi_board_info gsia18s_spi_devices[] = {
+ { /* User accessible spi0, cs0 used for communication with MSP RTC */
+ .modalias = "spidev",
+ .bus_num = 0,
+ .chip_select = 0,
+ .max_speed_hz = 580000,
+ .mode = SPI_MODE_1,
+ },
+ { /* User accessible spi1, cs0 used for communication with int. DSP */
+ .modalias = "spidev",
+ .bus_num = 1,
+ .chip_select = 0,
+ .max_speed_hz = 5600000,
+ .mode = SPI_MODE_0,
+ },
+ { /* User accessible spi1, cs1 used for communication with ext. DSP */
+ .modalias = "spidev",
+ .bus_num = 1,
+ .chip_select = 1,
+ .max_speed_hz = 5600000,
+ .mode = SPI_MODE_0,
+ },
+ { /* User accessible spi1, cs2 used for communication with ext. DSP */
+ .modalias = "spidev",
+ .bus_num = 1,
+ .chip_select = 2,
+ .max_speed_hz = 5600000,
+ .mode = SPI_MODE_0,
+ },
+ { /* User accessible spi1, cs3 used for communication with ext. DSP */
+ .modalias = "spidev",
+ .bus_num = 1,
+ .chip_select = 3,
+ .max_speed_hz = 5600000,
+ .mode = SPI_MODE_0,
+ }
+};
+
+/*
+ * GPI Buttons
+ */
+static struct gpio_keys_button buttons[] = {
+ {
+ .gpio = GPIO_TRIG_NET_IN,
+ .code = BTN_1,
+ .desc = "TRIG_NET_IN",
+ .type = EV_KEY,
+ .active_low = 0,
+ .wakeup = 1,
+ },
+ { /* SW80 on the GS_IA18_S-MN board*/
+ .gpio = GPIO_CARD_UNMOUNT_0,
+ .code = BTN_2,
+ .desc = "Card umount 0",
+ .type = EV_KEY,
+ .active_low = 1,
+ .wakeup = 1,
+ },
+ { /* SW79 on the GS_IA18_S-MN board*/
+ .gpio = GPIO_CARD_UNMOUNT_1,
+ .code = BTN_3,
+ .desc = "Card umount 1",
+ .type = EV_KEY,
+ .active_low = 1,
+ .wakeup = 1,
+ },
+ { /* SW280 on the GS_IA18-CB board*/
+ .gpio = GPIO_KEY_POWER,
+ .code = KEY_POWER,
+ .desc = "Power Off Button",
+ .type = EV_KEY,
+ .active_low = 0,
+ .wakeup = 1,
+ }
+};
+
+static struct gpio_keys_platform_data button_data = {
+ .buttons = buttons,
+ .nbuttons = ARRAY_SIZE(buttons),
+};
+
+static struct platform_device button_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &button_data,
+ }
+};
+
+static void __init gsia18s_add_device_buttons(void)
+{
+ at91_set_gpio_input(GPIO_TRIG_NET_IN, 1);
+ at91_set_deglitch(GPIO_TRIG_NET_IN, 1);
+ at91_set_gpio_input(GPIO_CARD_UNMOUNT_0, 1);
+ at91_set_deglitch(GPIO_CARD_UNMOUNT_0, 1);
+ at91_set_gpio_input(GPIO_CARD_UNMOUNT_1, 1);
+ at91_set_deglitch(GPIO_CARD_UNMOUNT_1, 1);
+ at91_set_gpio_input(GPIO_KEY_POWER, 0);
+ at91_set_deglitch(GPIO_KEY_POWER, 1);
+
+ platform_device_register(&button_device);
+}
+
+/*
+ * I2C
+ */
+static int pcf8574x_0x20_setup(struct i2c_client *client, int gpio,
+ unsigned int ngpio, void *context)
+{
+ int status;
+
+ status = gpio_request(gpio + PCF_GPIO_ETH_DETECT, "eth_det");
+ if (status < 0) {
+ pr_err("error: can't request GPIO%d\n",
+ gpio + PCF_GPIO_ETH_DETECT);
+ return status;
+ }
+ status = gpio_direction_input(gpio + PCF_GPIO_ETH_DETECT);
+ if (status < 0) {
+ pr_err("error: can't setup GPIO%d as input\n",
+ gpio + PCF_GPIO_ETH_DETECT);
+ return status;
+ }
+ status = gpio_export(gpio + PCF_GPIO_ETH_DETECT, false);
+ if (status < 0) {
+ pr_err("error: can't export GPIO%d\n",
+ gpio + PCF_GPIO_ETH_DETECT);
+ return status;
+ }
+ status = gpio_sysfs_set_active_low(gpio + PCF_GPIO_ETH_DETECT, 1);
+ if (status < 0) {
+ pr_err("error: gpio_sysfs_set active_low(GPIO%d, 1)\n",
+ gpio + PCF_GPIO_ETH_DETECT);
+ return status;
+ }
+
+ return 0;
+}
+
+static int pcf8574x_0x20_teardown(struct i2c_client *client, int gpio,
+ unsigned ngpio, void *context)
+{
+ gpio_free(gpio + PCF_GPIO_ETH_DETECT);
+ return 0;
+}
+
+static struct pcf857x_platform_data pcf20_pdata = {
+ .gpio_base = GS_IA18_S_PCF_GPIO_BASE0,
+ .n_latch = (1 << 4),
+ .setup = pcf8574x_0x20_setup,
+ .teardown = pcf8574x_0x20_teardown,
+};
+
+static struct pcf857x_platform_data pcf22_pdata = {
+ .gpio_base = GS_IA18_S_PCF_GPIO_BASE1,
+};
+
+static struct pcf857x_platform_data pcf24_pdata = {
+ .gpio_base = GS_IA18_S_PCF_GPIO_BASE2,
+};
+
+static struct i2c_board_info __initdata gsia18s_i2c_devices[] = {
+ { /* U1 on the GS_IA18-CB_V3 board */
+ I2C_BOARD_INFO("pcf8574", 0x20),
+ .platform_data = &pcf20_pdata,
+ },
+ { /* U1 on the GS_2G_OPT1-A_V0 board (Alarm) */
+ I2C_BOARD_INFO("pcf8574", 0x22),
+ .platform_data = &pcf22_pdata,
+ },
+ { /* U1 on the GS_2G-OPT23-A_V0 board (Modem) */
+ I2C_BOARD_INFO("pcf8574", 0x24),
+ .platform_data = &pcf24_pdata,
+ },
+ { /* U161 on the GS_IA18_S-MN board */
+ I2C_BOARD_INFO("24c1024", 0x50),
+ },
+ { /* U162 on the GS_IA18_S-MN board */
+ I2C_BOARD_INFO("24c01", 0x53),
+ },
+};
+
+/*
+ * Compact Flash
+ */
+static struct at91_cf_data __initdata gsia18s_cf1_data = {
+ .irq_pin = AT91_PIN_PA27,
+ .det_pin = AT91_PIN_PB30,
+ .rst_pin = AT91_PIN_PB31,
+ .chipselect = 5,
+ .flags = AT91_CF_TRUE_IDE,
+};
+
+/* Power Off by RTC */
+static void gsia18s_power_off(void)
+{
+ pr_notice("Power supply will be switched off automatically now or after 60 seconds without ArmDAS.\n");
+ at91_set_gpio_output(AT91_PIN_PA25, 1);
+ /* Spin to death... */
+ while (1)
+ ;
+}
+
+static int __init gsia18s_power_off_init(void)
+{
+ pm_power_off = gsia18s_power_off;
+ return 0;
+}
+
+/* ---------------------------------------------------------------------------*/
+
+static void __init gsia18s_board_init(void)
+{
+ stamp9g20_board_init();
+ at91_add_device_usbh(&usbh_data);
+ at91_add_device_udc(&udc_data);
+ at91_add_device_eth(&macb_data);
+ gsia18s_leds_init();
+ gsia18s_pcf_leds_init();
+ gsia18s_add_device_buttons();
+ at91_add_device_i2c(gsia18s_i2c_devices,
+ ARRAY_SIZE(gsia18s_i2c_devices));
+ at91_add_device_cf(&gsia18s_cf1_data);
+ at91_add_device_spi(gsia18s_spi_devices,
+ ARRAY_SIZE(gsia18s_spi_devices));
+ gsia18s_power_off_init();
+}
+
+MACHINE_START(GSIA18S, "GS_IA18_S")
+ .boot_params = AT91_SDRAM_BASE + 0x100,
+ .timer = &at91sam926x_timer,
+ .map_io = gsia18s_map_io,
+ .init_irq = init_irq,
+ .init_machine = gsia18s_board_init,
+MACHINE_END
diff --git a/trunk/arch/arm/mach-at91/board-sam9m10g45ek.c b/trunk/arch/arm/mach-at91/board-sam9m10g45ek.c
index 86ff4b52db32..6c999dbd2bcf 100644
--- a/trunk/arch/arm/mach-at91/board-sam9m10g45ek.c
+++ b/trunk/arch/arm/mach-at91/board-sam9m10g45ek.c
@@ -37,7 +37,6 @@
#include
#include
-#include
#include
#include
#include
diff --git a/trunk/arch/arm/mach-at91/gpio.c b/trunk/arch/arm/mach-at91/gpio.c
index ae4772e744ac..af818a21587c 100644
--- a/trunk/arch/arm/mach-at91/gpio.c
+++ b/trunk/arch/arm/mach-at91/gpio.c
@@ -274,10 +274,10 @@ EXPORT_SYMBOL(at91_get_gpio_value);
static u32 wakeups[MAX_GPIO_BANKS];
static u32 backups[MAX_GPIO_BANKS];
-static int gpio_irq_set_wake(unsigned pin, unsigned state)
+static int gpio_irq_set_wake(struct irq_data *d, unsigned state)
{
- unsigned mask = pin_to_mask(pin);
- unsigned bank = (pin - PIN_BASE) / 32;
+ unsigned mask = pin_to_mask(d->irq);
+ unsigned bank = (d->irq - PIN_BASE) / 32;
if (unlikely(bank >= MAX_GPIO_BANKS))
return -EINVAL;
@@ -344,25 +344,25 @@ void at91_gpio_resume(void)
* IRQ0..IRQ6 should be configurable, e.g. level vs edge triggering.
*/
-static void gpio_irq_mask(unsigned pin)
+static void gpio_irq_mask(struct irq_data *d)
{
- void __iomem *pio = pin_to_controller(pin);
- unsigned mask = pin_to_mask(pin);
+ void __iomem *pio = pin_to_controller(d->irq);
+ unsigned mask = pin_to_mask(d->irq);
if (pio)
__raw_writel(mask, pio + PIO_IDR);
}
-static void gpio_irq_unmask(unsigned pin)
+static void gpio_irq_unmask(struct irq_data *d)
{
- void __iomem *pio = pin_to_controller(pin);
- unsigned mask = pin_to_mask(pin);
+ void __iomem *pio = pin_to_controller(d->irq);
+ unsigned mask = pin_to_mask(d->irq);
if (pio)
__raw_writel(mask, pio + PIO_IER);
}
-static int gpio_irq_type(unsigned pin, unsigned type)
+static int gpio_irq_type(struct irq_data *d, unsigned type)
{
switch (type) {
case IRQ_TYPE_NONE:
@@ -375,10 +375,10 @@ static int gpio_irq_type(unsigned pin, unsigned type)
static struct irq_chip gpio_irqchip = {
.name = "GPIO",
- .mask = gpio_irq_mask,
- .unmask = gpio_irq_unmask,
- .set_type = gpio_irq_type,
- .set_wake = gpio_irq_set_wake,
+ .irq_mask = gpio_irq_mask,
+ .irq_unmask = gpio_irq_unmask,
+ .irq_set_type = gpio_irq_type,
+ .irq_set_wake = gpio_irq_set_wake,
};
static void gpio_irq_handler(unsigned irq, struct irq_desc *desc)
@@ -393,7 +393,7 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc)
pio = at91_gpio->regbase;
/* temporarily mask (level sensitive) parent IRQ */
- desc->chip->ack(irq);
+ desc->irq_data.chip->irq_ack(&desc->irq_data);
for (;;) {
/* Reading ISR acks pending (edge triggered) GPIO interrupts.
* When there none are pending, we're finished unless we need
@@ -419,7 +419,7 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc)
* another IRQ must be generated before it actually gets
* here to be disabled on the GPIO controller.
*/
- gpio_irq_mask(pin);
+ gpio_irq_mask(irq_get_irq_data(pin));
}
else
generic_handle_irq(pin);
@@ -429,7 +429,7 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc)
isr >>= 1;
}
}
- desc->chip->unmask(irq);
+ desc->irq_data.chip->irq_unmask(&desc->irq_data);
/* now it may re-trigger */
}
diff --git a/trunk/arch/arm/mach-at91/include/mach/gsia18s.h b/trunk/arch/arm/mach-at91/include/mach/gsia18s.h
new file mode 100644
index 000000000000..307c194926f9
--- /dev/null
+++ b/trunk/arch/arm/mach-at91/include/mach/gsia18s.h
@@ -0,0 +1,33 @@
+/* Buttons */
+#define GPIO_TRIG_NET_IN AT91_PIN_PB21
+#define GPIO_CARD_UNMOUNT_0 AT91_PIN_PB13
+#define GPIO_CARD_UNMOUNT_1 AT91_PIN_PB12
+#define GPIO_KEY_POWER AT91_PIN_PA25
+
+/* PCF8574 0x20 GPIO - U1 on the GS_IA18-CB_V3 board */
+#define GS_IA18_S_PCF_GPIO_BASE0 NR_BUILTIN_GPIO
+#define PCF_GPIO_HDC_POWER (GS_IA18_S_PCF_GPIO_BASE0 + 0)
+#define PCF_GPIO_WIFI_SETUP (GS_IA18_S_PCF_GPIO_BASE0 + 1)
+#define PCF_GPIO_WIFI_ENABLE (GS_IA18_S_PCF_GPIO_BASE0 + 2)
+#define PCF_GPIO_WIFI_RESET (GS_IA18_S_PCF_GPIO_BASE0 + 3)
+#define PCF_GPIO_ETH_DETECT 4 /* this is a GPI */
+#define PCF_GPIO_GPS_SETUP (GS_IA18_S_PCF_GPIO_BASE0 + 5)
+#define PCF_GPIO_GPS_STANDBY (GS_IA18_S_PCF_GPIO_BASE0 + 6)
+#define PCF_GPIO_GPS_POWER (GS_IA18_S_PCF_GPIO_BASE0 + 7)
+
+/* PCF8574 0x22 GPIO - U1 on the GS_2G_OPT1-A_V0 board (Alarm) */
+#define GS_IA18_S_PCF_GPIO_BASE1 (GS_IA18_S_PCF_GPIO_BASE0 + 8)
+#define PCF_GPIO_ALARM1 (GS_IA18_S_PCF_GPIO_BASE1 + 0)
+#define PCF_GPIO_ALARM2 (GS_IA18_S_PCF_GPIO_BASE1 + 1)
+#define PCF_GPIO_ALARM3 (GS_IA18_S_PCF_GPIO_BASE1 + 2)
+#define PCF_GPIO_ALARM4 (GS_IA18_S_PCF_GPIO_BASE1 + 3)
+/* bits 4, 5, 6 not used */
+#define PCF_GPIO_ALARM_V_RELAY_ON (GS_IA18_S_PCF_GPIO_BASE1 + 7)
+
+/* PCF8574 0x24 GPIO U1 on the GS_2G-OPT23-A_V0 board (Modem) */
+#define GS_IA18_S_PCF_GPIO_BASE2 (GS_IA18_S_PCF_GPIO_BASE1 + 8)
+#define PCF_GPIO_MODEM_POWER (GS_IA18_S_PCF_GPIO_BASE2 + 0)
+#define PCF_GPIO_MODEM_RESET (GS_IA18_S_PCF_GPIO_BASE2 + 3)
+/* bits 1, 2, 4, 5 not used */
+#define PCF_GPIO_TRX_RESET (GS_IA18_S_PCF_GPIO_BASE2 + 6)
+/* bit 7 not used */
diff --git a/trunk/arch/arm/mach-at91/irq.c b/trunk/arch/arm/mach-at91/irq.c
index da3494a53423..b56d6b3a4087 100644
--- a/trunk/arch/arm/mach-at91/irq.c
+++ b/trunk/arch/arm/mach-at91/irq.c
@@ -34,23 +34,23 @@
#include
-static void at91_aic_mask_irq(unsigned int irq)
+static void at91_aic_mask_irq(struct irq_data *d)
{
/* Disable interrupt on AIC */
- at91_sys_write(AT91_AIC_IDCR, 1 << irq);
+ at91_sys_write(AT91_AIC_IDCR, 1 << d->irq);
}
-static void at91_aic_unmask_irq(unsigned int irq)
+static void at91_aic_unmask_irq(struct irq_data *d)
{
/* Enable interrupt on AIC */
- at91_sys_write(AT91_AIC_IECR, 1 << irq);
+ at91_sys_write(AT91_AIC_IECR, 1 << d->irq);
}
unsigned int at91_extern_irq;
#define is_extern_irq(irq) ((1 << (irq)) & at91_extern_irq)
-static int at91_aic_set_type(unsigned irq, unsigned type)
+static int at91_aic_set_type(struct irq_data *d, unsigned type)
{
unsigned int smr, srctype;
@@ -62,13 +62,13 @@ static int at91_aic_set_type(unsigned irq, unsigned type)
srctype = AT91_AIC_SRCTYPE_RISING;
break;
case IRQ_TYPE_LEVEL_LOW:
- if ((irq == AT91_ID_FIQ) || is_extern_irq(irq)) /* only supported on external interrupts */
+ if ((d->irq == AT91_ID_FIQ) || is_extern_irq(d->irq)) /* only supported on external interrupts */
srctype = AT91_AIC_SRCTYPE_LOW;
else
return -EINVAL;
break;
case IRQ_TYPE_EDGE_FALLING:
- if ((irq == AT91_ID_FIQ) || is_extern_irq(irq)) /* only supported on external interrupts */
+ if ((d->irq == AT91_ID_FIQ) || is_extern_irq(d->irq)) /* only supported on external interrupts */
srctype = AT91_AIC_SRCTYPE_FALLING;
else
return -EINVAL;
@@ -77,8 +77,8 @@ static int at91_aic_set_type(unsigned irq, unsigned type)
return -EINVAL;
}
- smr = at91_sys_read(AT91_AIC_SMR(irq)) & ~AT91_AIC_SRCTYPE;
- at91_sys_write(AT91_AIC_SMR(irq), smr | srctype);
+ smr = at91_sys_read(AT91_AIC_SMR(d->irq)) & ~AT91_AIC_SRCTYPE;
+ at91_sys_write(AT91_AIC_SMR(d->irq), smr | srctype);
return 0;
}
@@ -87,15 +87,15 @@ static int at91_aic_set_type(unsigned irq, unsigned type)
static u32 wakeups;
static u32 backups;
-static int at91_aic_set_wake(unsigned irq, unsigned value)
+static int at91_aic_set_wake(struct irq_data *d, unsigned value)
{
- if (unlikely(irq >= 32))
+ if (unlikely(d->irq >= 32))
return -EINVAL;
if (value)
- wakeups |= (1 << irq);
+ wakeups |= (1 << d->irq);
else
- wakeups &= ~(1 << irq);
+ wakeups &= ~(1 << d->irq);
return 0;
}
@@ -119,11 +119,11 @@ void at91_irq_resume(void)
static struct irq_chip at91_aic_chip = {
.name = "AIC",
- .ack = at91_aic_mask_irq,
- .mask = at91_aic_mask_irq,
- .unmask = at91_aic_unmask_irq,
- .set_type = at91_aic_set_type,
- .set_wake = at91_aic_set_wake,
+ .irq_ack = at91_aic_mask_irq,
+ .irq_mask = at91_aic_mask_irq,
+ .irq_unmask = at91_aic_unmask_irq,
+ .irq_set_type = at91_aic_set_type,
+ .irq_set_wake = at91_aic_set_wake,
};
/*
diff --git a/trunk/arch/arm/mach-bcmring/irq.c b/trunk/arch/arm/mach-bcmring/irq.c
index e3152631eb37..84dcda0d1d9a 100644
--- a/trunk/arch/arm/mach-bcmring/irq.c
+++ b/trunk/arch/arm/mach-bcmring/irq.c
@@ -30,61 +30,61 @@
#include
#include
-static void bcmring_mask_irq0(unsigned int irq)
+static void bcmring_mask_irq0(struct irq_data *d)
{
- writel(1 << (irq - IRQ_INTC0_START),
+ writel(1 << (d->irq - IRQ_INTC0_START),
MM_IO_BASE_INTC0 + INTCHW_INTENCLEAR);
}
-static void bcmring_unmask_irq0(unsigned int irq)
+static void bcmring_unmask_irq0(struct irq_data *d)
{
- writel(1 << (irq - IRQ_INTC0_START),
+ writel(1 << (d->irq - IRQ_INTC0_START),
MM_IO_BASE_INTC0 + INTCHW_INTENABLE);
}
-static void bcmring_mask_irq1(unsigned int irq)
+static void bcmring_mask_irq1(struct irq_data *d)
{
- writel(1 << (irq - IRQ_INTC1_START),
+ writel(1 << (d->irq - IRQ_INTC1_START),
MM_IO_BASE_INTC1 + INTCHW_INTENCLEAR);
}
-static void bcmring_unmask_irq1(unsigned int irq)
+static void bcmring_unmask_irq1(struct irq_data *d)
{
- writel(1 << (irq - IRQ_INTC1_START),
+ writel(1 << (d->irq - IRQ_INTC1_START),
MM_IO_BASE_INTC1 + INTCHW_INTENABLE);
}
-static void bcmring_mask_irq2(unsigned int irq)
+static void bcmring_mask_irq2(struct irq_data *d)
{
- writel(1 << (irq - IRQ_SINTC_START),
+ writel(1 << (d->irq - IRQ_SINTC_START),
MM_IO_BASE_SINTC + INTCHW_INTENCLEAR);
}
-static void bcmring_unmask_irq2(unsigned int irq)
+static void bcmring_unmask_irq2(struct irq_data *d)
{
- writel(1 << (irq - IRQ_SINTC_START),
+ writel(1 << (d->irq - IRQ_SINTC_START),
MM_IO_BASE_SINTC + INTCHW_INTENABLE);
}
static struct irq_chip bcmring_irq0_chip = {
.name = "ARM-INTC0",
- .ack = bcmring_mask_irq0,
- .mask = bcmring_mask_irq0, /* mask a specific interrupt, blocking its delivery. */
- .unmask = bcmring_unmask_irq0, /* unmaks an interrupt */
+ .irq_ack = bcmring_mask_irq0,
+ .irq_mask = bcmring_mask_irq0, /* mask a specific interrupt, blocking its delivery. */
+ .irq_unmask = bcmring_unmask_irq0, /* unmaks an interrupt */
};
static struct irq_chip bcmring_irq1_chip = {
.name = "ARM-INTC1",
- .ack = bcmring_mask_irq1,
- .mask = bcmring_mask_irq1,
- .unmask = bcmring_unmask_irq1,
+ .irq_ack = bcmring_mask_irq1,
+ .irq_mask = bcmring_mask_irq1,
+ .irq_unmask = bcmring_unmask_irq1,
};
static struct irq_chip bcmring_irq2_chip = {
.name = "ARM-SINTC",
- .ack = bcmring_mask_irq2,
- .mask = bcmring_mask_irq2,
- .unmask = bcmring_unmask_irq2,
+ .irq_ack = bcmring_mask_irq2,
+ .irq_mask = bcmring_mask_irq2,
+ .irq_unmask = bcmring_unmask_irq2,
};
static void vic_init(void __iomem *base, struct irq_chip *chip,
diff --git a/trunk/arch/arm/mach-clps711x/irq.c b/trunk/arch/arm/mach-clps711x/irq.c
index 9a12d8562284..86da7a1b2bbe 100644
--- a/trunk/arch/arm/mach-clps711x/irq.c
+++ b/trunk/arch/arm/mach-clps711x/irq.c
@@ -27,24 +27,24 @@
#include
-static void int1_mask(unsigned int irq)
+static void int1_mask(struct irq_data *d)
{
u32 intmr1;
intmr1 = clps_readl(INTMR1);
- intmr1 &= ~(1 << irq);
+ intmr1 &= ~(1 << d->irq);
clps_writel(intmr1, INTMR1);
}
-static void int1_ack(unsigned int irq)
+static void int1_ack(struct irq_data *d)
{
u32 intmr1;
intmr1 = clps_readl(INTMR1);
- intmr1 &= ~(1 << irq);
+ intmr1 &= ~(1 << d->irq);
clps_writel(intmr1, INTMR1);
- switch (irq) {
+ switch (d->irq) {
case IRQ_CSINT: clps_writel(0, COEOI); break;
case IRQ_TC1OI: clps_writel(0, TC1EOI); break;
case IRQ_TC2OI: clps_writel(0, TC2EOI); break;
@@ -54,56 +54,56 @@ static void int1_ack(unsigned int irq)
}
}
-static void int1_unmask(unsigned int irq)
+static void int1_unmask(struct irq_data *d)
{
u32 intmr1;
intmr1 = clps_readl(INTMR1);
- intmr1 |= 1 << irq;
+ intmr1 |= 1 << d->irq;
clps_writel(intmr1, INTMR1);
}
static struct irq_chip int1_chip = {
- .ack = int1_ack,
- .mask = int1_mask,
- .unmask = int1_unmask,
+ .irq_ack = int1_ack,
+ .irq_mask = int1_mask,
+ .irq_unmask = int1_unmask,
};
-static void int2_mask(unsigned int irq)
+static void int2_mask(struct irq_data *d)
{
u32 intmr2;
intmr2 = clps_readl(INTMR2);
- intmr2 &= ~(1 << (irq - 16));
+ intmr2 &= ~(1 << (d->irq - 16));
clps_writel(intmr2, INTMR2);
}
-static void int2_ack(unsigned int irq)
+static void int2_ack(struct irq_data *d)
{
u32 intmr2;
intmr2 = clps_readl(INTMR2);
- intmr2 &= ~(1 << (irq - 16));
+ intmr2 &= ~(1 << (d->irq - 16));
clps_writel(intmr2, INTMR2);
- switch (irq) {
+ switch (d->irq) {
case IRQ_KBDINT: clps_writel(0, KBDEOI); break;
}
}
-static void int2_unmask(unsigned int irq)
+static void int2_unmask(struct irq_data *d)
{
u32 intmr2;
intmr2 = clps_readl(INTMR2);
- intmr2 |= 1 << (irq - 16);
+ intmr2 |= 1 << (d->irq - 16);
clps_writel(intmr2, INTMR2);
}
static struct irq_chip int2_chip = {
- .ack = int2_ack,
- .mask = int2_mask,
- .unmask = int2_unmask,
+ .irq_ack = int2_ack,
+ .irq_mask = int2_mask,
+ .irq_unmask = int2_unmask,
};
void __init clps711x_init_irq(void)
diff --git a/trunk/arch/arm/mach-davinci/cp_intc.c b/trunk/arch/arm/mach-davinci/cp_intc.c
index bb4c40ecb803..9abc80a86a22 100644
--- a/trunk/arch/arm/mach-davinci/cp_intc.c
+++ b/trunk/arch/arm/mach-davinci/cp_intc.c
@@ -26,30 +26,30 @@ static inline void cp_intc_write(unsigned long value, unsigned offset)
__raw_writel(value, davinci_intc_base + offset);
}
-static void cp_intc_ack_irq(unsigned int irq)
+static void cp_intc_ack_irq(struct irq_data *d)
{
- cp_intc_write(irq, CP_INTC_SYS_STAT_IDX_CLR);
+ cp_intc_write(d->irq, CP_INTC_SYS_STAT_IDX_CLR);
}
/* Disable interrupt */
-static void cp_intc_mask_irq(unsigned int irq)
+static void cp_intc_mask_irq(struct irq_data *d)
{
/* XXX don't know why we need to disable nIRQ here... */
cp_intc_write(1, CP_INTC_HOST_ENABLE_IDX_CLR);
- cp_intc_write(irq, CP_INTC_SYS_ENABLE_IDX_CLR);
+ cp_intc_write(d->irq, CP_INTC_SYS_ENABLE_IDX_CLR);
cp_intc_write(1, CP_INTC_HOST_ENABLE_IDX_SET);
}
/* Enable interrupt */
-static void cp_intc_unmask_irq(unsigned int irq)
+static void cp_intc_unmask_irq(struct irq_data *d)
{
- cp_intc_write(irq, CP_INTC_SYS_ENABLE_IDX_SET);
+ cp_intc_write(d->irq, CP_INTC_SYS_ENABLE_IDX_SET);
}
-static int cp_intc_set_irq_type(unsigned int irq, unsigned int flow_type)
+static int cp_intc_set_irq_type(struct irq_data *d, unsigned int flow_type)
{
- unsigned reg = BIT_WORD(irq);
- unsigned mask = BIT_MASK(irq);
+ unsigned reg = BIT_WORD(d->irq);
+ unsigned mask = BIT_MASK(d->irq);
unsigned polarity = cp_intc_read(CP_INTC_SYS_POLARITY(reg));
unsigned type = cp_intc_read(CP_INTC_SYS_TYPE(reg));
@@ -85,18 +85,18 @@ static int cp_intc_set_irq_type(unsigned int irq, unsigned int flow_type)
* generic drivers which call {enable|disable}_irq_wake for
* wake up interrupt sources (eg RTC on DA850).
*/
-static int cp_intc_set_wake(unsigned int irq, unsigned int on)
+static int cp_intc_set_wake(struct irq_data *d, unsigned int on)
{
return 0;
}
static struct irq_chip cp_intc_irq_chip = {
.name = "cp_intc",
- .ack = cp_intc_ack_irq,
- .mask = cp_intc_mask_irq,
- .unmask = cp_intc_unmask_irq,
- .set_type = cp_intc_set_irq_type,
- .set_wake = cp_intc_set_wake,
+ .irq_ack = cp_intc_ack_irq,
+ .irq_mask = cp_intc_mask_irq,
+ .irq_unmask = cp_intc_unmask_irq,
+ .irq_set_type = cp_intc_set_irq_type,
+ .irq_set_wake = cp_intc_set_wake,
};
void __init cp_intc_init(void)
diff --git a/trunk/arch/arm/mach-davinci/gpio.c b/trunk/arch/arm/mach-davinci/gpio.c
index bf0ff587e46a..20d66e5e4663 100644
--- a/trunk/arch/arm/mach-davinci/gpio.c
+++ b/trunk/arch/arm/mach-davinci/gpio.c
@@ -205,20 +205,20 @@ pure_initcall(davinci_gpio_setup);
* serve as EDMA event triggers.
*/
-static void gpio_irq_disable(unsigned irq)
+static void gpio_irq_disable(struct irq_data *d)
{
- struct davinci_gpio_regs __iomem *g = irq2regs(irq);
- u32 mask = (u32) get_irq_data(irq);
+ struct davinci_gpio_regs __iomem *g = irq2regs(d->irq);
+ u32 mask = (u32) irq_data_get_irq_data(d);
__raw_writel(mask, &g->clr_falling);
__raw_writel(mask, &g->clr_rising);
}
-static void gpio_irq_enable(unsigned irq)
+static void gpio_irq_enable(struct irq_data *d)
{
- struct davinci_gpio_regs __iomem *g = irq2regs(irq);
- u32 mask = (u32) get_irq_data(irq);
- unsigned status = irq_desc[irq].status;
+ struct davinci_gpio_regs __iomem *g = irq2regs(d->irq);
+ u32 mask = (u32) irq_data_get_irq_data(d);
+ unsigned status = irq_desc[d->irq].status;
status &= IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING;
if (!status)
@@ -230,19 +230,19 @@ static void gpio_irq_enable(unsigned irq)
__raw_writel(mask, &g->set_rising);
}
-static int gpio_irq_type(unsigned irq, unsigned trigger)
+static int gpio_irq_type(struct irq_data *d, unsigned trigger)
{
- struct davinci_gpio_regs __iomem *g = irq2regs(irq);
- u32 mask = (u32) get_irq_data(irq);
+ struct davinci_gpio_regs __iomem *g = irq2regs(d->irq);
+ u32 mask = (u32) irq_data_get_irq_data(d);
if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
return -EINVAL;
- irq_desc[irq].status &= ~IRQ_TYPE_SENSE_MASK;
- irq_desc[irq].status |= trigger;
+ irq_desc[d->irq].status &= ~IRQ_TYPE_SENSE_MASK;
+ irq_desc[d->irq].status |= trigger;
/* don't enable the IRQ if it's currently disabled */
- if (irq_desc[irq].depth == 0) {
+ if (irq_desc[d->irq].depth == 0) {
__raw_writel(mask, (trigger & IRQ_TYPE_EDGE_FALLING)
? &g->set_falling : &g->clr_falling);
__raw_writel(mask, (trigger & IRQ_TYPE_EDGE_RISING)
@@ -253,9 +253,9 @@ static int gpio_irq_type(unsigned irq, unsigned trigger)
static struct irq_chip gpio_irqchip = {
.name = "GPIO",
- .enable = gpio_irq_enable,
- .disable = gpio_irq_disable,
- .set_type = gpio_irq_type,
+ .irq_enable = gpio_irq_enable,
+ .irq_disable = gpio_irq_disable,
+ .irq_set_type = gpio_irq_type,
};
static void
@@ -269,8 +269,8 @@ gpio_irq_handler(unsigned irq, struct irq_desc *desc)
mask <<= 16;
/* temporarily mask (level sensitive) parent IRQ */
- desc->chip->mask(irq);
- desc->chip->ack(irq);
+ desc->irq_data.chip->irq_mask(&desc->irq_data);
+ desc->irq_data.chip->irq_ack(&desc->irq_data);
while (1) {
u32 status;
int n;
@@ -293,7 +293,7 @@ gpio_irq_handler(unsigned irq, struct irq_desc *desc)
status >>= res;
}
}
- desc->chip->unmask(irq);
+ desc->irq_data.chip->irq_unmask(&desc->irq_data);
/* now it may re-trigger */
}
@@ -320,10 +320,10 @@ static int gpio_to_irq_unbanked(struct gpio_chip *chip, unsigned offset)
return -ENODEV;
}
-static int gpio_irq_type_unbanked(unsigned irq, unsigned trigger)
+static int gpio_irq_type_unbanked(struct irq_data *d, unsigned trigger)
{
- struct davinci_gpio_regs __iomem *g = irq2regs(irq);
- u32 mask = (u32) get_irq_data(irq);
+ struct davinci_gpio_regs __iomem *g = irq2regs(d->irq);
+ u32 mask = (u32) irq_data_get_irq_data(d);
if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
return -EINVAL;
@@ -397,7 +397,7 @@ static int __init davinci_gpio_irq_setup(void)
irq = bank_irq;
gpio_irqchip_unbanked = *get_irq_desc_chip(irq_to_desc(irq));
gpio_irqchip_unbanked.name = "GPIO-AINTC";
- gpio_irqchip_unbanked.set_type = gpio_irq_type_unbanked;
+ gpio_irqchip_unbanked.irq_set_type = gpio_irq_type_unbanked;
/* default trigger: both edges */
g = gpio2regs(0);
diff --git a/trunk/arch/arm/mach-davinci/irq.c b/trunk/arch/arm/mach-davinci/irq.c
index 784ddf3c5ad4..5e05c9b64e1f 100644
--- a/trunk/arch/arm/mach-davinci/irq.c
+++ b/trunk/arch/arm/mach-davinci/irq.c
@@ -53,14 +53,14 @@ static inline void davinci_irq_writel(unsigned long value, int offset)
}
/* Disable interrupt */
-static void davinci_mask_irq(unsigned int irq)
+static void davinci_mask_irq(struct irq_data *d)
{
unsigned int mask;
u32 l;
- mask = 1 << IRQ_BIT(irq);
+ mask = 1 << IRQ_BIT(d->irq);
- if (irq > 31) {
+ if (d->irq > 31) {
l = davinci_irq_readl(IRQ_ENT_REG1_OFFSET);
l &= ~mask;
davinci_irq_writel(l, IRQ_ENT_REG1_OFFSET);
@@ -72,14 +72,14 @@ static void davinci_mask_irq(unsigned int irq)
}
/* Enable interrupt */
-static void davinci_unmask_irq(unsigned int irq)
+static void davinci_unmask_irq(struct irq_data *d)
{
unsigned int mask;
u32 l;
- mask = 1 << IRQ_BIT(irq);
+ mask = 1 << IRQ_BIT(d->irq);
- if (irq > 31) {
+ if (d->irq > 31) {
l = davinci_irq_readl(IRQ_ENT_REG1_OFFSET);
l |= mask;
davinci_irq_writel(l, IRQ_ENT_REG1_OFFSET);
@@ -91,23 +91,23 @@ static void davinci_unmask_irq(unsigned int irq)
}
/* EOI interrupt */
-static void davinci_ack_irq(unsigned int irq)
+static void davinci_ack_irq(struct irq_data *d)
{
unsigned int mask;
- mask = 1 << IRQ_BIT(irq);
+ mask = 1 << IRQ_BIT(d->irq);
- if (irq > 31)
+ if (d->irq > 31)
davinci_irq_writel(mask, IRQ_REG1_OFFSET);
else
davinci_irq_writel(mask, IRQ_REG0_OFFSET);
}
static struct irq_chip davinci_irq_chip_0 = {
- .name = "AINTC",
- .ack = davinci_ack_irq,
- .mask = davinci_mask_irq,
- .unmask = davinci_unmask_irq,
+ .name = "AINTC",
+ .irq_ack = davinci_ack_irq,
+ .irq_mask = davinci_mask_irq,
+ .irq_unmask = davinci_unmask_irq,
};
/* ARM Interrupt Controller Initialization */
diff --git a/trunk/arch/arm/mach-dove/irq.c b/trunk/arch/arm/mach-dove/irq.c
index 61bfcb3b08c2..9317f0558b57 100644
--- a/trunk/arch/arm/mach-dove/irq.c
+++ b/trunk/arch/arm/mach-dove/irq.c
@@ -36,9 +36,9 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
}
}
-static void pmu_irq_mask(unsigned int irq)
+static void pmu_irq_mask(struct irq_data *d)
{
- int pin = irq_to_pmu(irq);
+ int pin = irq_to_pmu(d->irq);
u32 u;
u = readl(PMU_INTERRUPT_MASK);
@@ -46,9 +46,9 @@ static void pmu_irq_mask(unsigned int irq)
writel(u, PMU_INTERRUPT_MASK);
}
-static void pmu_irq_unmask(unsigned int irq)
+static void pmu_irq_unmask(struct irq_data *d)
{
- int pin = irq_to_pmu(irq);
+ int pin = irq_to_pmu(d->irq);
u32 u;
u = readl(PMU_INTERRUPT_MASK);
@@ -56,9 +56,9 @@ static void pmu_irq_unmask(unsigned int irq)
writel(u, PMU_INTERRUPT_MASK);
}
-static void pmu_irq_ack(unsigned int irq)
+static void pmu_irq_ack(struct irq_data *d)
{
- int pin = irq_to_pmu(irq);
+ int pin = irq_to_pmu(d->irq);
u32 u;
u = ~(1 << (pin & 31));
@@ -67,9 +67,9 @@ static void pmu_irq_ack(unsigned int irq)
static struct irq_chip pmu_irq_chip = {
.name = "pmu_irq",
- .mask = pmu_irq_mask,
- .unmask = pmu_irq_unmask,
- .ack = pmu_irq_ack,
+ .irq_mask = pmu_irq_mask,
+ .irq_unmask = pmu_irq_unmask,
+ .irq_ack = pmu_irq_ack,
};
static void pmu_irq_handler(unsigned int irq, struct irq_desc *desc)
diff --git a/trunk/arch/arm/mach-ebsa110/core.c b/trunk/arch/arm/mach-ebsa110/core.c
index 5df4099fc14f..7df083f37fa7 100644
--- a/trunk/arch/arm/mach-ebsa110/core.c
+++ b/trunk/arch/arm/mach-ebsa110/core.c
@@ -35,20 +35,20 @@
#define IRQ_STAT 0xff000000 /* read */
#define IRQ_MCLR 0xff000000 /* write */
-static void ebsa110_mask_irq(unsigned int irq)
+static void ebsa110_mask_irq(struct irq_data *d)
{
- __raw_writeb(1 << irq, IRQ_MCLR);
+ __raw_writeb(1 << d->irq, IRQ_MCLR);
}
-static void ebsa110_unmask_irq(unsigned int irq)
+static void ebsa110_unmask_irq(struct irq_data *d)
{
- __raw_writeb(1 << irq, IRQ_MSET);
+ __raw_writeb(1 << d->irq, IRQ_MSET);
}
static struct irq_chip ebsa110_irq_chip = {
- .ack = ebsa110_mask_irq,
- .mask = ebsa110_mask_irq,
- .unmask = ebsa110_unmask_irq,
+ .irq_ack = ebsa110_mask_irq,
+ .irq_mask = ebsa110_mask_irq,
+ .irq_unmask = ebsa110_unmask_irq,
};
static void __init ebsa110_init_irq(void)
diff --git a/trunk/arch/arm/mach-ep93xx/gpio.c b/trunk/arch/arm/mach-ep93xx/gpio.c
index cf547ad7ebd4..f3dc76fdcea8 100644
--- a/trunk/arch/arm/mach-ep93xx/gpio.c
+++ b/trunk/arch/arm/mach-ep93xx/gpio.c
@@ -112,13 +112,13 @@ static void ep93xx_gpio_f_irq_handler(unsigned int irq, struct irq_desc *desc)
generic_handle_irq(gpio_irq);
}
-static void ep93xx_gpio_irq_ack(unsigned int irq)
+static void ep93xx_gpio_irq_ack(struct irq_data *d)
{
- int line = irq_to_gpio(irq);
+ int line = irq_to_gpio(d->irq);
int port = line >> 3;
int port_mask = 1 << (line & 7);
- if ((irq_desc[irq].status & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) {
+ if ((irq_desc[d->irq].status & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) {
gpio_int_type2[port] ^= port_mask; /* switch edge direction */
ep93xx_gpio_update_int_params(port);
}
@@ -126,13 +126,13 @@ static void ep93xx_gpio_irq_ack(unsigned int irq)
__raw_writeb(port_mask, EP93XX_GPIO_REG(eoi_register_offset[port]));
}
-static void ep93xx_gpio_irq_mask_ack(unsigned int irq)
+static void ep93xx_gpio_irq_mask_ack(struct irq_data *d)
{
- int line = irq_to_gpio(irq);
+ int line = irq_to_gpio(d->irq);
int port = line >> 3;
int port_mask = 1 << (line & 7);
- if ((irq_desc[irq].status & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH)
+ if ((irq_desc[d->irq].status & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH)
gpio_int_type2[port] ^= port_mask; /* switch edge direction */
gpio_int_unmasked[port] &= ~port_mask;
@@ -141,18 +141,18 @@ static void ep93xx_gpio_irq_mask_ack(unsigned int irq)
__raw_writeb(port_mask, EP93XX_GPIO_REG(eoi_register_offset[port]));
}
-static void ep93xx_gpio_irq_mask(unsigned int irq)
+static void ep93xx_gpio_irq_mask(struct irq_data *d)
{
- int line = irq_to_gpio(irq);
+ int line = irq_to_gpio(d->irq);
int port = line >> 3;
gpio_int_unmasked[port] &= ~(1 << (line & 7));
ep93xx_gpio_update_int_params(port);
}
-static void ep93xx_gpio_irq_unmask(unsigned int irq)
+static void ep93xx_gpio_irq_unmask(struct irq_data *d)
{
- int line = irq_to_gpio(irq);
+ int line = irq_to_gpio(d->irq);
int port = line >> 3;
gpio_int_unmasked[port] |= 1 << (line & 7);
@@ -164,10 +164,10 @@ static void ep93xx_gpio_irq_unmask(unsigned int irq)
* edge (1) triggered, while gpio_int_type2 controls whether it
* triggers on low/falling (0) or high/rising (1).
*/
-static int ep93xx_gpio_irq_type(unsigned int irq, unsigned int type)
+static int ep93xx_gpio_irq_type(struct irq_data *d, unsigned int type)
{
- struct irq_desc *desc = irq_desc + irq;
- const int gpio = irq_to_gpio(irq);
+ struct irq_desc *desc = irq_desc + d->irq;
+ const int gpio = irq_to_gpio(d->irq);
const int port = gpio >> 3;
const int port_mask = 1 << (gpio & 7);
@@ -220,11 +220,11 @@ static int ep93xx_gpio_irq_type(unsigned int irq, unsigned int type)
static struct irq_chip ep93xx_gpio_irq_chip = {
.name = "GPIO",
- .ack = ep93xx_gpio_irq_ack,
- .mask_ack = ep93xx_gpio_irq_mask_ack,
- .mask = ep93xx_gpio_irq_mask,
- .unmask = ep93xx_gpio_irq_unmask,
- .set_type = ep93xx_gpio_irq_type,
+ .irq_ack = ep93xx_gpio_irq_ack,
+ .irq_mask_ack = ep93xx_gpio_irq_mask_ack,
+ .irq_mask = ep93xx_gpio_irq_mask,
+ .irq_unmask = ep93xx_gpio_irq_unmask,
+ .irq_set_type = ep93xx_gpio_irq_type,
};
void __init ep93xx_gpio_init_irq(void)
diff --git a/trunk/arch/arm/mach-footbridge/common.c b/trunk/arch/arm/mach-footbridge/common.c
index 88b3dd89be89..84c5f258f2d8 100644
--- a/trunk/arch/arm/mach-footbridge/common.c
+++ b/trunk/arch/arm/mach-footbridge/common.c
@@ -75,20 +75,20 @@ static const int fb_irq_mask[] = {
IRQ_MASK_PCI_PERR, /* 19 */
};
-static void fb_mask_irq(unsigned int irq)
+static void fb_mask_irq(struct irq_data *d)
{
- *CSR_IRQ_DISABLE = fb_irq_mask[_DC21285_INR(irq)];
+ *CSR_IRQ_DISABLE = fb_irq_mask[_DC21285_INR(d->irq)];
}
-static void fb_unmask_irq(unsigned int irq)
+static void fb_unmask_irq(struct irq_data *d)
{
- *CSR_IRQ_ENABLE = fb_irq_mask[_DC21285_INR(irq)];
+ *CSR_IRQ_ENABLE = fb_irq_mask[_DC21285_INR(d->irq)];
}
static struct irq_chip fb_chip = {
- .ack = fb_mask_irq,
- .mask = fb_mask_irq,
- .unmask = fb_unmask_irq,
+ .irq_ack = fb_mask_irq,
+ .irq_mask = fb_mask_irq,
+ .irq_unmask = fb_unmask_irq,
};
static void __init __fb_init_irq(void)
diff --git a/trunk/arch/arm/mach-footbridge/isa-irq.c b/trunk/arch/arm/mach-footbridge/isa-irq.c
index 8bfd06aeb64d..de7a5cb5dbe1 100644
--- a/trunk/arch/arm/mach-footbridge/isa-irq.c
+++ b/trunk/arch/arm/mach-footbridge/isa-irq.c
@@ -30,61 +30,61 @@
#include "common.h"
-static void isa_mask_pic_lo_irq(unsigned int irq)
+static void isa_mask_pic_lo_irq(struct irq_data *d)
{
- unsigned int mask = 1 << (irq & 7);
+ unsigned int mask = 1 << (d->irq & 7);
outb(inb(PIC_MASK_LO) | mask, PIC_MASK_LO);
}
-static void isa_ack_pic_lo_irq(unsigned int irq)
+static void isa_ack_pic_lo_irq(struct irq_data *d)
{
- unsigned int mask = 1 << (irq & 7);
+ unsigned int mask = 1 << (d->irq & 7);
outb(inb(PIC_MASK_LO) | mask, PIC_MASK_LO);
outb(0x20, PIC_LO);
}
-static void isa_unmask_pic_lo_irq(unsigned int irq)
+static void isa_unmask_pic_lo_irq(struct irq_data *d)
{
- unsigned int mask = 1 << (irq & 7);
+ unsigned int mask = 1 << (d->irq & 7);
outb(inb(PIC_MASK_LO) & ~mask, PIC_MASK_LO);
}
static struct irq_chip isa_lo_chip = {
- .ack = isa_ack_pic_lo_irq,
- .mask = isa_mask_pic_lo_irq,
- .unmask = isa_unmask_pic_lo_irq,
+ .irq_ack = isa_ack_pic_lo_irq,
+ .irq_mask = isa_mask_pic_lo_irq,
+ .irq_unmask = isa_unmask_pic_lo_irq,
};
-static void isa_mask_pic_hi_irq(unsigned int irq)
+static void isa_mask_pic_hi_irq(struct irq_data *d)
{
- unsigned int mask = 1 << (irq & 7);
+ unsigned int mask = 1 << (d->irq & 7);
outb(inb(PIC_MASK_HI) | mask, PIC_MASK_HI);
}
-static void isa_ack_pic_hi_irq(unsigned int irq)
+static void isa_ack_pic_hi_irq(struct irq_data *d)
{
- unsigned int mask = 1 << (irq & 7);
+ unsigned int mask = 1 << (d->irq & 7);
outb(inb(PIC_MASK_HI) | mask, PIC_MASK_HI);
outb(0x62, PIC_LO);
outb(0x20, PIC_HI);
}
-static void isa_unmask_pic_hi_irq(unsigned int irq)
+static void isa_unmask_pic_hi_irq(struct irq_data *d)
{
- unsigned int mask = 1 << (irq & 7);
+ unsigned int mask = 1 << (d->irq & 7);
outb(inb(PIC_MASK_HI) & ~mask, PIC_MASK_HI);
}
static struct irq_chip isa_hi_chip = {
- .ack = isa_ack_pic_hi_irq,
- .mask = isa_mask_pic_hi_irq,
- .unmask = isa_unmask_pic_hi_irq,
+ .irq_ack = isa_ack_pic_hi_irq,
+ .irq_mask = isa_mask_pic_hi_irq,
+ .irq_unmask = isa_unmask_pic_hi_irq,
};
static void
diff --git a/trunk/arch/arm/mach-gemini/gpio.c b/trunk/arch/arm/mach-gemini/gpio.c
index fe3bd5ac8b10..fa3d333f21e1 100644
--- a/trunk/arch/arm/mach-gemini/gpio.c
+++ b/trunk/arch/arm/mach-gemini/gpio.c
@@ -54,33 +54,33 @@ static void _set_gpio_irqenable(unsigned int base, unsigned int index,
__raw_writel(reg, base + GPIO_INT_EN);
}
-static void gpio_ack_irq(unsigned int irq)
+static void gpio_ack_irq(struct irq_data *d)
{
- unsigned int gpio = irq_to_gpio(irq);
+ unsigned int gpio = irq_to_gpio(d->irq);
unsigned int base = GPIO_BASE(gpio / 32);
__raw_writel(1 << (gpio % 32), base + GPIO_INT_CLR);
}
-static void gpio_mask_irq(unsigned int irq)
+static void gpio_mask_irq(struct irq_data *d)
{
- unsigned int gpio = irq_to_gpio(irq);
+ unsigned int gpio = irq_to_gpio(d->irq);
unsigned int base = GPIO_BASE(gpio / 32);
_set_gpio_irqenable(base, gpio % 32, 0);
}
-static void gpio_unmask_irq(unsigned int irq)
+static void gpio_unmask_irq(struct irq_data *d)
{
- unsigned int gpio = irq_to_gpio(irq);
+ unsigned int gpio = irq_to_gpio(d->irq);
unsigned int base = GPIO_BASE(gpio / 32);
_set_gpio_irqenable(base, gpio % 32, 1);
}
-static int gpio_set_irq_type(unsigned int irq, unsigned int type)
+static int gpio_set_irq_type(struct irq_data *d, unsigned int type)
{
- unsigned int gpio = irq_to_gpio(irq);
+ unsigned int gpio = irq_to_gpio(d->irq);
unsigned int gpio_mask = 1 << (gpio % 32);
unsigned int base = GPIO_BASE(gpio / 32);
unsigned int reg_both, reg_level, reg_type;
@@ -120,7 +120,7 @@ static int gpio_set_irq_type(unsigned int irq, unsigned int type)
__raw_writel(reg_level, base + GPIO_INT_LEVEL);
__raw_writel(reg_both, base + GPIO_INT_BOTH_EDGE);
- gpio_ack_irq(irq);
+ gpio_ack_irq(d->irq);
return 0;
}
@@ -146,10 +146,10 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
static struct irq_chip gpio_irq_chip = {
.name = "GPIO",
- .ack = gpio_ack_irq,
- .mask = gpio_mask_irq,
- .unmask = gpio_unmask_irq,
- .set_type = gpio_set_irq_type,
+ .irq_ack = gpio_ack_irq,
+ .irq_mask = gpio_mask_irq,
+ .irq_unmask = gpio_unmask_irq,
+ .irq_set_type = gpio_set_irq_type,
};
static void _set_gpio_direction(struct gpio_chip *chip, unsigned offset,
diff --git a/trunk/arch/arm/mach-gemini/irq.c b/trunk/arch/arm/mach-gemini/irq.c
index 9e613ca8120d..96bc227dd849 100644
--- a/trunk/arch/arm/mach-gemini/irq.c
+++ b/trunk/arch/arm/mach-gemini/irq.c
@@ -32,34 +32,34 @@
#define FIQ_LEVEL(base_addr) (base_addr + 0x30)
#define FIQ_STATUS(base_addr) (base_addr + 0x34)
-static void gemini_ack_irq(unsigned int irq)
+static void gemini_ack_irq(struct irq_data *d)
{
- __raw_writel(1 << irq, IRQ_CLEAR(IO_ADDRESS(GEMINI_INTERRUPT_BASE)));
+ __raw_writel(1 << d->irq, IRQ_CLEAR(IO_ADDRESS(GEMINI_INTERRUPT_BASE)));
}
-static void gemini_mask_irq(unsigned int irq)
+static void gemini_mask_irq(struct irq_data *d)
{
unsigned int mask;
mask = __raw_readl(IRQ_MASK(IO_ADDRESS(GEMINI_INTERRUPT_BASE)));
- mask &= ~(1 << irq);
+ mask &= ~(1 << d->irq);
__raw_writel(mask, IRQ_MASK(IO_ADDRESS(GEMINI_INTERRUPT_BASE)));
}
-static void gemini_unmask_irq(unsigned int irq)
+static void gemini_unmask_irq(struct irq_data *d)
{
unsigned int mask;
mask = __raw_readl(IRQ_MASK(IO_ADDRESS(GEMINI_INTERRUPT_BASE)));
- mask |= (1 << irq);
+ mask |= (1 << d->irq);
__raw_writel(mask, IRQ_MASK(IO_ADDRESS(GEMINI_INTERRUPT_BASE)));
}
static struct irq_chip gemini_irq_chip = {
- .name = "INTC",
- .ack = gemini_ack_irq,
- .mask = gemini_mask_irq,
- .unmask = gemini_unmask_irq,
+ .name = "INTC",
+ .irq_ack = gemini_ack_irq,
+ .irq_mask = gemini_mask_irq,
+ .irq_unmask = gemini_unmask_irq,
};
static struct resource irq_resource = {
diff --git a/trunk/arch/arm/mach-h720x/common.c b/trunk/arch/arm/mach-h720x/common.c
index bdb3f6706801..1f28c90932c7 100644
--- a/trunk/arch/arm/mach-h720x/common.c
+++ b/trunk/arch/arm/mach-h720x/common.c
@@ -52,17 +52,17 @@ unsigned long h720x_gettimeoffset(void)
/*
* mask Global irq's
*/
-static void mask_global_irq (unsigned int irq )
+static void mask_global_irq(struct irq_data *d)
{
- CPU_REG (IRQC_VIRT, IRQC_IER) &= ~(1 << irq);
+ CPU_REG (IRQC_VIRT, IRQC_IER) &= ~(1 << d->irq);
}
/*
* unmask Global irq's
*/
-static void unmask_global_irq (unsigned int irq )
+static void unmask_global_irq(struct irq_data *d)
{
- CPU_REG (IRQC_VIRT, IRQC_IER) |= (1 << irq);
+ CPU_REG (IRQC_VIRT, IRQC_IER) |= (1 << d->irq);
}
@@ -70,10 +70,10 @@ static void unmask_global_irq (unsigned int irq )
* ack GPIO irq's
* Ack only for edge triggered int's valid
*/
-static void inline ack_gpio_irq(u32 irq)
+static void inline ack_gpio_irq(struct irq_data *d)
{
- u32 reg_base = GPIO_VIRT(IRQ_TO_REGNO(irq));
- u32 bit = IRQ_TO_BIT(irq);
+ u32 reg_base = GPIO_VIRT(IRQ_TO_REGNO(d->irq));
+ u32 bit = IRQ_TO_BIT(d->irq);
if ( (CPU_REG (reg_base, GPIO_EDGE) & bit))
CPU_REG (reg_base, GPIO_CLR) = bit;
}
@@ -81,20 +81,20 @@ static void inline ack_gpio_irq(u32 irq)
/*
* mask GPIO irq's
*/
-static void inline mask_gpio_irq(u32 irq)
+static void inline mask_gpio_irq(struct irq_data *d)
{
- u32 reg_base = GPIO_VIRT(IRQ_TO_REGNO(irq));
- u32 bit = IRQ_TO_BIT(irq);
+ u32 reg_base = GPIO_VIRT(IRQ_TO_REGNO(d->irq));
+ u32 bit = IRQ_TO_BIT(d->irq);
CPU_REG (reg_base, GPIO_MASK) &= ~bit;
}
/*
* unmask GPIO irq's
*/
-static void inline unmask_gpio_irq(u32 irq)
+static void inline unmask_gpio_irq(struct irq_data *d)
{
- u32 reg_base = GPIO_VIRT(IRQ_TO_REGNO(irq));
- u32 bit = IRQ_TO_BIT(irq);
+ u32 reg_base = GPIO_VIRT(IRQ_TO_REGNO(d->irq));
+ u32 bit = IRQ_TO_BIT(d->irq);
CPU_REG (reg_base, GPIO_MASK) |= bit;
}
@@ -170,15 +170,15 @@ h720x_gpioe_demux_handler(unsigned int irq_unused, struct irq_desc *desc)
#endif
static struct irq_chip h720x_global_chip = {
- .ack = mask_global_irq,
- .mask = mask_global_irq,
- .unmask = unmask_global_irq,
+ .irq_ack = mask_global_irq,
+ .irq_mask = mask_global_irq,
+ .irq_unmask = unmask_global_irq,
};
static struct irq_chip h720x_gpio_chip = {
- .ack = ack_gpio_irq,
- .mask = mask_gpio_irq,
- .unmask = unmask_gpio_irq,
+ .irq_ack = ack_gpio_irq,
+ .irq_mask = mask_gpio_irq,
+ .irq_unmask = unmask_gpio_irq,
};
/*
diff --git a/trunk/arch/arm/mach-h720x/cpu-h7202.c b/trunk/arch/arm/mach-h720x/cpu-h7202.c
index fd33a19c813a..ac3f91442376 100644
--- a/trunk/arch/arm/mach-h720x/cpu-h7202.c
+++ b/trunk/arch/arm/mach-h720x/cpu-h7202.c
@@ -141,27 +141,27 @@ h7202_timer_interrupt(int irq, void *dev_id)
/*
* mask multiplexed timer IRQs
*/
-static void inline mask_timerx_irq (u32 irq)
+static void inline mask_timerx_irq(struct irq_data *d)
{
unsigned int bit;
- bit = 2 << ((irq == IRQ_TIMER64B) ? 4 : (irq - IRQ_TIMER1));
+ bit = 2 << ((d->irq == IRQ_TIMER64B) ? 4 : (d->irq - IRQ_TIMER1));
CPU_REG (TIMER_VIRT, TIMER_TOPCTRL) &= ~bit;
}
/*
* unmask multiplexed timer IRQs
*/
-static void inline unmask_timerx_irq (u32 irq)
+static void inline unmask_timerx_irq(struct irq_data *d)
{
unsigned int bit;
- bit = 2 << ((irq == IRQ_TIMER64B) ? 4 : (irq - IRQ_TIMER1));
+ bit = 2 << ((d->irq == IRQ_TIMER64B) ? 4 : (d->irq - IRQ_TIMER1));
CPU_REG (TIMER_VIRT, TIMER_TOPCTRL) |= bit;
}
static struct irq_chip h7202_timerx_chip = {
- .ack = mask_timerx_irq,
- .mask = mask_timerx_irq,
- .unmask = unmask_timerx_irq,
+ .irq_ack = mask_timerx_irq,
+ .irq_mask = mask_timerx_irq,
+ .irq_unmask = unmask_timerx_irq,
};
static struct irqaction h7202_timer_irq = {
diff --git a/trunk/arch/arm/mach-h720x/h7201-eval.c b/trunk/arch/arm/mach-h720x/h7201-eval.c
index 79f0b896e446..629454d71c8d 100644
--- a/trunk/arch/arm/mach-h720x/h7201-eval.c
+++ b/trunk/arch/arm/mach-h720x/h7201-eval.c
@@ -23,7 +23,6 @@
#include
#include
#include