/**
 * mpc52xx_get_xtal_freq - Get SYS_XTAL_IN frequency for a device
 *
 * @node: device node
 *
 * Returns the frequency of the external oscillator clock connected
 * to the SYS_XTAL_IN pin, or 0 if it cannot be determined.
 */
unsigned int mpc52xx_get_xtal_freq(struct device_node *node)
{
	u32 val;
	unsigned int freq;

	if (!mpc52xx_cdm)
		return 0;

	freq = mpc5xxx_get_bus_frequency(node);
	if (!freq)
		return 0;

	if (in_8(&mpc52xx_cdm->ipb_clk_sel) & 0x1)
		freq *= 2;

	val  = in_be32(&mpc52xx_cdm->rstcfg);
	if (val & (1 << 5))
		freq *= 8;
	else
		freq *= 4;
	if (val & (1 << 6))
		freq /= 12;
	else
		freq /= 16;

	return freq;
}
示例#2
0
/* 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 mpc5xxx_get_bus_frequency(p) / 2;
}
示例#3
0
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)
		has_wdt = of_get_property(op->node, "fsl,has-wdt", NULL);
	if (!has_wdt)
		return -ENODEV;

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

	wdt->ipb_freq = mpc5xxx_get_bus_frequency(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", },
	{ .compatible = "fsl,mpc5200-gpt", },
/*
 * OF Platform Bus Binding
 */
static int __devinit mpc52xx_spi_probe(struct platform_device *op,
				       const struct of_device_id *match)
{
	struct spi_master *master;
	struct mpc52xx_spi *ms;
	void __iomem *regs;
	u8 ctrl1;
	int rc, i = 0;
	int gpio_cs;

	/* MMIO registers */
	dev_dbg(&op->dev, "probing mpc5200 SPI device\n");
	regs = of_iomap(op->dev.of_node, 0);
	if (!regs)
		return -ENODEV;

	/* initialize the device */
	ctrl1 = SPI_CTRL1_SPIE | SPI_CTRL1_SPE | SPI_CTRL1_MSTR;
	out_8(regs + SPI_CTRL1, ctrl1);
	out_8(regs + SPI_CTRL2, 0x0);
	out_8(regs + SPI_DATADIR, 0xe);	/* Set output pins */
	out_8(regs + SPI_PORTDATA, 0x8);	/* Deassert /SS signal */

	/* Clear the status register and re-read it to check for a MODF
	 * failure.  This driver cannot currently handle multiple masters
	 * on the SPI bus.  This fault will also occur if the SPI signals
	 * are not connected to any pins (port_config setting) */
	in_8(regs + SPI_STATUS);
	out_8(regs + SPI_CTRL1, ctrl1);

	in_8(regs + SPI_DATA);
	if (in_8(regs + SPI_STATUS) & SPI_STATUS_MODF) {
		dev_err(&op->dev, "mode fault; is port_config correct?\n");
		rc = -EIO;
		goto err_init;
	}

	dev_dbg(&op->dev, "allocating spi_master struct\n");
	master = spi_alloc_master(&op->dev, sizeof *ms);
	if (!master) {
		rc = -ENOMEM;
		goto err_alloc;
	}

	master->bus_num = -1;
	master->setup = mpc52xx_spi_setup;
	master->transfer = mpc52xx_spi_transfer;
	master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST;
	master->dev.of_node = op->dev.of_node;

	dev_set_drvdata(&op->dev, master);

	ms = spi_master_get_devdata(master);
	ms->master = master;
	ms->regs = regs;
	ms->irq0 = irq_of_parse_and_map(op->dev.of_node, 0);
	ms->irq1 = irq_of_parse_and_map(op->dev.of_node, 1);
	ms->state = mpc52xx_spi_fsmstate_idle;
	ms->ipb_freq = mpc5xxx_get_bus_frequency(op->dev.of_node);
	ms->gpio_cs_count = of_gpio_count(op->dev.of_node);
	if (ms->gpio_cs_count > 0) {
		master->num_chipselect = ms->gpio_cs_count;
		ms->gpio_cs = kmalloc(ms->gpio_cs_count * sizeof(unsigned int),
				GFP_KERNEL);
		if (!ms->gpio_cs) {
			rc = -ENOMEM;
			goto err_alloc;
		}

		for (i = 0; i < ms->gpio_cs_count; i++) {
			gpio_cs = of_get_gpio(op->dev.of_node, i);
			if (gpio_cs < 0) {
				dev_err(&op->dev,
					"could not parse the gpio field "
					"in oftree\n");
				rc = -ENODEV;
				goto err_gpio;
			}

			rc = gpio_request(gpio_cs, dev_name(&op->dev));
			if (rc) {
				dev_err(&op->dev,
					"can't request spi cs gpio #%d "
					"on gpio line %d\n", i, gpio_cs);
				goto err_gpio;
			}

			gpio_direction_output(gpio_cs, 1);
			ms->gpio_cs[i] = gpio_cs;
		}
	} else {
		master->num_chipselect = 1;
	}

	spin_lock_init(&ms->lock);
	INIT_LIST_HEAD(&ms->queue);
	INIT_WORK(&ms->work, mpc52xx_spi_wq);

	/* Decide if interrupts can be used */
	if (ms->irq0 && ms->irq1) {
		rc = request_irq(ms->irq0, mpc52xx_spi_irq, 0,
				  "mpc5200-spi-modf", ms);
		rc |= request_irq(ms->irq1, mpc52xx_spi_irq, 0,
				  "mpc5200-spi-spif", ms);
		if (rc) {
			free_irq(ms->irq0, ms);
			free_irq(ms->irq1, ms);
			ms->irq0 = ms->irq1 = 0;
		}
	} else {
		/* operate in polled mode */
		ms->irq0 = ms->irq1 = 0;
	}

	if (!ms->irq0)
		dev_info(&op->dev, "using polled mode\n");

	dev_dbg(&op->dev, "registering spi_master struct\n");
	rc = spi_register_master(master);
	if (rc)
		goto err_register;

	dev_info(&ms->master->dev, "registered MPC5200 SPI bus\n");

	return rc;

 err_register:
	dev_err(&ms->master->dev, "initialization failed\n");
	spi_master_put(master);
 err_gpio:
	while (i-- > 0)
		gpio_free(ms->gpio_cs[i]);

	kfree(ms->gpio_cs);
 err_alloc:
 err_init:
	iounmap(regs);
	return rc;
}