aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/crypto
diff options
context:
space:
mode:
authorMartin Schwidefsky <schwidefsky@de.ibm.com>2013-06-24 04:30:41 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2013-06-26 15:10:28 -0400
commitf4eae94f71372ea5ec1ba17a85f3aebedc516ca8 (patch)
treeec3d6a527bf276a92e8befd559d9a0f0866ab7bd /drivers/s390/crypto
parent386aa051fb4b6298c23996e68b7c92f186e484b6 (diff)
s390/airq: simplify adapter interrupt code
There are three users of adapter interrupts: AP, QDIO and PCI. Each registers a single adapter interrupt with independent ISCs. Define a "struct airq" with the interrupt handler, a pointer and a mask for the local summary indicator and the ISC for the adapter interrupt source. Convert the indicator array with its fixed number of adapter interrupt sources per ISE to an array of hlists. This removes the limitation to 32 adapter interrupts per ISC and allows for arbitrary memory locations for the local summary indicator. Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/crypto')
-rw-r--r--drivers/s390/crypto/ap_bus.c60
1 files changed, 35 insertions, 25 deletions
diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c
index 0b116a49ee53..f446a7705c3b 100644
--- a/drivers/s390/crypto/ap_bus.c
+++ b/drivers/s390/crypto/ap_bus.c
@@ -58,7 +58,7 @@ static inline void ap_schedule_poll_timer(void);
58static int __ap_poll_device(struct ap_device *ap_dev, unsigned long *flags); 58static int __ap_poll_device(struct ap_device *ap_dev, unsigned long *flags);
59static int ap_device_remove(struct device *dev); 59static int ap_device_remove(struct device *dev);
60static int ap_device_probe(struct device *dev); 60static int ap_device_probe(struct device *dev);
61static void ap_interrupt_handler(void *unused1, void *unused2); 61static void ap_interrupt_handler(struct airq_struct *airq);
62static void ap_reset(struct ap_device *ap_dev); 62static void ap_reset(struct ap_device *ap_dev);
63static void ap_config_timeout(unsigned long ptr); 63static void ap_config_timeout(unsigned long ptr);
64static int ap_select_domain(void); 64static int ap_select_domain(void);
@@ -106,7 +106,6 @@ static DECLARE_WAIT_QUEUE_HEAD(ap_poll_wait);
106static struct task_struct *ap_poll_kthread = NULL; 106static struct task_struct *ap_poll_kthread = NULL;
107static DEFINE_MUTEX(ap_poll_thread_mutex); 107static DEFINE_MUTEX(ap_poll_thread_mutex);
108static DEFINE_SPINLOCK(ap_poll_timer_lock); 108static DEFINE_SPINLOCK(ap_poll_timer_lock);
109static void *ap_interrupt_indicator;
110static struct hrtimer ap_poll_timer; 109static struct hrtimer ap_poll_timer;
111/* In LPAR poll with 4kHz frequency. Poll every 250000 nanoseconds. 110/* In LPAR poll with 4kHz frequency. Poll every 250000 nanoseconds.
112 * If z/VM change to 1500000 nanoseconds to adjust to z/VM polling.*/ 111 * If z/VM change to 1500000 nanoseconds to adjust to z/VM polling.*/
@@ -120,13 +119,21 @@ static int ap_suspend_flag;
120static int user_set_domain = 0; 119static int user_set_domain = 0;
121static struct bus_type ap_bus_type; 120static struct bus_type ap_bus_type;
122 121
122/* Adapter interrupt definitions */
123static int ap_airq_flag;
124
125static struct airq_struct ap_airq = {
126 .handler = ap_interrupt_handler,
127 .isc = AP_ISC,
128};
129
123/** 130/**
124 * ap_using_interrupts() - Returns non-zero if interrupt support is 131 * ap_using_interrupts() - Returns non-zero if interrupt support is
125 * available. 132 * available.
126 */ 133 */
127static inline int ap_using_interrupts(void) 134static inline int ap_using_interrupts(void)
128{ 135{
129 return ap_interrupt_indicator != NULL; 136 return ap_airq_flag;
130} 137}
131 138
132/** 139/**
@@ -588,7 +595,7 @@ static int ap_init_queue(ap_qid_t qid)
588 } 595 }
589 } 596 }
590 if (rc == 0 && ap_using_interrupts()) { 597 if (rc == 0 && ap_using_interrupts()) {
591 rc = ap_queue_enable_interruption(qid, ap_interrupt_indicator); 598 rc = ap_queue_enable_interruption(qid, ap_airq.lsi_ptr);
592 /* If interruption mode is supported by the machine, 599 /* If interruption mode is supported by the machine,
593 * but an AP can not be enabled for interruption then 600 * but an AP can not be enabled for interruption then
594 * the AP will be discarded. */ 601 * the AP will be discarded. */
@@ -821,13 +828,22 @@ static int ap_bus_suspend(struct device *dev, pm_message_t state)
821 828
822static int ap_bus_resume(struct device *dev) 829static int ap_bus_resume(struct device *dev)
823{ 830{
824 int rc = 0;
825 struct ap_device *ap_dev = to_ap_dev(dev); 831 struct ap_device *ap_dev = to_ap_dev(dev);
832 int rc;
826 833
827 if (ap_suspend_flag) { 834 if (ap_suspend_flag) {
828 ap_suspend_flag = 0; 835 ap_suspend_flag = 0;
829 if (!ap_interrupts_available()) 836 if (ap_interrupts_available()) {
830 ap_interrupt_indicator = NULL; 837 if (!ap_using_interrupts()) {
838 rc = register_adapter_interrupt(&ap_airq);
839 ap_airq_flag = (rc == 0);
840 }
841 } else {
842 if (ap_using_interrupts()) {
843 unregister_adapter_interrupt(&ap_airq);
844 ap_airq_flag = 0;
845 }
846 }
831 ap_query_configuration(); 847 ap_query_configuration();
832 if (!user_set_domain) { 848 if (!user_set_domain) {
833 ap_domain_index = -1; 849 ap_domain_index = -1;
@@ -848,7 +864,10 @@ static int ap_bus_resume(struct device *dev)
848 tasklet_schedule(&ap_tasklet); 864 tasklet_schedule(&ap_tasklet);
849 if (ap_thread_flag) 865 if (ap_thread_flag)
850 rc = ap_poll_thread_start(); 866 rc = ap_poll_thread_start();
851 } 867 else
868 rc = 0;
869 } else
870 rc = 0;
852 if (AP_QID_QUEUE(ap_dev->qid) != ap_domain_index) { 871 if (AP_QID_QUEUE(ap_dev->qid) != ap_domain_index) {
853 spin_lock_bh(&ap_dev->lock); 872 spin_lock_bh(&ap_dev->lock);
854 ap_dev->qid = AP_MKQID(AP_QID_DEVICE(ap_dev->qid), 873 ap_dev->qid = AP_MKQID(AP_QID_DEVICE(ap_dev->qid),
@@ -1266,7 +1285,7 @@ out:
1266 return rc; 1285 return rc;
1267} 1286}
1268 1287
1269static void ap_interrupt_handler(void *unused1, void *unused2) 1288static void ap_interrupt_handler(struct airq_struct *airq)
1270{ 1289{
1271 inc_irq_stat(IRQIO_APB); 1290 inc_irq_stat(IRQIO_APB);
1272 tasklet_schedule(&ap_tasklet); 1291 tasklet_schedule(&ap_tasklet);
@@ -1722,7 +1741,7 @@ static void ap_poll_all(unsigned long dummy)
1722 * important that no requests on any AP get lost. 1741 * important that no requests on any AP get lost.
1723 */ 1742 */
1724 if (ap_using_interrupts()) 1743 if (ap_using_interrupts())
1725 xchg((u8 *)ap_interrupt_indicator, 0); 1744 xchg(ap_airq.lsi_ptr, 0);
1726 do { 1745 do {
1727 flags = 0; 1746 flags = 0;
1728 spin_lock(&ap_device_list_lock); 1747 spin_lock(&ap_device_list_lock);
@@ -1881,13 +1900,8 @@ int __init ap_module_init(void)
1881 return -ENODEV; 1900 return -ENODEV;
1882 } 1901 }
1883 if (ap_interrupts_available()) { 1902 if (ap_interrupts_available()) {
1884 isc_register(AP_ISC); 1903 rc = register_adapter_interrupt(&ap_airq);
1885 ap_interrupt_indicator = s390_register_adapter_interrupt( 1904 ap_airq_flag = (rc == 0);
1886 &ap_interrupt_handler, NULL, AP_ISC);
1887 if (IS_ERR(ap_interrupt_indicator)) {
1888 ap_interrupt_indicator = NULL;
1889 isc_unregister(AP_ISC);
1890 }
1891 } 1905 }
1892 1906
1893 register_reset_call(&ap_reset_call); 1907 register_reset_call(&ap_reset_call);
@@ -1955,10 +1969,8 @@ out_bus:
1955 bus_unregister(&ap_bus_type); 1969 bus_unregister(&ap_bus_type);
1956out: 1970out:
1957 unregister_reset_call(&ap_reset_call); 1971 unregister_reset_call(&ap_reset_call);
1958 if (ap_using_interrupts()) { 1972 if (ap_using_interrupts())
1959 s390_unregister_adapter_interrupt(ap_interrupt_indicator, AP_ISC); 1973 unregister_adapter_interrupt(&ap_airq);
1960 isc_unregister(AP_ISC);
1961 }
1962 return rc; 1974 return rc;
1963} 1975}
1964 1976
@@ -1994,10 +2006,8 @@ void ap_module_exit(void)
1994 bus_remove_file(&ap_bus_type, ap_bus_attrs[i]); 2006 bus_remove_file(&ap_bus_type, ap_bus_attrs[i]);
1995 bus_unregister(&ap_bus_type); 2007 bus_unregister(&ap_bus_type);
1996 unregister_reset_call(&ap_reset_call); 2008 unregister_reset_call(&ap_reset_call);
1997 if (ap_using_interrupts()) { 2009 if (ap_using_interrupts())
1998 s390_unregister_adapter_interrupt(ap_interrupt_indicator, AP_ISC); 2010 unregister_adapter_interrupt(&ap_airq);
1999 isc_unregister(AP_ISC);
2000 }
2001} 2011}
2002 2012
2003module_init(ap_module_init); 2013module_init(ap_module_init);