···1313#include <asm/sbus.h>1414#include <asm/dma.h>1515#include <asm/oplib.h>1616+#include <asm/prom.h>1717+#include <asm/of_device.h>1618#include <asm/bpp.h>1719#include <asm/irq.h>18201921struct sbus_bus *sbus_root;20222121-#ifdef CONFIG_PCI2222-extern int pcic_present(void);2323-#endif2424-2525-static void __init fill_sbus_device(int prom_node, struct sbus_dev *sdev)2323+static void __init fill_sbus_device(struct device_node *dp, struct sbus_dev *sdev)2624{2727- unsigned long address, base;2525+ unsigned long base;2626+ void *pval;2827 int len;29283030- sdev->prom_node = prom_node;3131- prom_getstring(prom_node, "name",3232- sdev->prom_name, sizeof(sdev->prom_name));3333- address = prom_getint(prom_node, "address");3434- len = prom_getproperty(prom_node, "reg",3535- (char *) sdev->reg_addrs,3636- sizeof(sdev->reg_addrs));2929+ sdev->prom_node = dp->node;3030+ strcpy(sdev->prom_name, dp->name);3131+3232+ pval = of_get_property(dp, "reg", &len);3733 sdev->num_registers = 0;3838- if (len != -1) {3434+ if (pval) {3535+ memcpy(sdev->reg_addrs, pval, len);3636+3937 sdev->num_registers =4038 len / sizeof(struct linux_prom_registers);4141- sdev->ranges_applied = 0;42394340 base = (unsigned long) sdev->reg_addrs[0].phys_addr;4441···4649 sdev->slot = sdev->reg_addrs[0].which_io;4750 }48514949- len = prom_getproperty(prom_node, "ranges",5050- (char *)sdev->device_ranges,5151- sizeof(sdev->device_ranges));5252+ pval = of_get_property(dp, "ranges", &len);5253 sdev->num_device_ranges = 0;5353- if (len != -1)5454+ if (pval) {5555+ memcpy(sdev->device_ranges, pval, len);5456 sdev->num_device_ranges =5557 len / sizeof(struct linux_prom_ranges);5858+ }56595760 sbus_fill_device_irq(sdev);6161+6262+ sdev->ofdev.node = dp;6363+ if (sdev->parent)6464+ sdev->ofdev.dev.parent = &sdev->parent->ofdev.dev;6565+ else6666+ sdev->ofdev.dev.parent = &sdev->bus->ofdev.dev;6767+ sdev->ofdev.dev.bus = &sbus_bus_type;6868+ strcpy(sdev->ofdev.dev.bus_id, dp->path_component_name);6969+7070+ if (of_device_register(&sdev->ofdev) != 0)7171+ printk(KERN_DEBUG "sbus: device registration error for %s!\n",7272+ sdev->ofdev.dev.bus_id);5873}59746060-/* This routine gets called from whoever needs the sbus first, to scan6161- * the SBus device tree. Currently it just prints out the devices6262- * found on the bus and builds trees of SBUS structs and attached6363- * devices.6464- */6565-6666-extern void iommu_init(int iommu_node, struct sbus_bus *sbus);6767-extern void iounit_init(int sbi_node, int iounit_node, struct sbus_bus *sbus);6868-void sun4_init(void);6969-#ifdef CONFIG_SUN_AUXIO7070-extern void auxio_probe(void);7171-#endif7272-7373-static void __init sbus_do_child_siblings(int start_node,7474- struct sbus_dev *child,7575- struct sbus_dev *parent,7676- struct sbus_bus *sbus)7575+static void __init sbus_bus_ranges_init(struct device_node *dp, struct sbus_bus *sbus)7776{7878- struct sbus_dev *this_dev = child;7979- int this_node = start_node;8080-8181- /* Child already filled in, just need to traverse siblings. */8282- child->child = NULL;8383- child->parent = parent;8484- while((this_node = prom_getsibling(this_node)) != 0) {8585- this_dev->next = kmalloc(sizeof(struct sbus_dev), GFP_ATOMIC);8686- this_dev = this_dev->next;8787- this_dev->next = NULL;8888- this_dev->parent = parent;8989-9090- this_dev->bus = sbus;9191- fill_sbus_device(this_node, this_dev);9292-9393- if(prom_getchild(this_node)) {9494- this_dev->child = kmalloc(sizeof(struct sbus_dev),9595- GFP_ATOMIC);9696- this_dev->child->bus = sbus;9797- this_dev->child->next = NULL;9898- fill_sbus_device(prom_getchild(this_node), this_dev->child);9999- sbus_do_child_siblings(prom_getchild(this_node),100100- this_dev->child, this_dev, sbus);101101- } else {102102- this_dev->child = NULL;103103- }104104- }105105-}106106-107107-/*108108- * XXX This functions appears to be a distorted version of109109- * prom_sbus_ranges_init(), with all sun4d stuff cut away.110110- * Ask DaveM what is going on here, how is sun4d supposed to work... XXX111111- */112112-/* added back sun4d patch from Thomas Bogendoerfer - should be OK (crn) */113113-114114-static void __init sbus_bus_ranges_init(int parent_node, struct sbus_bus *sbus)115115-{7777+ void *pval;11678 int len;11779118118- len = prom_getproperty(sbus->prom_node, "ranges",119119- (char *) sbus->sbus_ranges,120120- sizeof(sbus->sbus_ranges));121121- if (len == -1 || len == 0) {122122- sbus->num_sbus_ranges = 0;123123- return;124124- }125125- sbus->num_sbus_ranges = len / sizeof(struct linux_prom_ranges);126126-#ifdef CONFIG_SPARC32127127- if (sparc_cpu_model == sun4d) {128128- struct linux_prom_ranges iounit_ranges[PROMREG_MAX];129129- int num_iounit_ranges;8080+ pval = of_get_property(dp, "ranges", &len);8181+ sbus->num_sbus_ranges = 0;8282+ if (pval) {8383+ memcpy(sbus->sbus_ranges, pval, len);8484+ sbus->num_sbus_ranges =8585+ len / sizeof(struct linux_prom_ranges);13086131131- len = prom_getproperty(parent_node, "ranges",132132- (char *) iounit_ranges,133133- sizeof (iounit_ranges));134134- if (len != -1) {135135- num_iounit_ranges = (len/sizeof(struct linux_prom_ranges));136136- prom_adjust_ranges (sbus->sbus_ranges, sbus->num_sbus_ranges, iounit_ranges, num_iounit_ranges);137137- }8787+ sbus_arch_bus_ranges_init(dp->parent, sbus);13888 }139139-#endif14089}1419014291static void __init __apply_ranges_to_regs(struct linux_prom_ranges *ranges,···160217 }161218}162219163163-extern void register_proc_sparc_ioport(void);164164-extern void firetruck_init(void);220220+/* We preserve the "probe order" of these bus and device lists to give221221+ * the same ordering as the old code.222222+ */223223+static void __init sbus_insert(struct sbus_bus *sbus, struct sbus_bus **root)224224+{225225+ while (*root)226226+ root = &(*root)->next;227227+ *root = sbus;228228+ sbus->next = NULL;229229+}165230166166-#ifdef CONFIG_SUN4167167-extern void sun4_dvma_init(void);168168-#endif231231+static void __init sdev_insert(struct sbus_dev *sdev, struct sbus_dev **root)232232+{233233+ while (*root)234234+ root = &(*root)->next;235235+ *root = sdev;236236+ sdev->next = NULL;237237+}238238+239239+static void __init walk_children(struct device_node *dp, struct sbus_dev *parent, struct sbus_bus *sbus)240240+{241241+ dp = dp->child;242242+ while (dp) {243243+ struct sbus_dev *sdev;244244+245245+ sdev = kzalloc(sizeof(struct sbus_dev), GFP_ATOMIC);246246+ if (sdev) {247247+ sdev_insert(sdev, &parent->child);248248+249249+ sdev->bus = sbus;250250+ sdev->parent = parent;251251+252252+ fill_sbus_device(dp, sdev);253253+254254+ walk_children(dp, sdev, sbus);255255+ }256256+ dp = dp->sibling;257257+ }258258+}259259+260260+static void __init build_one_sbus(struct device_node *dp, int num_sbus)261261+{262262+ struct sbus_bus *sbus;263263+ unsigned int sbus_clock;264264+ struct device_node *dev_dp;265265+266266+ sbus = kzalloc(sizeof(struct sbus_bus), GFP_ATOMIC);267267+ if (!sbus)268268+ return;269269+270270+ sbus_insert(sbus, &sbus_root);271271+ sbus->prom_node = dp->node;272272+273273+ sbus_setup_iommu(sbus, dp);274274+275275+ printk("sbus%d: ", num_sbus);276276+277277+ sbus_clock = of_getintprop_default(dp, "clock-frequency",278278+ (25*1000*1000));279279+ sbus->clock_freq = sbus_clock;280280+281281+ printk("Clock %d.%d MHz\n", (int) ((sbus_clock/1000)/1000),282282+ (int) (((sbus_clock/1000)%1000 != 0) ? 283283+ (((sbus_clock/1000)%1000) + 1000) : 0));284284+285285+ strcpy(sbus->prom_name, dp->name);286286+287287+ sbus_setup_arch_props(sbus, dp);288288+289289+ sbus_bus_ranges_init(dp, sbus);290290+291291+ sbus->ofdev.node = dp;292292+ sbus->ofdev.dev.parent = NULL;293293+ sbus->ofdev.dev.bus = &sbus_bus_type;294294+ strcpy(sbus->ofdev.dev.bus_id, dp->path_component_name);295295+296296+ if (of_device_register(&sbus->ofdev) != 0)297297+ printk(KERN_DEBUG "sbus: device registration error for %s!\n",298298+ sbus->ofdev.dev.bus_id);299299+300300+ dev_dp = dp->child;301301+ while (dev_dp) {302302+ struct sbus_dev *sdev;303303+304304+ sdev = kzalloc(sizeof(struct sbus_dev), GFP_ATOMIC);305305+ if (sdev) {306306+ sdev_insert(sdev, &sbus->devices);307307+308308+ sdev->bus = sbus;309309+ sdev->parent = NULL;310310+ fill_sbus_device(dev_dp, sdev);311311+312312+ walk_children(dev_dp, sdev, sbus);313313+ }314314+ dev_dp = dev_dp->sibling;315315+ }316316+317317+ sbus_fixup_all_regs(sbus->devices);318318+319319+ dvma_init(sbus);320320+}169321170322static int __init sbus_init(void)171323{172172- int nd, this_sbus, sbus_devs, topnd, iommund;173173- unsigned int sbus_clock;174174- struct sbus_bus *sbus;175175- struct sbus_dev *this_dev;176176- int num_sbus = 0; /* How many did we find? */324324+ struct device_node *dp;325325+ const char *sbus_name = "sbus";326326+ int num_sbus = 0;177327178178-#ifdef CONFIG_SPARC32179179- register_proc_sparc_ioport();180180-#endif328328+ if (sbus_arch_preinit())329329+ return 0;181330182182-#ifdef CONFIG_SUN4183183- sun4_dvma_init();184184- return 0;185185-#endif331331+ if (sparc_cpu_model == sun4d)332332+ sbus_name = "sbi";186333187187- topnd = prom_getchild(prom_root_node);188188-189189- /* Finding the first sbus is a special case... */190190- iommund = 0;191191- if(sparc_cpu_model == sun4u) {192192- nd = prom_searchsiblings(topnd, "sbus");193193- if(nd == 0) {194194-#ifdef CONFIG_PCI195195- if (!pcic_present()) {196196- prom_printf("Neither SBUS nor PCI found.\n");197197- prom_halt();198198- } else {199199-#ifdef CONFIG_SPARC64200200- firetruck_init();201201-#endif202202- }203203- return 0;204204-#else205205- prom_printf("YEEE, UltraSparc sbus not found\n");206206- prom_halt();207207-#endif208208- }209209- } else if(sparc_cpu_model == sun4d) {210210- if((iommund = prom_searchsiblings(topnd, "io-unit")) == 0 ||211211- (nd = prom_getchild(iommund)) == 0 ||212212- (nd = prom_searchsiblings(nd, "sbi")) == 0) {213213- panic("sbi not found");214214- }215215- } else if((nd = prom_searchsiblings(topnd, "sbus")) == 0) {216216- if((iommund = prom_searchsiblings(topnd, "iommu")) == 0 ||217217- (nd = prom_getchild(iommund)) == 0 ||218218- (nd = prom_searchsiblings(nd, "sbus")) == 0) {219219-#ifdef CONFIG_PCI220220- if (!pcic_present()) {221221- prom_printf("Neither SBUS nor PCI found.\n");222222- prom_halt();223223- }224224- return 0;225225-#else226226- /* No reason to run further - the data access trap will occur. */227227- panic("sbus not found");228228-#endif229229- }230230- }231231-232232- /* Ok, we've found the first one, allocate first SBus struct233233- * and place in chain.234234- */235235- sbus = sbus_root = kmalloc(sizeof(struct sbus_bus), GFP_ATOMIC);236236- sbus->next = NULL;237237- sbus->prom_node = nd;238238- this_sbus = nd;239239-240240- if(iommund && sparc_cpu_model != sun4u && sparc_cpu_model != sun4d)241241- iommu_init(iommund, sbus);242242-243243- /* Loop until we find no more SBUS's */244244- while(this_sbus) {245245-#ifdef CONFIG_SPARC64246246- /* IOMMU hides inside SBUS/SYSIO prom node on Ultra. */247247- if(sparc_cpu_model == sun4u) {248248- extern void sbus_iommu_init(int prom_node, struct sbus_bus *sbus);249249-250250- sbus_iommu_init(this_sbus, sbus);251251- }252252-#endif /* CONFIG_SPARC64 */253253-254254-#ifdef CONFIG_SPARC32255255- if (sparc_cpu_model == sun4d)256256- iounit_init(this_sbus, iommund, sbus);257257-#endif /* CONFIG_SPARC32 */258258- printk("sbus%d: ", num_sbus);259259- sbus_clock = prom_getint(this_sbus, "clock-frequency");260260- if(sbus_clock == -1)261261- sbus_clock = (25*1000*1000);262262- printk("Clock %d.%d MHz\n", (int) ((sbus_clock/1000)/1000),263263- (int) (((sbus_clock/1000)%1000 != 0) ? 264264- (((sbus_clock/1000)%1000) + 1000) : 0));265265-266266- prom_getstring(this_sbus, "name",267267- sbus->prom_name, sizeof(sbus->prom_name));268268- sbus->clock_freq = sbus_clock;269269-#ifdef CONFIG_SPARC32270270- if (sparc_cpu_model == sun4d) {271271- sbus->devid = prom_getint(iommund, "device-id");272272- sbus->board = prom_getint(iommund, "board#");273273- }274274-#endif275275-276276- sbus_bus_ranges_init(iommund, sbus);277277-278278- sbus_devs = prom_getchild(this_sbus);279279- if (!sbus_devs) {280280- sbus->devices = NULL;281281- goto next_bus;282282- }283283-284284- sbus->devices = kmalloc(sizeof(struct sbus_dev), GFP_ATOMIC);285285-286286- this_dev = sbus->devices;287287- this_dev->next = NULL;288288-289289- this_dev->bus = sbus;290290- this_dev->parent = NULL;291291- fill_sbus_device(sbus_devs, this_dev);292292-293293- /* Should we traverse for children? */294294- if(prom_getchild(sbus_devs)) {295295- /* Allocate device node */296296- this_dev->child = kmalloc(sizeof(struct sbus_dev),297297- GFP_ATOMIC);298298- /* Fill it */299299- this_dev->child->bus = sbus;300300- this_dev->child->next = NULL;301301- fill_sbus_device(prom_getchild(sbus_devs),302302- this_dev->child);303303- sbus_do_child_siblings(prom_getchild(sbus_devs),304304- this_dev->child,305305- this_dev,306306- sbus);307307- } else {308308- this_dev->child = NULL;309309- }310310-311311- while((sbus_devs = prom_getsibling(sbus_devs)) != 0) {312312- /* Allocate device node */313313- this_dev->next = kmalloc(sizeof(struct sbus_dev),314314- GFP_ATOMIC);315315- this_dev = this_dev->next;316316- this_dev->next = NULL;317317-318318- /* Fill it */319319- this_dev->bus = sbus;320320- this_dev->parent = NULL;321321- fill_sbus_device(sbus_devs, this_dev);322322-323323- /* Is there a child node hanging off of us? */324324- if(prom_getchild(sbus_devs)) {325325- /* Get new device struct */326326- this_dev->child = kmalloc(sizeof(struct sbus_dev),327327- GFP_ATOMIC);328328- /* Fill it */329329- this_dev->child->bus = sbus;330330- this_dev->child->next = NULL;331331- fill_sbus_device(prom_getchild(sbus_devs),332332- this_dev->child);333333- sbus_do_child_siblings(prom_getchild(sbus_devs),334334- this_dev->child,335335- this_dev,336336- sbus);337337- } else {338338- this_dev->child = NULL;339339- }340340- }341341-342342- /* Walk all devices and apply parent ranges. */343343- sbus_fixup_all_regs(sbus->devices);344344-345345- dvma_init(sbus);346346- next_bus:334334+ for_each_node_by_name(dp, sbus_name) {335335+ build_one_sbus(dp, num_sbus);347336 num_sbus++;348348- if(sparc_cpu_model == sun4u) {349349- this_sbus = prom_getsibling(this_sbus);350350- if(!this_sbus)351351- break;352352- this_sbus = prom_searchsiblings(this_sbus, "sbus");353353- } else if(sparc_cpu_model == sun4d) {354354- iommund = prom_getsibling(iommund);355355- if(!iommund)356356- break;357357- iommund = prom_searchsiblings(iommund, "io-unit");358358- if(!iommund)359359- break;360360- this_sbus = prom_searchsiblings(prom_getchild(iommund), "sbi");361361- } else {362362- this_sbus = prom_getsibling(this_sbus);363363- if(!this_sbus)364364- break;365365- this_sbus = prom_searchsiblings(this_sbus, "sbus");366366- }367367- if(this_sbus) {368368- sbus->next = kmalloc(sizeof(struct sbus_bus), GFP_ATOMIC);369369- sbus = sbus->next;370370- sbus->next = NULL;371371- sbus->prom_node = this_sbus;372372- } else {373373- break;374374- }375375- } /* while(this_sbus) */376337377377- if (sparc_cpu_model == sun4d) {378378- extern void sun4d_init_sbi_irq(void);379379- sun4d_init_sbi_irq();380338 }381381-382382-#ifdef CONFIG_SPARC64383383- if (sparc_cpu_model == sun4u) {384384- firetruck_init();385385- }386386-#endif387387-#ifdef CONFIG_SUN_AUXIO388388- if (sparc_cpu_model == sun4u)389389- auxio_probe ();390390-#endif391391-#ifdef CONFIG_SPARC64392392- if (sparc_cpu_model == sun4u) {393393- extern void clock_probe(void);394339395395- clock_probe();396396- }397397-#endif340340+ sbus_arch_postinit();398341399342 return 0;400343}
+19-8
include/asm-sparc/sbus.h
···1111#include <linux/ioport.h>12121313#include <asm/oplib.h>1414-/* #include <asm/iommu.h> */ /* Unused since we use opaque iommu (|io-unit) */1414+#include <asm/prom.h>1515+#include <asm/of_device.h>1516#include <asm/scatterlist.h>16171718/* We scan which devices are on the SBus using the PROM node device···43424443/* Linux SBUS device tables */4544struct sbus_dev {4646- struct sbus_bus *bus; /* Back ptr to sbus */4747- struct sbus_dev *next; /* next device on this SBus or null */4848- struct sbus_dev *child; /* For ledma and espdma on sun4m */4949- struct sbus_dev *parent; /* Parent device if not toplevel */5050- int prom_node; /* PROM device tree node for this device */5151- char prom_name[64]; /* PROM device name */4545+ struct of_device ofdev;4646+ struct sbus_bus *bus;4747+ struct sbus_dev *next;4848+ struct sbus_dev *child;4949+ struct sbus_dev *parent;5050+ int prom_node; 5151+ char prom_name[64];5252 int slot;53535454 struct resource resource[PROMREG_MAX];55555656 struct linux_prom_registers reg_addrs[PROMREG_MAX];5757- int num_registers, ranges_applied;5757+ int num_registers;58585959 struct linux_prom_ranges device_ranges[PROMREG_MAX];6060 int num_device_ranges;···6361 unsigned int irqs[4];6462 int num_irqs;6563};6464+#define to_sbus_device(d) container_of(d, struct sbus_dev, ofdev.dev)66656766/* This struct describes the SBus(s) found on this machine. */6867struct sbus_bus {6868+ struct of_device ofdev;6969 void *iommu; /* Opaque IOMMU cookie */7070 struct sbus_dev *devices; /* Link to devices on this SBus */7171 struct sbus_bus *next; /* next SBus, if more than one SBus */···8177 int devid;8278 int board;8379};8080+#define to_sbus(d) container_of(d, struct sbus_bus, ofdev.dev)84818582extern struct sbus_bus *sbus_root;8683···144139 */145140BTFIXUPDEF_CALL(unsigned int, sbint_to_irq, struct sbus_dev *sdev, unsigned int)146141#define sbint_to_irq(sdev, sbint) BTFIXUP_CALL(sbint_to_irq)(sdev, sbint)142142+143143+extern void sbus_arch_bus_ranges_init(struct device_node *, struct sbus_bus *);144144+extern void sbus_setup_iommu(struct sbus_bus *, struct device_node *);145145+extern void sbus_setup_arch_props(struct sbus_bus *, struct device_node *);146146+extern int sbus_arch_preinit(void);147147+extern void sbus_arch_postinit(void);147148148149#endif /* !(_SPARC_SBUS_H) */
+20-8
include/asm-sparc64/sbus.h
···1111#include <linux/ioport.h>12121313#include <asm/oplib.h>1414+#include <asm/prom.h>1515+#include <asm/of_device.h>1416#include <asm/iommu.h>1517#include <asm/scatterlist.h>1618···44424543/* Linux SBUS device tables */4644struct sbus_dev {4747- struct sbus_bus *bus; /* Our toplevel parent SBUS */4848- struct sbus_dev *next; /* Chain of siblings */4949- struct sbus_dev *child; /* Chain of children */5050- struct sbus_dev *parent;/* Parent device if not toplevel*/5151- int prom_node; /* OBP node of this device */5252- char prom_name[64]; /* OBP device name property */5353- int slot; /* SBUS slot number */4545+ struct of_device ofdev;4646+ struct sbus_bus *bus;4747+ struct sbus_dev *next;4848+ struct sbus_dev *child;4949+ struct sbus_dev *parent;5050+ int prom_node; 5151+ char prom_name[64];5252+ int slot;54535554 struct resource resource[PROMREG_MAX];56555756 struct linux_prom_registers reg_addrs[PROMREG_MAX];5858- int num_registers, ranges_applied;5757+ int num_registers;59586059 struct linux_prom_ranges device_ranges[PROMREG_MAX];6160 int num_device_ranges;···6461 unsigned int irqs[4];6562 int num_irqs;6663};6464+#define to_sbus_device(d) container_of(d, struct sbus_dev, ofdev.dev)67656866/* This struct describes the SBus(s) found on this machine. */6967struct sbus_bus {6868+ struct of_device ofdev;7069 void *iommu; /* Opaque IOMMU cookie */7170 struct sbus_dev *devices; /* Tree of SBUS devices */7271 struct sbus_bus *next; /* Next SBUS in system */···8277 int portid;8378 void *starfire_cookie;8479};8080+#define to_sbus(d) container_of(d, struct sbus_bus, ofdev.dev)85818682extern struct sbus_bus *sbus_root;8783···125119extern void sbus_dma_sync_sg_for_cpu(struct sbus_dev *, struct scatterlist *, int, int);126120#define sbus_dma_sync_sg sbus_dma_sync_sg_for_cpu127121extern void sbus_dma_sync_sg_for_device(struct sbus_dev *, struct scatterlist *, int, int);122122+123123+extern void sbus_arch_bus_ranges_init(struct device_node *, struct sbus_bus *);124124+extern void sbus_setup_iommu(struct sbus_bus *, struct device_node *);125125+extern void sbus_setup_arch_props(struct sbus_bus *, struct device_node *);126126+extern int sbus_arch_preinit(void);127127+extern void sbus_arch_postinit(void);128128129129#endif /* !(_SPARC64_SBUS_H) */