0001
0002
0003
0004
0005
0006
0007 #include <linux/irq.h>
0008 #include <linux/irq_sim.h>
0009 #include <linux/irq_work.h>
0010 #include <linux/interrupt.h>
0011 #include <linux/slab.h>
0012
0013 struct irq_sim_work_ctx {
0014 struct irq_work work;
0015 int irq_base;
0016 unsigned int irq_count;
0017 unsigned long *pending;
0018 struct irq_domain *domain;
0019 };
0020
0021 struct irq_sim_irq_ctx {
0022 int irqnum;
0023 bool enabled;
0024 struct irq_sim_work_ctx *work_ctx;
0025 };
0026
0027 static void irq_sim_irqmask(struct irq_data *data)
0028 {
0029 struct irq_sim_irq_ctx *irq_ctx = irq_data_get_irq_chip_data(data);
0030
0031 irq_ctx->enabled = false;
0032 }
0033
0034 static void irq_sim_irqunmask(struct irq_data *data)
0035 {
0036 struct irq_sim_irq_ctx *irq_ctx = irq_data_get_irq_chip_data(data);
0037
0038 irq_ctx->enabled = true;
0039 }
0040
0041 static int irq_sim_set_type(struct irq_data *data, unsigned int type)
0042 {
0043
0044 if (type & ~IRQ_TYPE_EDGE_BOTH)
0045 return -EINVAL;
0046
0047 irqd_set_trigger_type(data, type);
0048
0049 return 0;
0050 }
0051
0052 static int irq_sim_get_irqchip_state(struct irq_data *data,
0053 enum irqchip_irq_state which, bool *state)
0054 {
0055 struct irq_sim_irq_ctx *irq_ctx = irq_data_get_irq_chip_data(data);
0056 irq_hw_number_t hwirq = irqd_to_hwirq(data);
0057
0058 switch (which) {
0059 case IRQCHIP_STATE_PENDING:
0060 if (irq_ctx->enabled)
0061 *state = test_bit(hwirq, irq_ctx->work_ctx->pending);
0062 break;
0063 default:
0064 return -EINVAL;
0065 }
0066
0067 return 0;
0068 }
0069
0070 static int irq_sim_set_irqchip_state(struct irq_data *data,
0071 enum irqchip_irq_state which, bool state)
0072 {
0073 struct irq_sim_irq_ctx *irq_ctx = irq_data_get_irq_chip_data(data);
0074 irq_hw_number_t hwirq = irqd_to_hwirq(data);
0075
0076 switch (which) {
0077 case IRQCHIP_STATE_PENDING:
0078 if (irq_ctx->enabled) {
0079 assign_bit(hwirq, irq_ctx->work_ctx->pending, state);
0080 if (state)
0081 irq_work_queue(&irq_ctx->work_ctx->work);
0082 }
0083 break;
0084 default:
0085 return -EINVAL;
0086 }
0087
0088 return 0;
0089 }
0090
0091 static struct irq_chip irq_sim_irqchip = {
0092 .name = "irq_sim",
0093 .irq_mask = irq_sim_irqmask,
0094 .irq_unmask = irq_sim_irqunmask,
0095 .irq_set_type = irq_sim_set_type,
0096 .irq_get_irqchip_state = irq_sim_get_irqchip_state,
0097 .irq_set_irqchip_state = irq_sim_set_irqchip_state,
0098 };
0099
0100 static void irq_sim_handle_irq(struct irq_work *work)
0101 {
0102 struct irq_sim_work_ctx *work_ctx;
0103 unsigned int offset = 0;
0104 int irqnum;
0105
0106 work_ctx = container_of(work, struct irq_sim_work_ctx, work);
0107
0108 while (!bitmap_empty(work_ctx->pending, work_ctx->irq_count)) {
0109 offset = find_next_bit(work_ctx->pending,
0110 work_ctx->irq_count, offset);
0111 clear_bit(offset, work_ctx->pending);
0112 irqnum = irq_find_mapping(work_ctx->domain, offset);
0113 handle_simple_irq(irq_to_desc(irqnum));
0114 }
0115 }
0116
0117 static int irq_sim_domain_map(struct irq_domain *domain,
0118 unsigned int virq, irq_hw_number_t hw)
0119 {
0120 struct irq_sim_work_ctx *work_ctx = domain->host_data;
0121 struct irq_sim_irq_ctx *irq_ctx;
0122
0123 irq_ctx = kzalloc(sizeof(*irq_ctx), GFP_KERNEL);
0124 if (!irq_ctx)
0125 return -ENOMEM;
0126
0127 irq_set_chip(virq, &irq_sim_irqchip);
0128 irq_set_chip_data(virq, irq_ctx);
0129 irq_set_handler(virq, handle_simple_irq);
0130 irq_modify_status(virq, IRQ_NOREQUEST | IRQ_NOAUTOEN, IRQ_NOPROBE);
0131 irq_ctx->work_ctx = work_ctx;
0132
0133 return 0;
0134 }
0135
0136 static void irq_sim_domain_unmap(struct irq_domain *domain, unsigned int virq)
0137 {
0138 struct irq_sim_irq_ctx *irq_ctx;
0139 struct irq_data *irqd;
0140
0141 irqd = irq_domain_get_irq_data(domain, virq);
0142 irq_ctx = irq_data_get_irq_chip_data(irqd);
0143
0144 irq_set_handler(virq, NULL);
0145 irq_domain_reset_irq_data(irqd);
0146 kfree(irq_ctx);
0147 }
0148
0149 static const struct irq_domain_ops irq_sim_domain_ops = {
0150 .map = irq_sim_domain_map,
0151 .unmap = irq_sim_domain_unmap,
0152 };
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164 struct irq_domain *irq_domain_create_sim(struct fwnode_handle *fwnode,
0165 unsigned int num_irqs)
0166 {
0167 struct irq_sim_work_ctx *work_ctx;
0168
0169 work_ctx = kmalloc(sizeof(*work_ctx), GFP_KERNEL);
0170 if (!work_ctx)
0171 goto err_out;
0172
0173 work_ctx->pending = bitmap_zalloc(num_irqs, GFP_KERNEL);
0174 if (!work_ctx->pending)
0175 goto err_free_work_ctx;
0176
0177 work_ctx->domain = irq_domain_create_linear(fwnode, num_irqs,
0178 &irq_sim_domain_ops,
0179 work_ctx);
0180 if (!work_ctx->domain)
0181 goto err_free_bitmap;
0182
0183 work_ctx->irq_count = num_irqs;
0184 work_ctx->work = IRQ_WORK_INIT_HARD(irq_sim_handle_irq);
0185
0186 return work_ctx->domain;
0187
0188 err_free_bitmap:
0189 bitmap_free(work_ctx->pending);
0190 err_free_work_ctx:
0191 kfree(work_ctx);
0192 err_out:
0193 return ERR_PTR(-ENOMEM);
0194 }
0195 EXPORT_SYMBOL_GPL(irq_domain_create_sim);
0196
0197
0198
0199
0200
0201
0202
0203 void irq_domain_remove_sim(struct irq_domain *domain)
0204 {
0205 struct irq_sim_work_ctx *work_ctx = domain->host_data;
0206
0207 irq_work_sync(&work_ctx->work);
0208 bitmap_free(work_ctx->pending);
0209 kfree(work_ctx);
0210
0211 irq_domain_remove(domain);
0212 }
0213 EXPORT_SYMBOL_GPL(irq_domain_remove_sim);
0214
0215 static void devm_irq_domain_remove_sim(void *data)
0216 {
0217 struct irq_domain *domain = data;
0218
0219 irq_domain_remove_sim(domain);
0220 }
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233 struct irq_domain *devm_irq_domain_create_sim(struct device *dev,
0234 struct fwnode_handle *fwnode,
0235 unsigned int num_irqs)
0236 {
0237 struct irq_domain *domain;
0238 int ret;
0239
0240 domain = irq_domain_create_sim(fwnode, num_irqs);
0241 if (IS_ERR(domain))
0242 return domain;
0243
0244 ret = devm_add_action_or_reset(dev, devm_irq_domain_remove_sim, domain);
0245 if (ret)
0246 return ERR_PTR(ret);
0247
0248 return domain;
0249 }
0250 EXPORT_SYMBOL_GPL(devm_irq_domain_create_sim);