/* List of SPs, SP count, read-write access lock, and access functions * * Lock structure: get sp_unit_lock for reading whenever we need to * examine the SP list.
*/ static DEFINE_RWLOCK(sp_unit_lock); static LIST_HEAD(sp_units);
/* Ever-increasing value to produce unique unit numbers */ static atomic_t sp_ordinal;
if (sp->ccp_irq_handler)
sp->ccp_irq_handler(irq, sp->ccp_irq_data);
if (sp->psp_irq_handler)
sp->psp_irq_handler(irq, sp->psp_irq_data);
return IRQ_HANDLED;
}
int sp_request_ccp_irq(struct sp_device *sp, irq_handler_t handler, constchar *name, void *data)
{ int ret;
if ((sp->psp_irq == sp->ccp_irq) && sp->dev_vdata->psp_vdata) { /* Need a common routine to manage all interrupts */
sp->ccp_irq_data = data;
sp->ccp_irq_handler = handler;
if (!sp->irq_registered) {
ret = request_irq(sp->ccp_irq, sp_irq_handler, 0,
sp->name, sp); if (ret) return ret;
sp->irq_registered = true;
}
} else { /* Each sub-device can manage it's own interrupt */
ret = request_irq(sp->ccp_irq, handler, 0, name, data); if (ret) return ret;
}
return 0;
}
int sp_request_psp_irq(struct sp_device *sp, irq_handler_t handler, constchar *name, void *data)
{ int ret;
if ((sp->psp_irq == sp->ccp_irq) && sp->dev_vdata->ccp_vdata) { /* Need a common routine to manage all interrupts */
sp->psp_irq_data = data;
sp->psp_irq_handler = handler;
if (!sp->irq_registered) {
ret = request_irq(sp->psp_irq, sp_irq_handler, 0,
sp->name, sp); if (ret) return ret;
sp->irq_registered = true;
}
} else { /* Each sub-device can manage it's own interrupt */
ret = request_irq(sp->psp_irq, handler, 0, name, data); if (ret) return ret;
}
return 0;
}
void sp_free_ccp_irq(struct sp_device *sp, void *data)
{ if ((sp->psp_irq == sp->ccp_irq) && sp->dev_vdata->psp_vdata) { /* Using common routine to manage all interrupts */ if (!sp->psp_irq_handler) { /* Nothing else using it, so free it */
free_irq(sp->ccp_irq, sp);
sp->irq_registered = false;
}
sp->ccp_irq_handler = NULL;
sp->ccp_irq_data = NULL;
} else { /* Each sub-device can manage it's own interrupt */
free_irq(sp->ccp_irq, data);
}
}
void sp_free_psp_irq(struct sp_device *sp, void *data)
{ if ((sp->psp_irq == sp->ccp_irq) && sp->dev_vdata->ccp_vdata) { /* Using common routine to manage all interrupts */ if (!sp->ccp_irq_handler) { /* Nothing else using it, so free it */
free_irq(sp->psp_irq, sp);
sp->irq_registered = false;
}
sp->psp_irq_handler = NULL;
sp->psp_irq_data = NULL;
} else { /* Each sub-device can manage it's own interrupt */
free_irq(sp->psp_irq, data);
}
}
/** * sp_alloc_struct - allocate and initialize the sp_device struct * * @dev: device struct of the SP
*/ struct sp_device *sp_alloc_struct(struct device *dev)
{ struct sp_device *sp;
sp = devm_kzalloc(dev, sizeof(*sp), GFP_KERNEL); if (!sp) return NULL;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.