0001
0002 #include <linux/types.h>
0003 #include <linux/kernel.h>
0004 #include <linux/irq.h>
0005 #include <linux/smp.h>
0006 #include <linux/interrupt.h>
0007 #include <linux/init.h>
0008 #include <linux/cpu.h>
0009 #include <linux/of.h>
0010 #include <linux/spinlock.h>
0011 #include <linux/msi.h>
0012
0013 #include <asm/smp.h>
0014 #include <asm/machdep.h>
0015 #include <asm/irq.h>
0016 #include <asm/errno.h>
0017 #include <asm/xics.h>
0018 #include <asm/rtas.h>
0019
0020
0021 static int ibm_get_xive;
0022 static int ibm_set_xive;
0023 static int ibm_int_on;
0024 static int ibm_int_off;
0025
0026 static void ics_rtas_unmask_irq(struct irq_data *d)
0027 {
0028 unsigned int hw_irq = (unsigned int)irqd_to_hwirq(d);
0029 int call_status;
0030 int server;
0031
0032 pr_devel("xics: unmask virq %d [hw 0x%x]\n", d->irq, hw_irq);
0033
0034 if (hw_irq == XICS_IPI || hw_irq == XICS_IRQ_SPURIOUS)
0035 return;
0036
0037 server = xics_get_irq_server(d->irq, irq_data_get_affinity_mask(d), 0);
0038
0039 call_status = rtas_call_reentrant(ibm_set_xive, 3, 1, NULL, hw_irq,
0040 server, DEFAULT_PRIORITY);
0041 if (call_status != 0) {
0042 printk(KERN_ERR
0043 "%s: ibm_set_xive irq %u server %x returned %d\n",
0044 __func__, hw_irq, server, call_status);
0045 return;
0046 }
0047
0048
0049 call_status = rtas_call_reentrant(ibm_int_on, 1, 1, NULL, hw_irq);
0050 if (call_status != 0) {
0051 printk(KERN_ERR "%s: ibm_int_on irq=%u returned %d\n",
0052 __func__, hw_irq, call_status);
0053 return;
0054 }
0055 }
0056
0057 static unsigned int ics_rtas_startup(struct irq_data *d)
0058 {
0059
0060 ics_rtas_unmask_irq(d);
0061 return 0;
0062 }
0063
0064 static void ics_rtas_mask_real_irq(unsigned int hw_irq)
0065 {
0066 int call_status;
0067
0068 if (hw_irq == XICS_IPI)
0069 return;
0070
0071 call_status = rtas_call_reentrant(ibm_int_off, 1, 1, NULL, hw_irq);
0072 if (call_status != 0) {
0073 printk(KERN_ERR "%s: ibm_int_off irq=%u returned %d\n",
0074 __func__, hw_irq, call_status);
0075 return;
0076 }
0077
0078
0079 call_status = rtas_call_reentrant(ibm_set_xive, 3, 1, NULL, hw_irq,
0080 xics_default_server, 0xff);
0081 if (call_status != 0) {
0082 printk(KERN_ERR "%s: ibm_set_xive(0xff) irq=%u returned %d\n",
0083 __func__, hw_irq, call_status);
0084 return;
0085 }
0086 }
0087
0088 static void ics_rtas_mask_irq(struct irq_data *d)
0089 {
0090 unsigned int hw_irq = (unsigned int)irqd_to_hwirq(d);
0091
0092 pr_devel("xics: mask virq %d [hw 0x%x]\n", d->irq, hw_irq);
0093
0094 if (hw_irq == XICS_IPI || hw_irq == XICS_IRQ_SPURIOUS)
0095 return;
0096 ics_rtas_mask_real_irq(hw_irq);
0097 }
0098
0099 static int ics_rtas_set_affinity(struct irq_data *d,
0100 const struct cpumask *cpumask,
0101 bool force)
0102 {
0103 unsigned int hw_irq = (unsigned int)irqd_to_hwirq(d);
0104 int status;
0105 int xics_status[2];
0106 int irq_server;
0107
0108 if (hw_irq == XICS_IPI || hw_irq == XICS_IRQ_SPURIOUS)
0109 return -1;
0110
0111 status = rtas_call_reentrant(ibm_get_xive, 1, 3, xics_status, hw_irq);
0112
0113 if (status) {
0114 printk(KERN_ERR "%s: ibm,get-xive irq=%u returns %d\n",
0115 __func__, hw_irq, status);
0116 return -1;
0117 }
0118
0119 irq_server = xics_get_irq_server(d->irq, cpumask, 1);
0120 if (irq_server == -1) {
0121 pr_warn("%s: No online cpus in the mask %*pb for irq %d\n",
0122 __func__, cpumask_pr_args(cpumask), d->irq);
0123 return -1;
0124 }
0125
0126 pr_debug("%s: irq %d [hw 0x%x] server: 0x%x\n", __func__, d->irq,
0127 hw_irq, irq_server);
0128
0129 status = rtas_call_reentrant(ibm_set_xive, 3, 1, NULL,
0130 hw_irq, irq_server, xics_status[1]);
0131
0132 if (status) {
0133 printk(KERN_ERR "%s: ibm,set-xive irq=%u returns %d\n",
0134 __func__, hw_irq, status);
0135 return -1;
0136 }
0137
0138 return IRQ_SET_MASK_OK;
0139 }
0140
0141 static struct irq_chip ics_rtas_irq_chip = {
0142 .name = "XICS",
0143 .irq_startup = ics_rtas_startup,
0144 .irq_mask = ics_rtas_mask_irq,
0145 .irq_unmask = ics_rtas_unmask_irq,
0146 .irq_eoi = NULL,
0147 .irq_set_affinity = ics_rtas_set_affinity,
0148 .irq_set_type = xics_set_irq_type,
0149 .irq_retrigger = xics_retrigger,
0150 };
0151
0152 static int ics_rtas_check(struct ics *ics, unsigned int hw_irq)
0153 {
0154 int status[2];
0155 int rc;
0156
0157 if (WARN_ON(hw_irq == XICS_IPI || hw_irq == XICS_IRQ_SPURIOUS))
0158 return -EINVAL;
0159
0160
0161 rc = rtas_call_reentrant(ibm_get_xive, 1, 3, status, hw_irq);
0162 if (rc)
0163 return -ENXIO;
0164
0165 return 0;
0166 }
0167
0168 static void ics_rtas_mask_unknown(struct ics *ics, unsigned long vec)
0169 {
0170 ics_rtas_mask_real_irq(vec);
0171 }
0172
0173 static long ics_rtas_get_server(struct ics *ics, unsigned long vec)
0174 {
0175 int rc, status[2];
0176
0177 rc = rtas_call_reentrant(ibm_get_xive, 1, 3, status, vec);
0178 if (rc)
0179 return -1;
0180 return status[0];
0181 }
0182
0183 static int ics_rtas_host_match(struct ics *ics, struct device_node *node)
0184 {
0185
0186
0187
0188
0189 return !of_device_is_compatible(node, "chrp,iic");
0190 }
0191
0192
0193 static struct ics ics_rtas = {
0194 .check = ics_rtas_check,
0195 .mask_unknown = ics_rtas_mask_unknown,
0196 .get_server = ics_rtas_get_server,
0197 .host_match = ics_rtas_host_match,
0198 .chip = &ics_rtas_irq_chip,
0199 };
0200
0201 __init int ics_rtas_init(void)
0202 {
0203 ibm_get_xive = rtas_token("ibm,get-xive");
0204 ibm_set_xive = rtas_token("ibm,set-xive");
0205 ibm_int_on = rtas_token("ibm,int-on");
0206 ibm_int_off = rtas_token("ibm,int-off");
0207
0208
0209
0210
0211 if (ibm_get_xive == RTAS_UNKNOWN_SERVICE ||
0212 ibm_set_xive == RTAS_UNKNOWN_SERVICE)
0213 return -ENODEV;
0214
0215
0216
0217
0218 ics_rtas_irq_chip.irq_eoi = icp_ops->eoi;
0219
0220
0221 xics_register_ics(&ics_rtas);
0222
0223 return 0;
0224 }
0225