Exemple #1
0
int init_vfc_device(struct sbus_dev *sdev,struct vfc_dev *dev, int instance)
{
	char devname[8];

	if(dev == NULL) {
		printk(KERN_ERR "VFC: Bogus pointer passed\n");
		return -ENOMEM;
	}
	printk("Initializing vfc%d\n",instance);
	dev->regs = NULL;
	dev->regs = (volatile struct vfc_regs *)
		sbus_ioremap(&sdev->resource[0], 0,
			     sizeof(struct vfc_regs), vfcstr);
	dev->which_io = sdev->reg_addrs[0].which_io;
	dev->phys_regs = (struct vfc_regs *) sdev->reg_addrs[0].phys_addr;
	if (dev->regs == NULL)
		return -EIO;

	printk("vfc%d: registers mapped at phys_addr: 0x%lx\n    virt_addr: 0x%lx\n",
	       instance,(unsigned long)sdev->reg_addrs[0].phys_addr,(unsigned long)dev->regs);

	if (init_vfc_devstruct(dev, instance))
		return -EINVAL;
	if (init_vfc_hw(dev))
		return -EIO;

	sprintf (devname, "%d", instance);
	dev->de = devfs_register (devfs_handle, devname, DEVFS_FL_DEFAULT,
				  VFC_MAJOR, instance,
				  S_IFCHR | S_IRUSR | S_IWUSR,
				  &vfc_fops, NULL);
	return 0;
}
Exemple #2
0
int init_vfc_device(struct sbus_dev *sdev,struct vfc_dev *dev, int instance)
{
	if(dev == NULL) {
		printk(KERN_ERR "VFC: Bogus pointer passed\n");
		return -ENOMEM;
	}
	printk("Initializing vfc%d\n",instance);
	dev->regs = NULL;
	dev->regs = (volatile struct vfc_regs __iomem *)
		sbus_ioremap(&sdev->resource[0], 0,
			     sizeof(struct vfc_regs), vfcstr);
	dev->which_io = sdev->reg_addrs[0].which_io;
	dev->phys_regs = (struct vfc_regs *) sdev->reg_addrs[0].phys_addr;
	if (dev->regs == NULL)
		return -EIO;

	printk("vfc%d: registers mapped at phys_addr: 0x%lx\n    virt_addr: 0x%lx\n",
	       instance,(unsigned long)sdev->reg_addrs[0].phys_addr,(unsigned long)dev->regs);

	if (init_vfc_devstruct(dev, instance))
		return -EINVAL;
	if (init_vfc_hw(dev))
		return -EIO;
	return 0;
}
Exemple #3
0
void __init auxio_power_probe(void)
{
	struct linux_prom_registers regs;
	int node;
	struct resource r;

	/* Attempt to find the sun4m power control node. */
	node = prom_getchild(prom_root_node);
	node = prom_searchsiblings(node, "obio");
	node = prom_getchild(node);
	node = prom_searchsiblings(node, "power");
	if (node == 0 || node == -1)
		return;

	/* Map the power control register. */
	if (prom_getproperty(node, "reg", (char *)&regs, sizeof(regs)) <= 0)
		return;
	prom_apply_obio_ranges(&regs, 1);
	memset(&r, 0, sizeof(r));
	r.flags = regs.which_io & 0xF;
	r.start = regs.phys_addr;
	r.end = regs.phys_addr + regs.reg_size - 1;
	auxio_power_register = (unsigned char *) sbus_ioremap(&r, 0,
	    regs.reg_size, "auxpower");

	/* Display a quick message on the console. */
	if (auxio_power_register)
		printk(KERN_INFO "Power off control detected.\n");
}
Exemple #4
0
static int __devinit bw2_init_one(struct of_device *op)
{
	struct device_node *dp = op->node;
	struct all_info *all;
	int linebytes, err;

	all = kzalloc(sizeof(*all), GFP_KERNEL);
	if (!all)
		return -ENOMEM;

	spin_lock_init(&all->par.lock);

	all->par.physbase = op->resource[0].start;
	all->par.which_io = op->resource[0].flags & IORESOURCE_BITS;

	sbusfb_fill_var(&all->info.var, dp->node, 1);
	linebytes = of_getintprop_default(dp, "linebytes",
					  all->info.var.xres);

	all->info.var.red.length = all->info.var.green.length =
		all->info.var.blue.length = all->info.var.bits_per_pixel;
	all->info.var.red.offset = all->info.var.green.offset =
		all->info.var.blue.offset = 0;

	all->par.regs = of_ioremap(&op->resource[0], BWTWO_REGISTER_OFFSET,
				   sizeof(struct bw2_regs), "bw2 regs");

	if (!of_find_property(dp, "width", NULL))
		bw2_do_default_mode(&all->par, &all->info, &linebytes);

	all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres);

	all->info.flags = FBINFO_DEFAULT;
	all->info.fbops = &bw2_ops;

	all->info.screen_base =
		sbus_ioremap(&op->resource[0], 0, all->par.fbsize, "bw2 ram");
	all->info.par = &all->par;

	bw2_blank(0, &all->info);

	bw2_init_fix(&all->info, linebytes);

	err= register_framebuffer(&all->info);
	if (err < 0) {
		of_iounmap(all->par.regs, sizeof(struct bw2_regs));
		of_iounmap(all->info.screen_base, all->par.fbsize);
		kfree(all);
		return err;
	}

	dev_set_drvdata(&op->dev, all);

	printk("%s: bwtwo at %lx:%lx\n",
	       dp->full_name,
	       all->par.which_io, all->par.physbase);

	return 0;
}
Exemple #5
0
/* Probe for the real time clock chip on Sun4 */
static __inline__ void sun4_clock_probe(void)
{
#ifdef CONFIG_SUN4
	int temp;
	struct resource r;

	memset(&r, 0, sizeof(r));
	if( idprom->id_machtype == (SM_SUN4 | SM_4_330) ) {
		sp_clock_typ = MSTK48T02;
		r.start = sun4_clock_physaddr;
		mstk48t02_regs = sbus_ioremap(&r, 0,
				       sizeof(struct mostek48t02), NULL);
		mstk48t08_regs = NULL;  /* To catch weirdness */
		intersil_clock = NULL;  /* just in case */

		/* Kick start the clock if it is completely stopped. */
		if (mostek_read(mstk48t02_regs + MOSTEK_SEC) & MSTK_STOP)
			kick_start_clock();
	} else if( idprom->id_machtype == (SM_SUN4 | SM_4_260)) {
		/* intersil setup code */
		printk("Clock: INTERSIL at %8x ",sun4_clock_physaddr);
		sp_clock_typ = INTERSIL;
		r.start = sun4_clock_physaddr;
		intersil_clock = (struct intersil *) 
		    sbus_ioremap(&r, 0, sizeof(*intersil_clock), "intersil");
		mstk48t02_regs = 0;  /* just be sure */
		mstk48t08_regs = NULL;  /* ditto */
		/* initialise the clock */

		intersil_intr(intersil_clock,INTERSIL_INT_100HZ);

		intersil_start(intersil_clock);

		intersil_read_intr(intersil_clock, temp);
                while (!(temp & 0x80))
                        intersil_read_intr(intersil_clock, temp);

                intersil_read_intr(intersil_clock, temp);
                while (!(temp & 0x80))
                        intersil_read_intr(intersil_clock, temp);

		intersil_stop(intersil_clock);

	}
#endif
}
Exemple #6
0
void __init auxio_probe(void)
{
	int node, auxio_nd;
	struct linux_prom_registers auxregs[1];
	struct resource r;

	switch (sparc_cpu_model) {
	case sun4d:
	case sun4:
		auxio_register = 0;
		return;
	default:
		break;
	}
	node = prom_getchild(prom_root_node);
	auxio_nd = prom_searchsiblings(node, "auxiliary-io");
	if(!auxio_nd) {
		node = prom_searchsiblings(node, "obio");
		node = prom_getchild(node);
		auxio_nd = prom_searchsiblings(node, "auxio");
		if(!auxio_nd) {
#ifdef CONFIG_PCI
			/* There may be auxio on Ebus */
			auxio_register = 0;
			return;
#else
			if(prom_searchsiblings(node, "leds")) {
				/* VME chassis sun4m machine, no auxio exists. */
				auxio_register = 0;
				return;
			}
			prom_printf("Cannot find auxio node, cannot continue...\n");
			prom_halt();
#endif
		}
	}
	prom_getproperty(auxio_nd, "reg", (char *) auxregs, sizeof(auxregs));
	prom_apply_obio_ranges(auxregs, 0x1);
	/* Map the register both read and write */
	r.flags = auxregs[0].which_io & 0xF;
	r.start = auxregs[0].phys_addr;
	r.end = auxregs[0].phys_addr + auxregs[0].reg_size - 1;
	auxio_register = (unsigned char *) sbus_ioremap(&r, 0,
	    auxregs[0].reg_size, "auxio");
	/* Fix the address on sun4m and sun4c. */
	if((((unsigned long) auxregs[0].phys_addr) & 3) == 3 ||
	   sparc_cpu_model == sun4c)
		auxio_register = (unsigned char *) ((int)auxio_register | 3);

	TURN_ON_LED;
}
Exemple #7
0
void __init auxio_probe(void)
{
        struct sbus_bus *sbus;
        struct sbus_dev *sdev = 0;

        for_each_sbus(sbus) {
                for_each_sbusdev(sdev, sbus) {
                        if(!strcmp(sdev->prom_name, "auxio"))
				goto found_sdev;
                }
        }

found_sdev:
	if (!sdev) {
#ifdef CONFIG_PCI
		struct linux_ebus *ebus;
		struct linux_ebus_device *edev = 0;
		unsigned long led_auxio;

		for_each_ebus(ebus) {
			for_each_ebusdev(edev, ebus) {
				if (!strcmp(edev->prom_name, "auxio"))
					goto ebus_done;
			}
		}
	ebus_done:

		if (edev) {
			led_auxio = edev->resource[0].start;
			outl(0x01, led_auxio);
			return;
		}
#endif
		if(central_bus || this_is_starfire) {
			auxio_register = 0UL;
			return;
		}
		prom_printf("Cannot find auxio node, cannot continue...\n");
		prom_halt();
	}

	/* Map the register both read and write */
	auxio_register = sbus_ioremap(&sdev->resource[0], 0,
				      sdev->reg_addrs[0].reg_size, "auxiliaryIO");
	TURN_ON_LED;
}
Exemple #8
0
void __init sun4c_init_IRQ(void)
{
	struct linux_prom_registers int_regs[2];
	int ie_node;

	if (ARCH_SUN4) {
		interrupt_enable = (char *)
		    ioremap(sun4_ie_physaddr, PAGE_SIZE);
	} else {
		struct resource phyres;

		ie_node = prom_searchsiblings (prom_getchild(prom_root_node),
				       	"interrupt-enable");
		if(ie_node == 0)
			panic("Cannot find /interrupt-enable node");

		/* Depending on the "address" property is bad news... */
		prom_getproperty(ie_node, "reg", (char *) int_regs, sizeof(int_regs));
		memset(&phyres, 0, sizeof(struct resource));
		phyres.flags = int_regs[0].which_io;
		phyres.start = int_regs[0].phys_addr;
		interrupt_enable = (char *) sbus_ioremap(&phyres, 0,
		    int_regs[0].reg_size, "sun4c_intr");
	}

	BTFIXUPSET_CALL(sbint_to_irq, sun4c_sbint_to_irq, BTFIXUPCALL_NORM);
	BTFIXUPSET_CALL(enable_irq, sun4c_enable_irq, BTFIXUPCALL_NORM);
	BTFIXUPSET_CALL(disable_irq, sun4c_disable_irq, BTFIXUPCALL_NORM);
	BTFIXUPSET_CALL(enable_pil_irq, sun4c_enable_irq, BTFIXUPCALL_NORM);
	BTFIXUPSET_CALL(disable_pil_irq, sun4c_disable_irq, BTFIXUPCALL_NORM);
	BTFIXUPSET_CALL(clear_clock_irq, sun4c_clear_clock_irq, BTFIXUPCALL_NORM);
	BTFIXUPSET_CALL(clear_profile_irq, sun4c_clear_profile_irq, BTFIXUPCALL_NOP);
	BTFIXUPSET_CALL(load_profile_irq, sun4c_load_profile_irq, BTFIXUPCALL_NOP);
	BTFIXUPSET_CALL(__irq_itoa, sun4m_irq_itoa, BTFIXUPCALL_NORM);
	sparc_init_timers = sun4c_init_timers;
#ifdef CONFIG_SMP
	BTFIXUPSET_CALL(set_cpu_int, sun4c_nop, BTFIXUPCALL_NOP);
	BTFIXUPSET_CALL(clear_cpu_int, sun4c_nop, BTFIXUPCALL_NOP);
	BTFIXUPSET_CALL(set_irq_udt, sun4c_nop, BTFIXUPCALL_NOP);
#endif
	*interrupt_enable = (SUN4C_INT_ENABLE);
	/* Cannot enable interrupts until OBP ticker is disabled. */
}
Exemple #9
0
/* Probe this SBus DMA module(s) */
void __init dvma_init(struct sbus_bus *sbus)
{
	struct sbus_dev *this_dev;
	struct sbus_dma *dma;
	struct sbus_dma *dchain;
	static int num_dma = 0;

	for_each_sbusdev(this_dev, sbus) {
		char *name = this_dev->prom_name;
		int hme = 0;

		if(!strcmp(name, "SUNW,fas"))
			hme = 1;
		else if(strcmp(name, "dma") &&
			strcmp(name, "ledma") &&
			strcmp(name, "espdma"))
			continue;

		/* Found one... */
		dma = kmalloc(sizeof(struct sbus_dma), GFP_ATOMIC);

		dma->sdev = this_dev;

		/* Put at end of dma chain */
		dchain = dma_chain;
		if(dchain) {
			while(dchain->next)
				dchain = dchain->next;
			dchain->next = dma;
		} else {
			/* We're the first in line */
			dma_chain = dma;
		}

		dma->regs = sbus_ioremap(&dma->sdev->resource[0], 0,
					 dma->sdev->resource[0].end - dma->sdev->resource[0].start + 1,
					 "dma");

		dma->node = dma->sdev->prom_node;
		
		init_one_dvma(dma, num_dma++);
	}
Exemple #10
0
static int __init apc_probe(void)
{
	struct sbus_bus *sbus = NULL;
	struct sbus_dev *sdev = NULL;
	int iTmp = 0;

	for_each_sbus(sbus) {
		for_each_sbusdev(sdev, sbus) {
			if (!strcmp(sdev->prom_name, APC_OBPNAME)) {
				goto sbus_done;
			}
		}
	}

sbus_done:
	if (!sdev) {
		return -ENODEV;
	}

	apc_regsize = sdev->reg_addrs[0].reg_size;
	regs = sbus_ioremap(&sdev->resource[0], 0, 
				   apc_regsize, APC_OBPNAME);
	if(!regs) {
		printk(KERN_ERR "%s: unable to map registers\n", APC_DEVNAME);
		return -ENODEV;
	}

	iTmp = misc_register(&apc_miscdev);
	if (iTmp != 0) {
		printk(KERN_ERR "%s: unable to register device\n", APC_DEVNAME);
		apc_free();
		return -ENODEV;
	}

	/* Assign power management IDLE handler */
	if(!apc_no_idle)
		pm_idle = apc_swift_idle;	

	printk(KERN_INFO "%s: power management initialized%s\n", 
		APC_DEVNAME, apc_no_idle ? " (CPU idle disabled)" : "");
	return 0;
}
Exemple #11
0
void __init auxio_probe(void)
{
        struct sbus_bus *sbus;
        struct sbus_dev *sdev = NULL;

        for_each_sbus(sbus) {
                for_each_sbusdev(sdev, sbus) {
                        if(!strcmp(sdev->prom_name, "auxio"))
				goto found_sdev;
                }
        }

found_sdev:
	if (sdev) {
		auxio_devtype  = AUXIO_TYPE_SBUS;
		auxio_register = sbus_ioremap(&sdev->resource[0], 0,
					      sdev->reg_addrs[0].reg_size,
					      "auxiliaryIO");
	}
#ifdef CONFIG_PCI
	else {
		struct linux_ebus *ebus;
		struct linux_ebus_device *edev = NULL;

		for_each_ebus(ebus) {
			for_each_ebusdev(edev, ebus) {
				if (!strcmp(edev->prom_name, "auxio"))
					goto ebus_done;
			}
		}
	ebus_done:
		if (edev) {
			auxio_devtype  = AUXIO_TYPE_EBUS;
			auxio_register =
				ioremap(edev->resource[0].start, sizeof(u32));
		}
	}
	auxio_set_led(AUXIO_LED_ON);
#endif
}
Exemple #12
0
void __init
iommu_init(int iommund, struct sbus_bus *sbus)
{
	unsigned int impl, vers;
	unsigned long tmp;
	struct iommu_struct *iommu;
	struct linux_prom_registers iommu_promregs[PROMREG_MAX];
	struct resource r;
	unsigned long *bitmap;

	iommu = kmalloc(sizeof(struct iommu_struct), GFP_ATOMIC);
	if (!iommu) {
		prom_printf("Unable to allocate iommu structure\n");
		prom_halt();
	}
	prom_getproperty(iommund, "reg", (void *) iommu_promregs,
			 sizeof(iommu_promregs));
	memset(&r, 0, sizeof(r));
	r.flags = iommu_promregs[0].which_io;
	r.start = iommu_promregs[0].phys_addr;
	iommu->regs = (struct iommu_regs *)
		sbus_ioremap(&r, 0, PAGE_SIZE * 3, "iommu_regs");
	if(!iommu->regs) {
		prom_printf("Cannot map IOMMU registers\n");
		prom_halt();
	}
	impl = (iommu->regs->control & IOMMU_CTRL_IMPL) >> 28;
	vers = (iommu->regs->control & IOMMU_CTRL_VERS) >> 24;
	tmp = iommu->regs->control;
	tmp &= ~(IOMMU_CTRL_RNGE);
	tmp |= (IOMMU_RNGE_256MB | IOMMU_CTRL_ENAB);
	iommu->regs->control = tmp;
	iommu_invalidate(iommu->regs);
	iommu->start = IOMMU_START;
	iommu->end = 0xffffffff;

	/* Allocate IOMMU page table */
	/* Stupid alignment constraints give me a headache. 
	   We need 256K or 512K or 1M or 2M area aligned to
           its size and current gfp will fortunately give
           it to us. */
        tmp = __get_free_pages(GFP_KERNEL, IOMMU_ORDER);
	if (!tmp) {
		prom_printf("Unable to allocate iommu table [0x%08x]\n",
			    IOMMU_NPTES*sizeof(iopte_t));
		prom_halt();
	}
	iommu->page_table = (iopte_t *)tmp;

	/* Initialize new table. */
	memset(iommu->page_table, 0, IOMMU_NPTES*sizeof(iopte_t));
	flush_cache_all();
	flush_tlb_all();
	iommu->regs->base = __pa((unsigned long) iommu->page_table) >> 4;
	iommu_invalidate(iommu->regs);

	bitmap = kmalloc(IOMMU_NPTES>>3, GFP_KERNEL);
	if (!bitmap) {
		prom_printf("Unable to allocate iommu bitmap [%d]\n",
			    (int)(IOMMU_NPTES>>3));
		prom_halt();
	}
Exemple #13
0
void __init sun4m_init_IRQ(void)
{
	int ie_node,i;
	struct linux_prom_registers int_regs[PROMREG_MAX];
	int num_regs;
	struct resource r;
	int mid;
    
	local_irq_disable();
	if((ie_node = prom_searchsiblings(prom_getchild(prom_root_node), "obio")) == 0 ||
	   (ie_node = prom_getchild (ie_node)) == 0 ||
	   (ie_node = prom_searchsiblings (ie_node, "interrupt")) == 0) {
		prom_printf("Cannot find /obio/interrupt node\n");
		prom_halt();
	}
	num_regs = prom_getproperty(ie_node, "reg", (char *) int_regs,
				    sizeof(int_regs));
	num_regs = (num_regs/sizeof(struct linux_prom_registers));
    
	/* Apply the obio ranges to these registers. */
	prom_apply_obio_ranges(int_regs, num_regs);
    
	int_regs[4].phys_addr = int_regs[num_regs-1].phys_addr;
	int_regs[4].reg_size = int_regs[num_regs-1].reg_size;
	int_regs[4].which_io = int_regs[num_regs-1].which_io;
	for(ie_node = 1; ie_node < 4; ie_node++) {
		int_regs[ie_node].phys_addr = int_regs[ie_node-1].phys_addr + PAGE_SIZE;
		int_regs[ie_node].reg_size = int_regs[ie_node-1].reg_size;
		int_regs[ie_node].which_io = int_regs[ie_node-1].which_io;
	}

	memset((char *)&r, 0, sizeof(struct resource));
	/* Map the interrupt registers for all possible cpus. */
	r.flags = int_regs[0].which_io;
	r.start = int_regs[0].phys_addr;
	sun4m_interrupts = (struct sun4m_intregs *) sbus_ioremap(&r, 0,
	    PAGE_SIZE*SUN4M_NCPUS, "interrupts_percpu");

	/* Map the system interrupt control registers. */
	r.flags = int_regs[4].which_io;
	r.start = int_regs[4].phys_addr;
	sbus_ioremap(&r, 0, int_regs[4].reg_size, "interrupts_system");

	sun4m_interrupts->set = ~SUN4M_INT_MASKALL;
	for (i = 0; !cpu_find_by_instance(i, NULL, &mid); i++)
		sun4m_interrupts->cpu_intregs[mid].clear = ~0x17fff;

	if (!cpu_find_by_instance(1, NULL, NULL)) {
		/* system wide interrupts go to cpu 0, this should always
		 * be safe because it is guaranteed to be fitted or OBP doesn't
		 * come up
		 *
		 * Not sure, but writing here on SLAVIO systems may puke
		 * so I don't do it unless there is more than 1 cpu.
		 */
		irq_rcvreg = (unsigned long *)
				&sun4m_interrupts->undirected_target;
		sun4m_interrupts->undirected_target = 0;
	}
	BTFIXUPSET_CALL(sbint_to_irq, sun4m_sbint_to_irq, BTFIXUPCALL_NORM);
	BTFIXUPSET_CALL(enable_irq, sun4m_enable_irq, BTFIXUPCALL_NORM);
	BTFIXUPSET_CALL(disable_irq, sun4m_disable_irq, BTFIXUPCALL_NORM);
	BTFIXUPSET_CALL(enable_pil_irq, sun4m_enable_pil_irq, BTFIXUPCALL_NORM);
	BTFIXUPSET_CALL(disable_pil_irq, sun4m_disable_pil_irq, BTFIXUPCALL_NORM);
	BTFIXUPSET_CALL(clear_clock_irq, sun4m_clear_clock_irq, BTFIXUPCALL_NORM);
	BTFIXUPSET_CALL(clear_profile_irq, sun4m_clear_profile_irq, BTFIXUPCALL_NORM);
	BTFIXUPSET_CALL(load_profile_irq, sun4m_load_profile_irq, BTFIXUPCALL_NORM);
	sparc_init_timers = sun4m_init_timers;
#ifdef CONFIG_SMP
	BTFIXUPSET_CALL(set_cpu_int, sun4m_send_ipi, BTFIXUPCALL_NORM);
	BTFIXUPSET_CALL(clear_cpu_int, sun4m_clear_ipi, BTFIXUPCALL_NORM);
	BTFIXUPSET_CALL(set_irq_udt, sun4m_set_udt, BTFIXUPCALL_NORM);
#endif
	/* Cannot enable interrupts until OBP ticker is disabled. */
}
Exemple #14
0
static void __init sun4m_init_timers(irqreturn_t (*counter_fn)(int, void *, struct pt_regs *))
{
	int reg_count, irq, cpu;
	struct linux_prom_registers cnt_regs[PROMREG_MAX];
	int obio_node, cnt_node;
	struct resource r;

	cnt_node = 0;
	if((obio_node =
	    prom_searchsiblings (prom_getchild(prom_root_node), "obio")) == 0 ||
	   (obio_node = prom_getchild (obio_node)) == 0 ||
	   (cnt_node = prom_searchsiblings (obio_node, "counter")) == 0) {
		prom_printf("Cannot find /obio/counter node\n");
		prom_halt();
	}
	reg_count = prom_getproperty(cnt_node, "reg",
				     (void *) cnt_regs, sizeof(cnt_regs));
	reg_count = (reg_count/sizeof(struct linux_prom_registers));
    
	/* Apply the obio ranges to the timer registers. */
	prom_apply_obio_ranges(cnt_regs, reg_count);
    
	cnt_regs[4].phys_addr = cnt_regs[reg_count-1].phys_addr;
	cnt_regs[4].reg_size = cnt_regs[reg_count-1].reg_size;
	cnt_regs[4].which_io = cnt_regs[reg_count-1].which_io;
	for(obio_node = 1; obio_node < 4; obio_node++) {
		cnt_regs[obio_node].phys_addr =
			cnt_regs[obio_node-1].phys_addr + PAGE_SIZE;
		cnt_regs[obio_node].reg_size = cnt_regs[obio_node-1].reg_size;
		cnt_regs[obio_node].which_io = cnt_regs[obio_node-1].which_io;
	}

	memset((char*)&r, 0, sizeof(struct resource));
	/* Map the per-cpu Counter registers. */
	r.flags = cnt_regs[0].which_io;
	r.start = cnt_regs[0].phys_addr;
	sun4m_timers = (struct sun4m_timer_regs *) sbus_ioremap(&r, 0,
	    PAGE_SIZE*SUN4M_NCPUS, "sun4m_cpu_cnt");
	/* Map the system Counter register. */
	/* XXX Here we expect consequent calls to yeld adjusent maps. */
	r.flags = cnt_regs[4].which_io;
	r.start = cnt_regs[4].phys_addr;
	sbus_ioremap(&r, 0, cnt_regs[4].reg_size, "sun4m_sys_cnt");

	sun4m_timers->l10_timer_limit =  (((1000000/HZ) + 1) << 10);
	master_l10_counter = &sun4m_timers->l10_cur_count;
	master_l10_limit = &sun4m_timers->l10_timer_limit;

	irq = request_irq(TIMER_IRQ,
			  counter_fn,
			  (IRQF_DISABLED | SA_STATIC_ALLOC),
			  "timer", NULL);
	if (irq) {
		prom_printf("time_init: unable to attach IRQ%d\n",TIMER_IRQ);
		prom_halt();
	}
   
	if (!cpu_find_by_instance(1, NULL, NULL)) {
		for(cpu = 0; cpu < 4; cpu++)
			sun4m_timers->cpu_timers[cpu].l14_timer_limit = 0;
		sun4m_interrupts->set = SUN4M_INT_E14;
	} else {
		sun4m_timers->cpu_timers[0].l14_timer_limit = 0;
	}
#ifdef CONFIG_SMP
	{
		unsigned long flags;
		extern unsigned long lvl14_save[4];
		struct tt_entry *trap_table = &sparc_ttable[SP_TRAP_IRQ1 + (14 - 1)];

		/* For SMP we use the level 14 ticker, however the bootup code
		 * has copied the firmwares level 14 vector into boot cpu's
		 * trap table, we must fix this now or we get squashed.
		 */
		local_irq_save(flags);
		trap_table->inst_one = lvl14_save[0];
		trap_table->inst_two = lvl14_save[1];
		trap_table->inst_three = lvl14_save[2];
		trap_table->inst_four = lvl14_save[3];
		local_flush_cache_all();
		local_irq_restore(flags);
	}
#endif
}
Exemple #15
0
char __init *cgthreefb_init(struct fb_info_sbusfb *fb)
{
    struct fb_fix_screeninfo *fix = &fb->fix;
    struct display *disp = &fb->disp;
    struct fbtype *type = &fb->type;
    struct sbus_dev *sdev = fb->sbdp;
    unsigned long phys = sdev->reg_addrs[0].phys_addr;
    int cgRDI = strstr(fb->sbdp->prom_name, "cgRDI") != NULL;

#ifndef FBCON_HAS_CFB8
    return NULL;
#endif

    if (!fb->s.cg3.regs) {
        fb->s.cg3.regs = (struct cg3_regs *)
                         sbus_ioremap(&sdev->resource[0], CG3_REGS_OFFSET,
                                      sizeof(struct cg3_regs), "cg3 regs");
        if (cgRDI) {
            char buffer[40];
            char *p;
            int ww, hh;

            *buffer = 0;
            prom_getstring (fb->prom_node, "params", buffer, sizeof(buffer));
            if (*buffer) {
                ww = simple_strtoul (buffer, &p, 10);
                if (ww && *p == 'x') {
                    hh = simple_strtoul (p + 1, &p, 10);
                    if (hh && *p == '-') {
                        if (type->fb_width != ww || type->fb_height != hh) {
                            type->fb_width = ww;
                            type->fb_height = hh;
                            return SBUSFBINIT_SIZECHANGE;
                        }
                    }
                }
            }
        }
    }

    strcpy(fb->info.modename, "CGthree");
    strcpy(fix->id, "CGthree");
    fix->line_length = fb->var.xres_virtual;
    fix->accel = FB_ACCEL_SUN_CGTHREE;

    disp->scrollmode = SCROLL_YREDRAW;
    if (!disp->screen_base) {
        disp->screen_base = (char *)
                            sbus_ioremap(&sdev->resource[0], CG3_RAM_OFFSET,
                                         type->fb_size, "cg3 ram");
    }
    disp->screen_base += fix->line_length * fb->y_margin + fb->x_margin;
    fb->dispsw = fbcon_cfb8;

    fb->margins = cg3_margins;
    fb->loadcmap = cg3_loadcmap;
    fb->blank = cg3_blank;
    fb->unblank = cg3_unblank;

    fb->physbase = phys;
    fb->mmap_map = cg3_mmap_map;

#ifdef __sparc_v9__
    sprintf(idstring, "%s at %016lx", cgRDI ? "cgRDI" : "cgthree", phys);
#else
    sprintf(idstring, "%s at %x.%08lx", cgRDI ? "cgRDI" : "cgthree", fb->iospace, phys);
#endif

    if (!prom_getbool(fb->prom_node, "width")) {
        /* Ugh, broken PROM didn't initialize us.
         * Let's deal with this ourselves.
         */
        enum cg3_type type;
        u8 *p;

        if (cgRDI)
            type = CG3_RDI;
        else {
            u8 status = sbus_readb(&fb->s.cg3.regs->status), mon;
            if ((status & CG3_SR_ID_MASK) == CG3_SR_ID_COLOR) {
                mon = status & CG3_SR_RES_MASK;
                if (mon == CG3_SR_1152_900_76_A ||
                        mon == CG3_SR_1152_900_76_B)
                    type = CG3_AT_76HZ;
                else
                    type = CG3_AT_66HZ;
            } else {
                prom_printf("cgthree: can't handle SR %02x\n",
                            status);
                prom_halt();
                return NULL; /* fool gcc. */
            }
        }

        for (p = cg3_regvals[type]; *p; p += 2) {
            u8 *regp = &((u8 *)fb->s.cg3.regs)[p[0]];
            sbus_writeb(p[1], regp);
        }
        for (p = cg3_dacvals; *p; p += 2) {
            volatile u8 *regp;

            regp = (volatile u8 *)&fb->s.cg3.regs->cmap.addr;
            sbus_writeb(p[0], regp);
            regp = (volatile u8 *)&fb->s.cg3.regs->cmap.control;
            sbus_writeb(p[1], regp);
        }
    }

    return idstring;
}
Exemple #16
0
static void __iomem *map_bpp(struct sbus_dev *dev, int idx)
{
      return sbus_ioremap(&dev->resource[0], 0, BPP_SIZE, "bpp");
}
Exemple #17
0
/* Probe for the mostek real time clock chip. */
static __inline__ void clock_probe(void)
{
	struct linux_prom_registers clk_reg[2];
	char model[128];
	register int node, cpuunit, bootbus;
	struct resource r;

	cpuunit = bootbus = 0;
	memset(&r, 0, sizeof(r));

	/* Determine the correct starting PROM node for the probe. */
	node = prom_getchild(prom_root_node);
	switch (sparc_cpu_model) {
	case sun4c:
		break;
	case sun4m:
		node = prom_getchild(prom_searchsiblings(node, "obio"));
		break;
	case sun4d:
		node = prom_getchild(bootbus = prom_searchsiblings(prom_getchild(cpuunit = prom_searchsiblings(node, "cpu-unit")), "bootbus"));
		break;
	default:
		prom_printf("CLOCK: Unsupported architecture!\n");
		prom_halt();
	}

	/* Find the PROM node describing the real time clock. */
	sp_clock_typ = MSTK_INVALID;
	node = prom_searchsiblings(node,"eeprom");
	if (!node) {
		prom_printf("CLOCK: No clock found!\n");
		prom_halt();
	}

	/* Get the model name and setup everything up. */
	model[0] = '\0';
	prom_getstring(node, "model", model, sizeof(model));
	if (strcmp(model, "mk48t02") == 0) {
		sp_clock_typ = MSTK48T02;
		if (prom_getproperty(node, "reg", (char *) clk_reg, sizeof(clk_reg)) == -1) {
			prom_printf("clock_probe: FAILED!\n");
			prom_halt();
		}
		if (sparc_cpu_model == sun4d)
			prom_apply_generic_ranges (bootbus, cpuunit, clk_reg, 1);
		else
			prom_apply_obio_ranges(clk_reg, 1);
		/* Map the clock register io area read-only */
		r.flags = clk_reg[0].which_io;
		r.start = clk_reg[0].phys_addr;
		mstk48t02_regs = sbus_ioremap(&r, 0,
		    sizeof(struct mostek48t02), "mk48t02");
		mstk48t08_regs = NULL;  /* To catch weirdness */
	} else if (strcmp(model, "mk48t08") == 0) {
		sp_clock_typ = MSTK48T08;
		if(prom_getproperty(node, "reg", (char *) clk_reg,
				    sizeof(clk_reg)) == -1) {
			prom_printf("clock_probe: FAILED!\n");
			prom_halt();
		}
		if (sparc_cpu_model == sun4d)
			prom_apply_generic_ranges (bootbus, cpuunit, clk_reg, 1);
		else
			prom_apply_obio_ranges(clk_reg, 1);
		/* Map the clock register io area read-only */
		/* XXX r/o attribute is somewhere in r.flags */
		r.flags = clk_reg[0].which_io;
		r.start = clk_reg[0].phys_addr;
		mstk48t08_regs = (struct mostek48t08 *) sbus_ioremap(&r, 0,
		    sizeof(struct mostek48t08), "mk48t08");

		mstk48t02_regs = &mstk48t08_regs->regs;
	} else {
		prom_printf("CLOCK: Unknown model name '%s'\n",model);
		prom_halt();
	}

	/* Report a low battery voltage condition. */
	if (has_low_battery())
		printk(KERN_CRIT "NVRAM: Low battery voltage!\n");

	/* Kick start the clock if it is completely stopped. */
	if (mostek_read(mstk48t02_regs + MOSTEK_SEC) & MSTK_STOP)
		kick_start_clock();
}
char * __init leofb_init(struct fb_info_sbusfb *fb)
{
	struct fb_fix_screeninfo *fix = &fb->fix;
	struct fb_var_screeninfo *var = &fb->var;
	struct display *disp = &fb->disp;
	struct fbtype *type = &fb->type;
	struct sbus_dev *sdev = fb->sbdp;
	unsigned long phys = sdev->reg_addrs[0].phys_addr;
	struct fb_wid_item wi;
	struct fb_wid_list wl;
	int i;
	register struct leo_lc_ss0_usr *us;
	register struct leo_ld *ss;
	struct fb_ops *fbops;
	u32 tmp;

	strcpy(fb->info.modename, "Leo");
		
	strcpy(fix->id, "Leo");
	fix->visual = FB_VISUAL_TRUECOLOR;
	fix->line_length = 8192;
	fix->accel = FB_ACCEL_SUN_LEO;
	
	var->bits_per_pixel = 32;
	var->green.offset = 8;
	var->blue.offset = 16;
	var->accel_flags = FB_ACCELF_TEXT;
	
	fbops = kmalloc(sizeof(*fbops), GFP_KERNEL);
	if (fbops == NULL)
		return NULL;
	
	*fbops = *fb->info.fbops;
	fbops->fb_rasterimg = leo_rasterimg;
	fb->info.fbops = fbops;
	
	disp->scrollmode = SCROLL_YREDRAW;
	if (!disp->screen_base) {
		disp->screen_base = (char *)
			sbus_ioremap(&sdev->resource[0], LEO_OFF_SS0,
				     0x800000, "leo ram");
	}
	disp->screen_base += 8192 * fb->y_margin + 4 * fb->x_margin;
	us = fb->s.leo.lc_ss0_usr = (struct leo_lc_ss0_usr *)
		sbus_ioremap(&sdev->resource[0], LEO_OFF_LC_SS0_USR,
			     0x1000, "leolc ss0usr");
	fb->s.leo.ld_ss0 = (struct leo_ld_ss0 *)
		sbus_ioremap(&sdev->resource[0], LEO_OFF_LD_SS0,
			     0x1000, "leold ss0");
	ss = (struct leo_ld *) fb->s.leo.ld_ss0;
	fb->s.leo.ld_ss1 = (struct leo_ld_ss1 *)
		sbus_ioremap(&sdev->resource[0], LEO_OFF_LD_SS1,
			     0x1000, "leold ss1");
	fb->s.leo.lx_krn = (struct leo_lx_krn *)
		sbus_ioremap(&sdev->resource[0], LEO_OFF_LX_KRN,
			     0x1000, "leolx krn");
	fb->s.leo.cursor = (struct leo_cursor *)
		sbus_ioremap(&sdev->resource[0], LEO_OFF_LX_CURSOR,
			     sizeof(struct leo_cursor), "leolx cursor");
	fb->dispsw = leo_dispsw;
	
	fb->s.leo.extent = (type->fb_width-1) | ((type->fb_height-1) << 16);

	wl.wl_count = 1;
	wl.wl_list = &wi;
	wi.wi_type = FB_WID_DBL_8;
	wi.wi_index = 0;
	wi.wi_values [0] = 0x2c0;
	leo_wid_put (fb, &wl);
	wi.wi_index = 1;
	wi.wi_values [0] = 0x30;
	leo_wid_put (fb, &wl);
	wi.wi_index = 2;
	wi.wi_values [0] = 0x20;
	leo_wid_put (fb, &wl);
	wi.wi_type = FB_WID_DBL_24;
	wi.wi_index = 1;
	wi.wi_values [0] = 0x30;
	leo_wid_put (fb, &wl);

	tmp = sbus_readl(&fb->s.leo.ld_ss1->ss1_misc);
	tmp |= LEO_SS1_MISC_ENABLE;
	sbus_writel(tmp, &fb->s.leo.ld_ss1->ss1_misc);

	sbus_writel(0xffffffff, &ss->wid);
	sbus_writel(0xffff, &ss->wmask);
	sbus_writel(0, &ss->vclipmin);
	sbus_writel(fb->s.leo.extent, &ss->vclipmax);
	sbus_writel(0, &ss->fg);
	sbus_writel(0xff000000, &ss->planemask);
	sbus_writel(0x310850, &ss->rop);
	sbus_writel(0, &ss->widclip);
	sbus_writel((type->fb_width-1) | ((type->fb_height-1) << 11), &us->extent);
	sbus_writel(4, &us->addrspace);
	sbus_writel(0x80000000, &us->fill);
	sbus_writel(0, &us->fontt);
	do {
		i = sbus_readl(&us->csr);
	} while (i & 0x20000000);

	fb->margins = leo_margins;
	fb->loadcmap = leo_loadcmap;
	fb->setcursor = leo_setcursor;
	fb->setcursormap = leo_setcursormap;
	fb->setcurshape = leo_setcurshape;
	fb->restore_palette = leo_restore_palette;
	fb->switch_from_graph = leo_switch_from_graph;
	fb->fill = leo_fill;
	fb->blank = leo_blank;
	fb->unblank = leo_unblank;
	
	fb->physbase = phys;
	fb->mmap_map = leo_mmap_map;
	
#ifdef __sparc_v9__
	sprintf(idstring, "leo at %016lx", phys);
#else	
	sprintf(idstring, "leo at %x.%08lx", fb->iospace, phys);
#endif
		    
	return idstring;
}
static int __init init_one_port(struct sbus_dev *sdev)
{
	struct parport *p;
	/* at least in theory there may be a "we don't dma" case */
	struct parport_operations *ops;
	unsigned long base;
	int irq, dma, err, size;
	struct bpp_regs *regs;
	unsigned char value_tcr;

	dprintk((KERN_DEBUG "init_one_port(%p): ranges, alloc_io, ", sdev));
	irq = sdev->irqs[0];
	base = sbus_ioremap(&sdev->resource[0], 0,
			    sdev->reg_addrs[0].reg_size, 
			    "sunbpp");
	size = sdev->reg_addrs[0].reg_size;
	dma = PARPORT_DMA_NONE;

	dprintk(("alloc(ppops), "));
	ops = kmalloc (sizeof (struct parport_operations), GFP_KERNEL);
        if (!ops) {
		sbus_iounmap(base, size);
		return 0;
        }

        memcpy (ops, &parport_sunbpp_ops, sizeof (struct parport_operations));

	dprintk(("register_port\n"));
	if (!(p = parport_register_port(base, irq, dma, ops))) {
		kfree(ops);
		sbus_iounmap(base, size);
		return 0;
	}

	p->size = size;

	dprintk((KERN_DEBUG "init_one_port: request_irq(%08x:%p:%x:%s:%p) ",
		p->irq, parport_sunbpp_interrupt, SA_SHIRQ, p->name, p));
	if ((err = request_irq(p->irq, parport_sunbpp_interrupt,
			       SA_SHIRQ, p->name, p)) != 0) {
		dprintk(("ERROR %d\n", err));
		parport_unregister_port(p);
		kfree(ops);
		sbus_iounmap(base, size);
		return err;
	} else {
		dprintk(("OK\n"));
		parport_sunbpp_enable_irq(p);
	}

	regs = (struct bpp_regs *)p->base;
	dprintk((KERN_DEBUG "forward\n"));
	value_tcr = sbus_readb(&regs->p_tcr);
	value_tcr &= ~P_TCR_DIR;
	sbus_writeb(value_tcr, &regs->p_tcr);

	printk(KERN_INFO "%s: sunbpp at 0x%lx\n", p->name, p->base);
	parport_proc_register(p);
	parport_announce_port (p);

	return 1;
}
Exemple #20
0
static int __init init_one_port(struct sbus_dev *sdev)
{
	struct parport *p;
	/* at least in theory there may be a "we don't dma" case */
	struct parport_operations *ops;
	void __iomem *base;
	int irq, dma, err = 0, size;
	struct bpp_regs __iomem *regs;
	unsigned char value_tcr;
	Node *node;

	dprintk((KERN_DEBUG "init_one_port(%p): ranges, alloc_io, ", sdev));
	node = kmalloc(sizeof(Node), GFP_KERNEL);
	if (!node)
		goto out0;

	irq = sdev->irqs[0];
	base = sbus_ioremap(&sdev->resource[0], 0,
			    sdev->reg_addrs[0].reg_size, 
			    "sunbpp");
	if (!base)
		goto out1;

	size = sdev->reg_addrs[0].reg_size;
	dma = PARPORT_DMA_NONE;

	dprintk(("alloc(ppops), "));
	ops = kmalloc (sizeof (struct parport_operations), GFP_KERNEL);
        if (!ops)
		goto out2;

        memcpy (ops, &parport_sunbpp_ops, sizeof (struct parport_operations));

	dprintk(("register_port\n"));
	if (!(p = parport_register_port((unsigned long)base, irq, dma, ops)))
		goto out3;

	p->size = size;

	dprintk((KERN_DEBUG "init_one_port: request_irq(%08x:%p:%x:%s:%p) ",
		p->irq, parport_sunbpp_interrupt, SA_SHIRQ, p->name, p));
	if ((err = request_irq(p->irq, parport_sunbpp_interrupt,
			       SA_SHIRQ, p->name, p)) != 0) {
		dprintk(("ERROR %d\n", err));
		goto out4;
	}
	dprintk(("OK\n"));
	parport_sunbpp_enable_irq(p);

	regs = (struct bpp_regs __iomem *)p->base;
	dprintk((KERN_DEBUG "forward\n"));
	value_tcr = sbus_readb(&regs->p_tcr);
	value_tcr &= ~P_TCR_DIR;
	sbus_writeb(value_tcr, &regs->p_tcr);

	printk(KERN_INFO "%s: sunbpp at 0x%lx\n", p->name, p->base);
	node->port = p;
	list_add(&node->list, &port_list);
	parport_announce_port (p);

	return 1;

out4:
	parport_put_port(p);
out3:
	kfree(ops);
out2:
	sbus_iounmap(base, size);
out1:
	kfree(node);
out0:
	return err;
}
Exemple #21
0
static int __init myri_ether_init(struct net_device *dev, struct sbus_dev *sdev, int num)
{
	static unsigned version_printed = 0;
	struct myri_eth *mp;
	unsigned char prop_buf[32];
	int i;

	DET(("myri_ether_init(%p,%p,%d):\n", dev, sdev, num));
	dev = init_etherdev(0, sizeof(struct myri_eth));

	if (version_printed++ == 0)
		printk(version);

	printk("%s: MyriCOM MyriNET Ethernet ", dev->name);

	mp = (struct myri_eth *) dev->priv;
	mp->myri_sdev = sdev;

	/* Clean out skb arrays. */
	for (i = 0; i < (RX_RING_SIZE + 1); i++)
		mp->rx_skbs[i] = NULL;

	for (i = 0; i < TX_RING_SIZE; i++)
		mp->tx_skbs[i] = NULL;

	/* First check for EEPROM information. */
	i = prom_getproperty(sdev->prom_node, "myrinet-eeprom-info",
			     (char *)&mp->eeprom, sizeof(struct myri_eeprom));
	DET(("prom_getprop(myrinet-eeprom-info) returns %d\n", i));
	if (i == 0 || i == -1) {
		/* No eeprom property, must cook up the values ourselves. */
		DET(("No EEPROM: "));
		mp->eeprom.bus_type = BUS_TYPE_SBUS;
		mp->eeprom.cpuvers = prom_getintdefault(sdev->prom_node,"cpu_version",0);
		mp->eeprom.cval = prom_getintdefault(sdev->prom_node,"clock_value",0);
		mp->eeprom.ramsz = prom_getintdefault(sdev->prom_node,"sram_size",0);
		DET(("cpuvers[%d] cval[%d] ramsz[%d]\n", mp->eeprom.cpuvers,
		     mp->eeprom.cval, mp->eeprom.ramsz));
		if (mp->eeprom.cpuvers == 0) {
			DET(("EEPROM: cpuvers was zero, setting to %04x\n",CPUVERS_2_3));
			mp->eeprom.cpuvers = CPUVERS_2_3;
		}
		if (mp->eeprom.cpuvers < CPUVERS_3_0) {
			DET(("EEPROM: cpuvers < CPUVERS_3_0, clockval set to zero.\n"));
			mp->eeprom.cval = 0;
		}
		if (mp->eeprom.ramsz == 0) {
			DET(("EEPROM: ramsz == 0, setting to 128k\n"));
			mp->eeprom.ramsz = (128 * 1024);
		}
		i = prom_getproperty(sdev->prom_node, "myrinet-board-id",
				     &prop_buf[0], 10);
		DET(("EEPROM: prom_getprop(myrinet-board-id) returns %d\n", i));
		if ((i != 0) && (i != -1))
			memcpy(&mp->eeprom.id[0], &prop_buf[0], 6);
		else
			set_boardid_from_idprom(mp, num);
		i = prom_getproperty(sdev->prom_node, "fpga_version",
				     &mp->eeprom.fvers[0], 32);
		DET(("EEPROM: prom_getprop(fpga_version) returns %d\n", i));
		if (i == 0 || i == -1)
			memset(&mp->eeprom.fvers[0], 0, 32);

		if (mp->eeprom.cpuvers == CPUVERS_4_1) {
			DET(("EEPROM: cpuvers CPUVERS_4_1, "));
			if (mp->eeprom.ramsz == (128 * 1024)) {
				DET(("ramsize 128k, setting to 256k, "));
				mp->eeprom.ramsz = (256 * 1024);
			}
			if ((mp->eeprom.cval==0x40414041)||(mp->eeprom.cval==0x90449044)){
				DET(("changing cval from %08x to %08x ",
				     mp->eeprom.cval, 0x50e450e4));
				mp->eeprom.cval = 0x50e450e4;
			}
			DET(("\n"));
		}
	}
#ifdef DEBUG_DETECT
	dump_eeprom(mp);
#endif

	for (i = 0; i < 6; i++)
		printk("%2.2x%c",
		       dev->dev_addr[i] = mp->eeprom.id[i],
		       i == 5 ? ' ' : ':');
	printk("\n");

	determine_reg_space_size(mp);

	/* Map in the MyriCOM register/localram set. */
	if (mp->eeprom.cpuvers < CPUVERS_4_0) {
		/* XXX Makes no sense, if control reg is non-existant this
		 * XXX driver cannot function at all... maybe pre-4.0 is
		 * XXX only a valid version for PCI cards?  Ask feldy...
		 */
		DET(("Mapping regs for cpuvers < CPUVERS_4_0\n"));
		mp->regs = sbus_ioremap(&sdev->resource[0], 0,
					mp->reg_size, "MyriCOM Regs");
		if (!mp->regs) {
			printk("MyriCOM: Cannot map MyriCOM registers.\n");
			return -ENODEV;
		}
		mp->lanai = (unsigned short *) (mp->regs + (256 * 1024));
		mp->lanai3 = (unsigned int *) mp->lanai;
		mp->lregs = (unsigned long) &mp->lanai[0x10000];
	} else {
		DET(("Mapping regs for cpuvers >= CPUVERS_4_0\n"));
		mp->cregs = sbus_ioremap(&sdev->resource[0], 0,
					 PAGE_SIZE, "MyriCOM Control Regs");
		mp->lregs = sbus_ioremap(&sdev->resource[0], (256 * 1024),
					 PAGE_SIZE, "MyriCOM LANAI Regs");
		mp->lanai = (unsigned short *)
			sbus_ioremap(&sdev->resource[0], (512 * 1024),
				     mp->eeprom.ramsz, "MyriCOM SRAM");
		mp->lanai3 = (unsigned int *) mp->lanai;
	}
	DET(("Registers mapped: cregs[%lx] lregs[%lx] lanai[%p] lanai3[%p]\n",
	     mp->cregs, mp->lregs, mp->lanai, mp->lanai3));

	if (mp->eeprom.cpuvers >= CPUVERS_4_0)
		mp->shmem_base = 0xf000;
	else
		mp->shmem_base = 0x8000;

	DET(("Shared memory base is %04x, ", mp->shmem_base));

	mp->shmem = (struct myri_shmem *) &mp->lanai[mp->shmem_base];
	DET(("shmem mapped at %p\n", mp->shmem));

	mp->rqack	= &mp->shmem->channel.recvqa;
	mp->rq		= &mp->shmem->channel.recvq;
	mp->sq		= &mp->shmem->channel.sendq;

	/* Reset the board. */
	DET(("Resetting LANAI\n"));
	myri_reset_off(mp->lregs, mp->cregs);
	myri_reset_on(mp->cregs);

	/* Turn IRQ's off. */
	myri_disable_irq(mp->lregs, mp->cregs);

	/* Reset once more. */
	myri_reset_on(mp->cregs);

	/* Get the supported DVMA burst sizes from our SBUS. */
	mp->myri_bursts = prom_getintdefault(mp->myri_sdev->bus->prom_node,
					     "burst-sizes", 0x00);

	if (!sbus_can_burst64(sdev))
		mp->myri_bursts &= ~(DMA_BURST64);

	DET(("MYRI bursts %02x\n", mp->myri_bursts));

	/* Encode SBUS interrupt level in second control register. */
	i = prom_getint(sdev->prom_node, "interrupts");
	if (i == 0)
		i = 4;
	DET(("prom_getint(interrupts)==%d, irqlvl set to %04x\n",
	     i, (1 << i)));

	sbus_writel((1 << i), mp->cregs + MYRICTRL_IRQLVL);

	mp->dev = dev;
	dev->open = &myri_open;
	dev->stop = &myri_close;
	dev->hard_start_xmit = &myri_start_xmit;
	dev->tx_timeout = &myri_tx_timeout;
	dev->watchdog_timeo = 5*HZ;
	dev->get_stats = &myri_get_stats;
	dev->set_multicast_list = &myri_set_multicast;
	dev->irq = sdev->irqs[0];

	/* Register interrupt handler now. */
	DET(("Requesting MYRIcom IRQ line.\n"));
	if (request_irq(dev->irq, &myri_interrupt,
			SA_SHIRQ, "MyriCOM Ethernet", (void *) dev)) {
		printk("MyriCOM: Cannot register interrupt handler.\n");
		return -ENODEV;
	}

	DET(("ether_setup()\n"));
	ether_setup(dev);

	dev->mtu		= MYRINET_MTU;
	dev->change_mtu		= myri_change_mtu;
	dev->hard_header	= myri_header;
	dev->rebuild_header	= myri_rebuild_header;
	dev->hard_header_len	= (ETH_HLEN + MYRI_PAD_LEN);
	dev->hard_header_cache 	= myri_header_cache;
	dev->header_cache_update= myri_header_cache_update;

	/* Load code onto the LANai. */
	DET(("Loading LANAI firmware\n"));
	myri_load_lanai(mp);

#ifdef MODULE
	dev->ifindex = dev_new_index();
	mp->next_module = root_myri_dev;
	root_myri_dev = mp;
#endif
	return 0;
}
Exemple #22
0
static int __devinit init_one_port(struct sbus_dev *sdev)
{
	struct parport *p;
	/* at least in theory there may be a "we don't dma" case */
	struct parport_operations *ops;
	void __iomem *base;
	int irq, dma, err = 0, size;
	struct bpp_regs __iomem *regs;
	unsigned char value_tcr;

	irq = sdev->irqs[0];
	base = sbus_ioremap(&sdev->resource[0], 0,
			    sdev->reg_addrs[0].reg_size, 
			    "sunbpp");
	if (!base)
		return -ENODEV;

	size = sdev->reg_addrs[0].reg_size;
	dma = PARPORT_DMA_NONE;

	ops = kmalloc(sizeof(struct parport_operations), GFP_KERNEL);
        if (!ops)
		goto out_unmap;

        memcpy (ops, &parport_sunbpp_ops, sizeof (struct parport_operations));

	dprintk(("register_port\n"));
	if (!(p = parport_register_port((unsigned long)base, irq, dma, ops)))
		goto out_free_ops;

	p->size = size;
	p->dev = &sdev->ofdev.dev;

	if ((err = request_irq(p->irq, parport_sunbpp_interrupt,
			       IRQF_SHARED, p->name, p)) != 0) {
		goto out_put_port;
	}

	parport_sunbpp_enable_irq(p);

	regs = (struct bpp_regs __iomem *)p->base;

	value_tcr = sbus_readb(&regs->p_tcr);
	value_tcr &= ~P_TCR_DIR;
	sbus_writeb(value_tcr, &regs->p_tcr);

	printk(KERN_INFO "%s: sunbpp at 0x%lx\n", p->name, p->base);

	dev_set_drvdata(&sdev->ofdev.dev, p);

	parport_announce_port(p);

	return 0;

out_put_port:
	parport_put_port(p);

out_free_ops:
	kfree(ops);

out_unmap:
	sbus_iounmap(base, size);

	return err;
}