summaryrefslogtreecommitdiff
path: root/arch/sparc64/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc64/kernel')
-rw-r--r--arch/sparc64/kernel/auxio.c3
-rw-r--r--arch/sparc64/kernel/irq.c61
-rw-r--r--arch/sparc64/kernel/of_device.c3
-rw-r--r--arch/sparc64/kernel/prom.c107
4 files changed, 94 insertions, 80 deletions
diff --git a/arch/sparc64/kernel/auxio.c b/arch/sparc64/kernel/auxio.c
index 2c42894..c2c69c1 100644
--- a/arch/sparc64/kernel/auxio.c
+++ b/arch/sparc64/kernel/auxio.c
@@ -6,6 +6,7 @@
*/
#include <linux/config.h>
+#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/ioport.h>
@@ -16,8 +17,8 @@
#include <asm/ebus.h>
#include <asm/auxio.h>
-/* This cannot be static, as it is referenced in irq.c */
void __iomem *auxio_register = NULL;
+EXPORT_SYMBOL(auxio_register);
enum auxio_type {
AUXIO_TYPE_NODEV,
diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c
index 31e0fbb..cc89b06 100644
--- a/arch/sparc64/kernel/irq.c
+++ b/arch/sparc64/kernel/irq.c
@@ -563,67 +563,6 @@ void handler_irq(int irq, struct pt_regs *regs)
irq_exit();
}
-#ifdef CONFIG_BLK_DEV_FD
-extern irqreturn_t floppy_interrupt(int, void *, struct pt_regs *);
-
-/* XXX No easy way to include asm/floppy.h XXX */
-extern unsigned char *pdma_vaddr;
-extern unsigned long pdma_size;
-extern volatile int doing_pdma;
-extern unsigned long fdc_status;
-
-irqreturn_t sparc_floppy_irq(int irq, void *dev_cookie, struct pt_regs *regs)
-{
- if (likely(doing_pdma)) {
- void __iomem *stat = (void __iomem *) fdc_status;
- unsigned char *vaddr = pdma_vaddr;
- unsigned long size = pdma_size;
- u8 val;
-
- while (size) {
- val = readb(stat);
- if (unlikely(!(val & 0x80))) {
- pdma_vaddr = vaddr;
- pdma_size = size;
- return IRQ_HANDLED;
- }
- if (unlikely(!(val & 0x20))) {
- pdma_vaddr = vaddr;
- pdma_size = size;
- doing_pdma = 0;
- goto main_interrupt;
- }
- if (val & 0x40) {
- /* read */
- *vaddr++ = readb(stat + 1);
- } else {
- unsigned char data = *vaddr++;
-
- /* write */
- writeb(data, stat + 1);
- }
- size--;
- }
-
- pdma_vaddr = vaddr;
- pdma_size = size;
-
- /* Send Terminal Count pulse to floppy controller. */
- val = readb(auxio_register);
- val |= AUXIO_AUX1_FTCNT;
- writeb(val, auxio_register);
- val &= ~AUXIO_AUX1_FTCNT;
- writeb(val, auxio_register);
-
- doing_pdma = 0;
- }
-
-main_interrupt:
- return floppy_interrupt(irq, dev_cookie, regs);
-}
-EXPORT_SYMBOL(sparc_floppy_irq);
-#endif
-
struct sun5_timer {
u64 count0;
u64 limit0;
diff --git a/arch/sparc64/kernel/of_device.c b/arch/sparc64/kernel/of_device.c
index 566aa34..768475b 100644
--- a/arch/sparc64/kernel/of_device.c
+++ b/arch/sparc64/kernel/of_device.c
@@ -138,6 +138,7 @@ struct bus_type isa_bus_type = {
.suspend = of_device_suspend,
.resume = of_device_resume,
};
+EXPORT_SYMBOL(isa_bus_type);
struct bus_type ebus_bus_type = {
.name = "ebus",
@@ -147,6 +148,7 @@ struct bus_type ebus_bus_type = {
.suspend = of_device_suspend,
.resume = of_device_resume,
};
+EXPORT_SYMBOL(ebus_bus_type);
#endif
#ifdef CONFIG_SBUS
@@ -158,6 +160,7 @@ struct bus_type sbus_bus_type = {
.suspend = of_device_suspend,
.resume = of_device_resume,
};
+EXPORT_SYMBOL(sbus_bus_type);
#endif
static int __init of_bus_driver_init(void)
diff --git a/arch/sparc64/kernel/prom.c b/arch/sparc64/kernel/prom.c
index e9d703e..8e87e7e 100644
--- a/arch/sparc64/kernel/prom.c
+++ b/arch/sparc64/kernel/prom.c
@@ -27,6 +27,11 @@
static struct device_node *allnodes;
+/* use when traversing tree through the allnext, child, sibling,
+ * or parent members of struct device_node.
+ */
+static DEFINE_RWLOCK(devtree_lock);
+
int of_device_is_compatible(struct device_node *device, const char *compat)
{
const char* cp;
@@ -185,6 +190,54 @@ int of_getintprop_default(struct device_node *np, const char *name, int def)
}
EXPORT_SYMBOL(of_getintprop_default);
+int of_set_property(struct device_node *dp, const char *name, void *val, int len)
+{
+ struct property **prevp;
+ void *new_val;
+ int err;
+
+ new_val = kmalloc(len, GFP_KERNEL);
+ if (!new_val)
+ return -ENOMEM;
+
+ memcpy(new_val, val, len);
+
+ err = -ENODEV;
+
+ write_lock(&devtree_lock);
+ prevp = &dp->properties;
+ while (*prevp) {
+ struct property *prop = *prevp;
+
+ if (!strcmp(prop->name, name)) {
+ void *old_val = prop->value;
+ int ret;
+
+ ret = prom_setprop(dp->node, name, val, len);
+ err = -EINVAL;
+ if (ret >= 0) {
+ prop->value = new_val;
+ prop->length = len;
+
+ if (OF_IS_DYNAMIC(prop))
+ kfree(old_val);
+
+ OF_MARK_DYNAMIC(prop);
+
+ err = 0;
+ }
+ break;
+ }
+ prevp = &(*prevp)->next;
+ }
+ write_unlock(&devtree_lock);
+
+ /* XXX Upate procfs if necessary... */
+
+ return err;
+}
+EXPORT_SYMBOL(of_set_property);
+
static unsigned int prom_early_allocated;
static void * __init prom_early_alloc(unsigned long size)
@@ -531,7 +584,9 @@ static char * __init build_full_name(struct device_node *dp)
return n;
}
-static struct property * __init build_one_prop(phandle node, char *prev)
+static unsigned int unique_id;
+
+static struct property * __init build_one_prop(phandle node, char *prev, char *special_name, void *special_val, int special_len)
{
static struct property *tmp = NULL;
struct property *p;
@@ -540,25 +595,35 @@ static struct property * __init build_one_prop(phandle node, char *prev)
p = tmp;
memset(p, 0, sizeof(*p) + 32);
tmp = NULL;
- } else
+ } else {
p = prom_early_alloc(sizeof(struct property) + 32);
+ p->unique_id = unique_id++;
+ }
p->name = (char *) (p + 1);
- if (prev == NULL) {
- prom_firstprop(node, p->name);
+ if (special_name) {
+ strcpy(p->name, special_name);
+ p->length = special_len;
+ p->value = prom_early_alloc(special_len);
+ memcpy(p->value, special_val, special_len);
} else {
- prom_nextprop(node, prev, p->name);
- }
- if (strlen(p->name) == 0) {
- tmp = p;
- return NULL;
- }
- p->length = prom_getproplen(node, p->name);
- if (p->length <= 0) {
- p->length = 0;
- } else {
- p->value = prom_early_alloc(p->length);
- prom_getproperty(node, p->name, p->value, p->length);
+ if (prev == NULL) {
+ prom_firstprop(node, p->name);
+ } else {
+ prom_nextprop(node, prev, p->name);
+ }
+ if (strlen(p->name) == 0) {
+ tmp = p;
+ return NULL;
+ }
+ p->length = prom_getproplen(node, p->name);
+ if (p->length <= 0) {
+ p->length = 0;
+ } else {
+ p->value = prom_early_alloc(p->length + 1);
+ prom_getproperty(node, p->name, p->value, p->length);
+ ((unsigned char *)p->value)[p->length] = '\0';
+ }
}
return p;
}
@@ -567,9 +632,14 @@ static struct property * __init build_prop_list(phandle node)
{
struct property *head, *tail;
- head = tail = build_one_prop(node, NULL);
+ head = tail = build_one_prop(node, NULL,
+ ".node", &node, sizeof(node));
+
+ tail->next = build_one_prop(node, NULL, NULL, NULL, 0);
+ tail = tail->next;
while(tail) {
- tail->next = build_one_prop(node, tail->name);
+ tail->next = build_one_prop(node, tail->name,
+ NULL, NULL, 0);
tail = tail->next;
}
@@ -598,6 +668,7 @@ static struct device_node * __init create_node(phandle node)
return NULL;
dp = prom_early_alloc(sizeof(*dp));
+ dp->unique_id = unique_id++;
kref_init(&dp->kref);