/* Search for bus-frequency property in this node or a parent */
static unsigned long mpc52xx_getuartclk(void *p)
{
	/*
	 * 5200 UARTs have a / 32 prescaler
	 * but the generic serial code assumes 16
	 * so return ipb freq / 2
	 */
	return mpc52xx_find_ipb_freq(p) / 2;
}
/* Search for bus-frequency property in this node or a parent */
static unsigned long mpc52xx_getuartclk(void *p)
{
#if defined(CONFIG_PPC_MERGE)
	/*
	 * 5200 UARTs have a / 32 prescaler
	 * but the generic serial code assumes 16
	 * so return ipb freq / 2
	 */
	return mpc52xx_find_ipb_freq(p) / 2;
#else
	pr_debug("unexpected call to mpc52xx_getuartclk with arch/ppc\n");
	return NULL;
#endif
}
Esempio n. 3
0
static int __devinit
mpc52xx_ata_probe(struct of_device *op, const struct of_device_id *match)
{
	unsigned int ipb_freq;
	struct resource res_mem;
	int ata_irq;
	struct mpc52xx_ata __iomem *ata_regs;
	struct mpc52xx_ata_priv *priv;
	int rv;

	/* Get ipb frequency */
	ipb_freq = mpc52xx_find_ipb_freq(op->node);
	if (!ipb_freq) {
		printk(KERN_ERR DRV_NAME ": "
			"Unable to find IPB Bus frequency\n" );
		return -ENODEV;
	}

	/* Get IRQ and register */
	rv = of_address_to_resource(op->node, 0, &res_mem);
	if (rv) {
		printk(KERN_ERR DRV_NAME ": "
			"Error while parsing device node resource\n" );
		return rv;
	}

	ata_irq = irq_of_parse_and_map(op->node, 0);
	if (ata_irq == NO_IRQ) {
		printk(KERN_ERR DRV_NAME ": "
			"Error while mapping the irq\n");
		return -EINVAL;
	}

	/* Request mem region */
	if (!devm_request_mem_region(&op->dev, res_mem.start,
				     sizeof(struct mpc52xx_ata), DRV_NAME)) {
		printk(KERN_ERR DRV_NAME ": "
			"Error while requesting mem region\n");
		rv = -EBUSY;
		goto err;
	}

	/* Remap registers */
	ata_regs = devm_ioremap(&op->dev, res_mem.start,
				sizeof(struct mpc52xx_ata));
	if (!ata_regs) {
		printk(KERN_ERR DRV_NAME ": "
			"Error while mapping register set\n");
		rv = -ENOMEM;
		goto err;
	}

	/* Prepare our private structure */
	priv = devm_kzalloc(&op->dev, sizeof(struct mpc52xx_ata_priv),
			    GFP_ATOMIC);
	if (!priv) {
		printk(KERN_ERR DRV_NAME ": "
			"Error while allocating private structure\n");
		rv = -ENOMEM;
		goto err;
	}

	priv->ipb_period = 1000000000 / (ipb_freq / 1000);
	priv->ata_regs = ata_regs;
	priv->ata_irq = ata_irq;
	priv->csel = -1;

	/* Init the hw */
	rv = mpc52xx_ata_hw_init(priv);
	if (rv) {
		printk(KERN_ERR DRV_NAME ": Error during HW init\n");
		goto err;
	}

	/* Register ourselves to libata */
	rv = mpc52xx_ata_init_one(&op->dev, priv, res_mem.start);
	if (rv) {
		printk(KERN_ERR DRV_NAME ": "
			"Error while registering to ATA layer\n");
		return rv;
	}

	/* Done */
	return 0;

	/* Error path */
err:
	irq_dispose_mapping(ata_irq);
	return rv;
}
Esempio n. 4
0
/* module operations */
static int mpc5200_wdt_probe(struct of_device *op, const struct of_device_id *match)
{
    struct mpc5200_wdt *wdt;
    int err;
    const void *has_wdt;
    int size;

    has_wdt = of_get_property(op->node, "has-wdt", NULL);
    if (!has_wdt)
        return -ENODEV;

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

    wdt->ipb_freq = mpc52xx_find_ipb_freq(op->node);

    err = of_address_to_resource(op->node, 0, &wdt->mem);
    if (err)
        goto out_free;
    size = wdt->mem.end - wdt->mem.start + 1;
    if (!request_mem_region(wdt->mem.start, size, "mpc5200_wdt")) {
        err = -ENODEV;
        goto out_free;
    }
    wdt->regs = ioremap(wdt->mem.start, size);
    if (!wdt->regs) {
        err = -ENODEV;
        goto out_release;
    }

    dev_set_drvdata(&op->dev, wdt);
    spin_lock_init(&wdt->io_lock);

    wdt->miscdev = (struct miscdevice) {
        .minor	= WATCHDOG_MINOR,
          .name	= "watchdog",
             .fops	= &mpc5200_wdt_fops,
                .parent = &op->dev,
    };
    wdt_global = wdt;
    err = misc_register(&wdt->miscdev);
    if (!err)
        return 0;

    iounmap(wdt->regs);
out_release:
    release_mem_region(wdt->mem.start, size);
out_free:
    kfree(wdt);
    return err;
}

static int mpc5200_wdt_remove(struct of_device *op)
{
    struct mpc5200_wdt *wdt = dev_get_drvdata(&op->dev);

    mpc5200_wdt_stop(wdt);
    misc_deregister(&wdt->miscdev);
    iounmap(wdt->regs);
    release_mem_region(wdt->mem.start, wdt->mem.end - wdt->mem.start + 1);
    kfree(wdt);

    return 0;
}
static int mpc5200_wdt_suspend(struct of_device *op, pm_message_t state)
{
    struct mpc5200_wdt *wdt = dev_get_drvdata(&op->dev);
    mpc5200_wdt_stop(wdt);
    return 0;
}
static int mpc5200_wdt_resume(struct of_device *op)
{
    struct mpc5200_wdt *wdt = dev_get_drvdata(&op->dev);
    if (wdt->count)
        mpc5200_wdt_start(wdt);
    return 0;
}
static int mpc5200_wdt_shutdown(struct of_device *op)
{
    struct mpc5200_wdt *wdt = dev_get_drvdata(&op->dev);
    mpc5200_wdt_stop(wdt);
    return 0;
}

static struct of_device_id mpc5200_wdt_match[] = {
    { .compatible = "mpc5200-gpt", },
    {},
};