[SPARC]: sparc32 side of of_device layer IRQ resolution.
Happily, life is much simpler on 32-bit sparc systems. The "intr" property, preferred over the "interrupts" property is used-as. Some minor translations of this value happen on sun4d systems. The stage is now set to rewrite the sparc serial driver probing to use the of_driver framework, and then to convert all SBUS, EBUS, and ISA drivers in-kind so that we can nuke all those special bus frameworks. Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
committed by
David S. Miller
parent
2b1e597871
commit
8f96cd1a69
@@ -129,6 +129,26 @@ static int of_device_resume(struct device * dev)
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int node_match(struct device *dev, void *data)
|
||||||
|
{
|
||||||
|
struct of_device *op = to_of_device(dev);
|
||||||
|
struct device_node *dp = data;
|
||||||
|
|
||||||
|
return (op->node == dp);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct of_device *of_find_device_by_node(struct device_node *dp)
|
||||||
|
{
|
||||||
|
struct device *dev = bus_find_device(&of_bus_type, NULL,
|
||||||
|
dp, node_match);
|
||||||
|
|
||||||
|
if (dev)
|
||||||
|
return to_of_device(dev);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(of_find_device_by_node);
|
||||||
|
|
||||||
#ifdef CONFIG_PCI
|
#ifdef CONFIG_PCI
|
||||||
struct bus_type ebus_bus_type = {
|
struct bus_type ebus_bus_type = {
|
||||||
.name = "ebus",
|
.name = "ebus",
|
||||||
@@ -503,8 +523,8 @@ static struct of_device * __init scan_one_device(struct device_node *dp,
|
|||||||
struct device *parent)
|
struct device *parent)
|
||||||
{
|
{
|
||||||
struct of_device *op = kzalloc(sizeof(*op), GFP_KERNEL);
|
struct of_device *op = kzalloc(sizeof(*op), GFP_KERNEL);
|
||||||
unsigned int *irq;
|
struct linux_prom_irqs *intr;
|
||||||
int len;
|
int len, i;
|
||||||
|
|
||||||
if (!op)
|
if (!op)
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -517,11 +537,46 @@ static struct of_device * __init scan_one_device(struct device_node *dp,
|
|||||||
if (op->portid == -1)
|
if (op->portid == -1)
|
||||||
op->portid = of_getintprop_default(dp, "portid", -1);
|
op->portid = of_getintprop_default(dp, "portid", -1);
|
||||||
|
|
||||||
irq = of_get_property(dp, "interrupts", &len);
|
intr = of_get_property(dp, "intr", &len);
|
||||||
if (irq)
|
if (intr) {
|
||||||
op->irq = *irq;
|
op->num_irqs = len / sizeof(struct linux_prom_irqs);
|
||||||
else
|
for (i = 0; i < op->num_irqs; i++)
|
||||||
op->irq = 0xffffffff;
|
op->irqs[i] = intr[i].pri;
|
||||||
|
} else {
|
||||||
|
unsigned int *irq = of_get_property(dp, "interrupts", &len);
|
||||||
|
|
||||||
|
if (irq) {
|
||||||
|
op->num_irqs = len / sizeof(unsigned int);
|
||||||
|
for (i = 0; i < op->num_irqs; i++)
|
||||||
|
op->irqs[i] = irq[i];
|
||||||
|
} else {
|
||||||
|
op->num_irqs = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sparc_cpu_model == sun4d) {
|
||||||
|
static int pil_to_sbus[] = {
|
||||||
|
0, 0, 1, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 0,
|
||||||
|
};
|
||||||
|
struct device_node *busp = dp->parent;
|
||||||
|
struct linux_prom_registers *regs;
|
||||||
|
int board = of_getintprop_default(busp, "board#", 0);
|
||||||
|
int slot;
|
||||||
|
|
||||||
|
regs = of_get_property(dp, "reg", NULL);
|
||||||
|
slot = regs->which_io;
|
||||||
|
|
||||||
|
for (i = 0; i < op->num_irqs; i++) {
|
||||||
|
int this_irq = op->irqs[i];
|
||||||
|
int sbusl = pil_to_sbus[this_irq];
|
||||||
|
|
||||||
|
if (sbusl)
|
||||||
|
this_irq = (((board + 1) << 5) +
|
||||||
|
(sbusl << 2) +
|
||||||
|
slot);
|
||||||
|
|
||||||
|
op->irqs[i] = this_irq;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
build_device_resources(op, parent);
|
build_device_resources(op, parent);
|
||||||
|
|
||||||
|
@@ -21,7 +21,8 @@ struct of_device
|
|||||||
struct device_node *node;
|
struct device_node *node;
|
||||||
struct device dev;
|
struct device dev;
|
||||||
struct resource resource[PROMREG_MAX];
|
struct resource resource[PROMREG_MAX];
|
||||||
unsigned int irq;
|
unsigned int irqs[PROMINTR_MAX];
|
||||||
|
int num_irqs;
|
||||||
|
|
||||||
void *sysdata;
|
void *sysdata;
|
||||||
|
|
||||||
@@ -34,6 +35,8 @@ struct of_device
|
|||||||
extern void __iomem *of_ioremap(struct resource *res, unsigned long offset, unsigned long size, char *name);
|
extern void __iomem *of_ioremap(struct resource *res, unsigned long offset, unsigned long size, char *name);
|
||||||
extern void of_iounmap(void __iomem *base, unsigned long size);
|
extern void of_iounmap(void __iomem *base, unsigned long size);
|
||||||
|
|
||||||
|
extern struct of_device *of_find_device_by_node(struct device_node *);
|
||||||
|
|
||||||
extern const struct of_device_id *of_match_device(
|
extern const struct of_device_id *of_match_device(
|
||||||
const struct of_device_id *matches, const struct of_device *dev);
|
const struct of_device_id *matches, const struct of_device *dev);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user