示例#1
0
文件: pmac.c 项目: RealJohnGalt/linux
/*
 * Attach to a macio probed interface
 */
static int pmac_ide_macio_attach(struct macio_dev *mdev,
                                 const struct of_device_id *match)
{
    void __iomem *base;
    unsigned long regbase;
    pmac_ide_hwif_t *pmif;
    int irq, rc;
    struct ide_hw hw;

    pmif = kzalloc(sizeof(*pmif), GFP_KERNEL);
    if (pmif == NULL)
        return -ENOMEM;

    if (macio_resource_count(mdev) == 0) {
        printk(KERN_WARNING "ide-pmac: no address for %s\n",
               mdev->ofdev.dev.of_node->full_name);
        rc = -ENXIO;
        goto out_free_pmif;
    }

    /* Request memory resource for IO ports */
    if (macio_request_resource(mdev, 0, "ide-pmac (ports)")) {
        printk(KERN_ERR "ide-pmac: can't request MMIO resource for "
               "%s!\n", mdev->ofdev.dev.of_node->full_name);
        rc = -EBUSY;
        goto out_free_pmif;
    }

    /* XXX This is bogus. Should be fixed in the registry by checking
     * the kind of host interrupt controller, a bit like gatwick
     * fixes in irq.c. That works well enough for the single case
     * where that happens though...
     */
    if (macio_irq_count(mdev) == 0) {
        printk(KERN_WARNING "ide-pmac: no intrs for device %s, using "
               "13\n", mdev->ofdev.dev.of_node->full_name);
        irq = irq_create_mapping(NULL, 13);
    } else
        irq = macio_irq(mdev, 0);

    base = ioremap(macio_resource_start(mdev, 0), 0x400);
    regbase = (unsigned long) base;

    pmif->mdev = mdev;
    pmif->node = mdev->ofdev.dev.of_node;
    pmif->regbase = regbase;
    pmif->irq = irq;
    pmif->kauai_fcr = NULL;

    if (macio_resource_count(mdev) >= 2) {
        if (macio_request_resource(mdev, 1, "ide-pmac (dma)"))
            printk(KERN_WARNING "ide-pmac: can't request DMA "
                   "resource for %s!\n",
                   mdev->ofdev.dev.of_node->full_name);
        else
            pmif->dma_regs = ioremap(macio_resource_start(mdev, 1), 0x1000);
    } else
        pmif->dma_regs = NULL;

    dev_set_drvdata(&mdev->ofdev.dev, pmif);

    memset(&hw, 0, sizeof(hw));
    pmac_ide_init_ports(&hw, pmif->regbase);
    hw.irq = irq;
    hw.dev = &mdev->bus->pdev->dev;
    hw.parent = &mdev->ofdev.dev;

    rc = pmac_ide_setup_device(pmif, &hw);
    if (rc != 0) {
        /* The inteface is released to the common IDE layer */
        dev_set_drvdata(&mdev->ofdev.dev, NULL);
        iounmap(base);
        if (pmif->dma_regs) {
            iounmap(pmif->dma_regs);
            macio_release_resource(mdev, 1);
        }
        macio_release_resource(mdev, 0);
        kfree(pmif);
    }

    return rc;

out_free_pmif:
    kfree(pmif);
    return rc;
}
示例#2
0
static int
airport_attach(struct macio_dev *mdev, const struct of_device_id *match)
{
	struct orinoco_private *priv;
	struct airport *card;
	unsigned long phys_addr;
	hermes_t *hw;

	if (macio_resource_count(mdev) < 1 || macio_irq_count(mdev) < 1) {
;
		return -ENODEV;
	}

	/* Allocate space for private device-specific data */
	priv = alloc_orinocodev(sizeof(*card), &mdev->ofdev.dev,
				airport_hard_reset, NULL);
	if (!priv) {
;
		return -ENODEV;
	}
	card = priv->card;

	hw = &priv->hw;
	card->mdev = mdev;

	if (macio_request_resource(mdev, 0, DRIVER_NAME)) {
;
		free_orinocodev(priv);
		return -EBUSY;
	}

	macio_set_drvdata(mdev, priv);

	/* Setup interrupts & base address */
	card->irq = macio_irq(mdev, 0);
	phys_addr = macio_resource_start(mdev, 0);  /* Physical address */
;
	card->vaddr = ioremap(phys_addr, AIRPORT_IO_LEN);
	if (!card->vaddr) {
;
		goto failed;
	}

	hermes_struct_init(hw, card->vaddr, HERMES_16BIT_REGSPACING);

	/* Power up card */
	pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE,
			  macio_get_of_node(mdev), 0, 1);
	ssleep(1);

	/* Reset it before we get the interrupt */
	hw->ops->init(hw);

	if (request_irq(card->irq, orinoco_interrupt, 0, DRIVER_NAME, priv)) {
;
		goto failed;
	}
	card->irq_requested = 1;

	/* Initialise the main driver */
	if (orinoco_init(priv) != 0) {
;
		goto failed;
	}

	/* Register an interface with the stack */
	if (orinoco_if_add(priv, phys_addr, card->irq, NULL) != 0) {
;
		goto failed;
	}
	card->ndev_registered = 1;
	return 0;
 failed:
	airport_detach(mdev);
	return -ENODEV;
}				/* airport_attach */
示例#3
0
static int swim3_add_device(struct macio_dev *mdev, int index)
{
	struct device_node *swim = mdev->ofdev.dev.of_node;
	struct floppy_state *fs = &floppy_states[index];
	int rc = -EBUSY;

	/* Do this first for message macros */
	memset(fs, 0, sizeof(*fs));
	fs->mdev = mdev;
	fs->index = index;

	/* Check & Request resources */
	if (macio_resource_count(mdev) < 2) {
		swim3_err("%s", "No address in device-tree\n");
		return -ENXIO;
	}
	if (macio_irq_count(mdev) < 1) {
		swim3_err("%s", "No interrupt in device-tree\n");
		return -ENXIO;
	}
	if (macio_request_resource(mdev, 0, "swim3 (mmio)")) {
		swim3_err("%s", "Can't request mmio resource\n");
		return -EBUSY;
	}
	if (macio_request_resource(mdev, 1, "swim3 (dma)")) {
		swim3_err("%s", "Can't request dma resource\n");
		macio_release_resource(mdev, 0);
		return -EBUSY;
	}
	dev_set_drvdata(&mdev->ofdev.dev, fs);

	if (mdev->media_bay == NULL)
		pmac_call_feature(PMAC_FTR_SWIM3_ENABLE, swim, 0, 1);
	
	fs->state = idle;
	fs->swim3 = (struct swim3 __iomem *)
		ioremap(macio_resource_start(mdev, 0), 0x200);
	if (fs->swim3 == NULL) {
		swim3_err("%s", "Couldn't map mmio registers\n");
		rc = -ENOMEM;
		goto out_release;
	}
	fs->dma = (struct dbdma_regs __iomem *)
		ioremap(macio_resource_start(mdev, 1), 0x200);
	if (fs->dma == NULL) {
		swim3_err("%s", "Couldn't map dma registers\n");
		iounmap(fs->swim3);
		rc = -ENOMEM;
		goto out_release;
	}
	fs->swim3_intr = macio_irq(mdev, 0);
	fs->dma_intr = macio_irq(mdev, 1);
	fs->cur_cyl = -1;
	fs->cur_sector = -1;
	fs->secpercyl = 36;
	fs->secpertrack = 18;
	fs->total_secs = 2880;
	init_waitqueue_head(&fs->wait);

	fs->dma_cmd = (struct dbdma_cmd *) DBDMA_ALIGN(fs->dbdma_cmd_space);
	memset(fs->dma_cmd, 0, 2 * sizeof(struct dbdma_cmd));
	fs->dma_cmd[1].command = cpu_to_le16(DBDMA_STOP);

	if (mdev->media_bay == NULL || check_media_bay(mdev->media_bay) == MB_FD)
		swim3_mb_event(mdev, MB_FD);

	if (request_irq(fs->swim3_intr, swim3_interrupt, 0, "SWIM3", fs)) {
		swim3_err("%s", "Couldn't request interrupt\n");
		pmac_call_feature(PMAC_FTR_SWIM3_ENABLE, swim, 0, 0);
		goto out_unmap;
		return -EBUSY;
	}

	init_timer(&fs->timeout);

	swim3_info("SWIM3 floppy controller %s\n",
		mdev->media_bay ? "in media bay" : "");

	return 0;

 out_unmap:
	iounmap(fs->dma);
	iounmap(fs->swim3);

 out_release:
	macio_release_resource(mdev, 0);
	macio_release_resource(mdev, 1);

	return rc;
}
示例#4
0
static int
airport_attach(struct macio_dev *mdev, const struct of_device_id *match)
{
	struct orinoco_private *priv;
	struct net_device *dev;
	struct airport *card;
	unsigned long phys_addr;
	hermes_t *hw;

	if (macio_resource_count(mdev) < 1 || macio_irq_count(mdev) < 1) {
		printk(KERN_ERR PFX "Wrong interrupt/addresses in OF tree\n");
		return -ENODEV;
	}

	/* Allocate space for private device-specific data */
	dev = alloc_orinocodev(sizeof(*card), &mdev->ofdev.dev,
			       airport_hard_reset, NULL);
	if (! dev) {
		printk(KERN_ERR PFX "Cannot allocate network device\n");
		return -ENODEV;
	}
	priv = netdev_priv(dev);
	card = priv->card;

	hw = &priv->hw;
	card->mdev = mdev;

	if (macio_request_resource(mdev, 0, "airport")) {
		printk(KERN_ERR PFX "can't request IO resource !\n");
		free_orinocodev(dev);
		return -EBUSY;
	}

	SET_NETDEV_DEV(dev, &mdev->ofdev.dev);

	macio_set_drvdata(mdev, dev);

	/* Setup interrupts & base address */
	dev->irq = macio_irq(mdev, 0);
	phys_addr = macio_resource_start(mdev, 0);  /* Physical address */
	printk(KERN_DEBUG PFX "Physical address %lx\n", phys_addr);
	dev->base_addr = phys_addr;
	card->vaddr = ioremap(phys_addr, AIRPORT_IO_LEN);
	if (!card->vaddr) {
		printk(KERN_ERR PFX "ioremap() failed\n");
		goto failed;
	}

	hermes_struct_init(hw, card->vaddr, HERMES_16BIT_REGSPACING);
		
	/* Power up card */
	pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, macio_get_of_node(mdev), 0, 1);
	ssleep(1);

	/* Reset it before we get the interrupt */
	hermes_init(hw);

	if (request_irq(dev->irq, orinoco_interrupt, 0, dev->name, dev)) {
		printk(KERN_ERR PFX "Couldn't get IRQ %d\n", dev->irq);
		goto failed;
	}
	card->irq_requested = 1;

	/* Tell the stack we exist */
	if (register_netdev(dev) != 0) {
		printk(KERN_ERR PFX "register_netdev() failed\n");
		goto failed;
	}
	printk(KERN_DEBUG PFX "Card registered for interface %s\n", dev->name);
	card->ndev_registered = 1;
	return 0;
 failed:
	airport_detach(mdev);
	return -ENODEV;
}				/* airport_attach */