From 350559961593a9680244b22b32733a49e21f25d6 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 25 Jun 2006 01:32:25 -0700 Subject: [SPARC64]: Allow floppy driver to build modular. Signed-off-by: David S. Miller --- include/asm-sparc64/floppy.h | 50 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) (limited to 'include/asm-sparc64') diff --git a/include/asm-sparc64/floppy.h b/include/asm-sparc64/floppy.h index f8d57bb5570c..b591d0e8d8f0 100644 --- a/include/asm-sparc64/floppy.h +++ b/include/asm-sparc64/floppy.h @@ -208,7 +208,55 @@ static void sun_fd_enable_dma(void) pdma_areasize = pdma_size; } -extern irqreturn_t sparc_floppy_irq(int, void *, struct pt_regs *); +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); +} static int sun_fd_request_irq(void) { -- cgit v1.2.3 From 36321426e320c2c6bc2f8a1587d6f4d695fca84c Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 25 Jun 2006 02:07:52 -0700 Subject: [SPARC64]: Add missing interfaces to dma-mapping.h Signed-off-by: David S. Miller --- include/asm-sparc64/dma-mapping.h | 43 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'include/asm-sparc64') diff --git a/include/asm-sparc64/dma-mapping.h b/include/asm-sparc64/dma-mapping.h index 3c2b5bc8650b..0f5b89c9323b 100644 --- a/include/asm-sparc64/dma-mapping.h +++ b/include/asm-sparc64/dma-mapping.h @@ -162,4 +162,47 @@ static inline void dma_free_coherent(struct device *dev, size_t size, #endif /* PCI */ + +/* Now for the API extensions over the pci_ one */ + +#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) +#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) +#define dma_is_consistent(d) (1) + +static inline int +dma_get_cache_alignment(void) +{ + /* no easy way to get cache size on all processors, so return + * the maximum possible, to be safe */ + return (1 << INTERNODE_CACHE_SHIFT); +} + +static inline void +dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle, + unsigned long offset, size_t size, + enum dma_data_direction direction) +{ + /* just sync everything, that's all the pci API can do */ + dma_sync_single_for_cpu(dev, dma_handle, offset+size, direction); +} + +static inline void +dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle, + unsigned long offset, size_t size, + enum dma_data_direction direction) +{ + /* just sync everything, that's all the pci API can do */ + dma_sync_single_for_device(dev, dma_handle, offset+size, direction); +} + +static inline void +dma_cache_sync(void *vaddr, size_t size, + enum dma_data_direction direction) +{ + /* could define this in terms of the dma_cache ... operations, + * but if you get this on a platform, you should convert the platform + * to using the generic device DMA API */ + BUG(); +} + #endif /* _ASM_SPARC64_DMA_MAPPING_H */ -- cgit v1.2.3 From fb7cd9d9acfb52dc1b9fbd5079445e4732667bbc Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 25 Jun 2006 23:18:36 -0700 Subject: [SPARC]: Add of_set_property() interface. Signed-off-by: David S. Miller --- arch/sparc/kernel/prom.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++ arch/sparc64/kernel/prom.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++ include/asm-sparc/prom.h | 8 +++++++ include/asm-sparc64/prom.h | 8 +++++++ 4 files changed, 122 insertions(+) (limited to 'include/asm-sparc64') diff --git a/arch/sparc/kernel/prom.c b/arch/sparc/kernel/prom.c index 63b2b9bd778e..f3f53f2e0e1e 100644 --- a/arch/sparc/kernel/prom.c +++ b/arch/sparc/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) diff --git a/arch/sparc64/kernel/prom.c b/arch/sparc64/kernel/prom.c index e9d703eea806..c62fd3e7a0f8 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) diff --git a/include/asm-sparc/prom.h b/include/asm-sparc/prom.h index c5e3d26eabd3..e9b8047470fe 100644 --- a/include/asm-sparc/prom.h +++ b/include/asm-sparc/prom.h @@ -35,6 +35,7 @@ struct property { int length; void *value; struct property *next; + unsigned long _flags; }; struct device_node { @@ -60,6 +61,12 @@ struct device_node { void *data; }; +/* flag descriptions */ +#define OF_DYNAMIC 1 /* node and properties were allocated via kmalloc */ + +#define OF_IS_DYNAMIC(x) test_bit(OF_DYNAMIC, &x->_flags) +#define OF_MARK_DYNAMIC(x) set_bit(OF_DYNAMIC, &x->_flags) + static inline void set_node_proc_entry(struct device_node *dn, struct proc_dir_entry *de) { dn->pde = de; @@ -88,6 +95,7 @@ extern struct property *of_find_property(struct device_node *np, extern int of_device_is_compatible(struct device_node *device, const char *); extern void *of_get_property(struct device_node *node, const char *name, int *lenp); +extern int of_set_property(struct device_node *node, const char *name, void *val, int len); extern int of_getintprop_default(struct device_node *np, const char *name, int def); diff --git a/include/asm-sparc64/prom.h b/include/asm-sparc64/prom.h index 6d1556c0c263..c8022a337380 100644 --- a/include/asm-sparc64/prom.h +++ b/include/asm-sparc64/prom.h @@ -35,6 +35,7 @@ struct property { int length; void *value; struct property *next; + unsigned long _flags; }; struct device_node { @@ -60,6 +61,12 @@ struct device_node { void *data; }; +/* flag descriptions */ +#define OF_DYNAMIC 1 /* node and properties were allocated via kmalloc */ + +#define OF_IS_DYNAMIC(x) test_bit(OF_DYNAMIC, &x->_flags) +#define OF_MARK_DYNAMIC(x) set_bit(OF_DYNAMIC, &x->_flags) + static inline void set_node_proc_entry(struct device_node *dn, struct proc_dir_entry *de) { dn->pde = de; @@ -88,6 +95,7 @@ extern struct property *of_find_property(struct device_node *np, extern int of_device_is_compatible(struct device_node *device, const char *); extern void *of_get_property(struct device_node *node, const char *name, int *lenp); +extern int of_set_property(struct device_node *node, const char *name, void *val, int len); extern int of_getintprop_default(struct device_node *np, const char *name, int def); -- cgit v1.2.3 From 87b385da1f5a5f4a12a28e00fe597bcde8d6fea3 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 25 Jun 2006 23:18:57 -0700 Subject: [SPARC]: Add unique device_node IDs and a ".node" property. Signed-off-by: David S. Miller --- arch/sparc/kernel/prom.c | 53 +++++++++++++++++++++++++++++---------------- arch/sparc64/kernel/prom.c | 54 ++++++++++++++++++++++++++++++---------------- include/asm-sparc/prom.h | 2 ++ include/asm-sparc64/prom.h | 2 ++ 4 files changed, 75 insertions(+), 36 deletions(-) (limited to 'include/asm-sparc64') diff --git a/arch/sparc/kernel/prom.c b/arch/sparc/kernel/prom.c index f3f53f2e0e1e..946ce6d15819 100644 --- a/arch/sparc/kernel/prom.c +++ b/arch/sparc/kernel/prom.c @@ -407,7 +407,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; @@ -417,25 +419,34 @@ 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) { + 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); - len = 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; } @@ -444,9 +455,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; } @@ -475,6 +491,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); diff --git a/arch/sparc64/kernel/prom.c b/arch/sparc64/kernel/prom.c index c62fd3e7a0f8..8e87e7ea0325 100644 --- a/arch/sparc64/kernel/prom.c +++ b/arch/sparc64/kernel/prom.c @@ -584,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; @@ -593,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; } @@ -620,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; } @@ -651,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); diff --git a/include/asm-sparc/prom.h b/include/asm-sparc/prom.h index e9b8047470fe..f9cf44c07164 100644 --- a/include/asm-sparc/prom.h +++ b/include/asm-sparc/prom.h @@ -36,6 +36,7 @@ struct property { void *value; struct property *next; unsigned long _flags; + unsigned int unique_id; }; struct device_node { @@ -59,6 +60,7 @@ struct device_node { struct kref kref; unsigned long _flags; void *data; + unsigned int unique_id; }; /* flag descriptions */ diff --git a/include/asm-sparc64/prom.h b/include/asm-sparc64/prom.h index c8022a337380..265614d497c4 100644 --- a/include/asm-sparc64/prom.h +++ b/include/asm-sparc64/prom.h @@ -36,6 +36,7 @@ struct property { void *value; struct property *next; unsigned long _flags; + unsigned int unique_id; }; struct device_node { @@ -59,6 +60,7 @@ struct device_node { struct kref kref; unsigned long _flags; void *data; + unsigned int unique_id; }; /* flag descriptions */ -- cgit v1.2.3