コード例 #1
0
ファイル: irq.c プロジェクト: 8563/millennium-sources
static void __internal_irq_unmask_32(unsigned int irq)
{
	u32 mask;

	mask = bcm_readl(irq_mask_addr);
	mask |= (1 << irq);
	bcm_writel(mask, irq_mask_addr);
}
コード例 #2
0
ファイル: bcm63xx-rng.c プロジェクト: Forzaferrarileo/linux
static int bcm63xx_rng_data_read(struct hwrng *rng, u32 *data)
{
	struct bcm63xx_rng_priv *priv = to_rng_priv(rng);

	*data = bcm_readl(priv->regs + RNG_DATA);

	return 4;
}
コード例 #3
0
ファイル: bcm63xx-rng.c プロジェクト: Forzaferrarileo/linux
static void bcm63xx_rng_cleanup(struct hwrng *rng)
{
	struct bcm63xx_rng_priv *priv = to_rng_priv(rng);
	u32 val;

	val = bcm_readl(priv->regs + RNG_CTRL);
	val &= ~RNG_EN;
	bcm_writel(val, priv->regs + RNG_CTRL);
}
コード例 #4
0
ファイル: irq.c プロジェクト: 8563/millennium-sources
/*
 * dispatch internal devices IRQ (uart, enet, watchdog, ...). do not
 * prioritize any interrupt relatively to another. the static counter
 * will resume the loop where it ended the last time we left this
 * function.
 */
static void __dispatch_internal(void)
{
	u32 pending;
	static int i;

	pending = bcm_readl(irq_stat_addr) & bcm_readl(irq_mask_addr);

	if (!pending)
		return ;

	while (1) {
		int to_call = i;

		i = (i + 1) & 0x1f;
		if (pending & (1 << to_call)) {
			handle_internal(to_call);
			break;
		}
	}
}
コード例 #5
0
ファイル: bcm63xx-rng.c プロジェクト: Forzaferrarileo/linux
static int bcm63xx_rng_init(struct hwrng *rng)
{
	struct bcm63xx_rng_priv *priv = to_rng_priv(rng);
	u32 val;

	val = bcm_readl(priv->regs + RNG_CTRL);
	val |= RNG_EN;
	bcm_writel(val, priv->regs + RNG_CTRL);

	return 0;
}
コード例 #6
0
/*
 * io helpers to access shared registers
 */
static inline u32 enet_dma_readl(struct bcm_enet_priv *priv, u32 off)
{
	return bcm_readl(bcm_enet_shared_base + off);
}
コード例 #7
0
/*
 * io helpers to access mac registers
 */
static inline u32 enet_readl(struct bcm_enet_priv *priv, u32 off)
{
	return bcm_readl(priv->base + off);
}
コード例 #8
0
/*
 * handy uart register accessor
 */
static inline unsigned int bcm_uart_readl(struct uart_port *port,
					 unsigned int offset)
{
	return bcm_readl(port->membase + offset);
}
コード例 #9
0
/*
 * read/write helper for pcmcia regs
 */
static inline u32 pcmcia_readl(struct bcm63xx_pcmcia_socket *skt, u32 off)
{
	return bcm_readl(skt->base + off);
}
コード例 #10
0
static long bcm63xx_wdt_ioctl(struct file *file, unsigned int cmd,
				unsigned long arg)
{
	void __user *argp = (void __user *)arg;
	int new_timeout;
	unsigned int value;
	static struct watchdog_info ident = {
		.options =		WDIOF_SETTIMEOUT |
					WDIOF_KEEPALIVEPING |
					WDIOF_MAGICCLOSE,
		.identity =		"BCM63xx Watchdog",
	};
	switch (cmd) {
	case WDIOC_KEEPALIVE:
		bcm63xx_wdt_reset();
		break;
	case WDIOC_GETSTATUS:
	case WDIOC_GETBOOTSTATUS:
		value = bcm_readl(bcm63xx_wdt_device.regs + WDT_DEFVAL_REG);
		if (copy_to_user(argp, &value, sizeof(int)))
			return -EFAULT;
		break;
	case WDIOC_GETSUPPORT:
		if (copy_to_user(argp, &ident, sizeof(ident)))
			return -EFAULT;
		break;
	case WDIOC_SETOPTIONS:
		if (copy_from_user(&value, argp, sizeof(int)))
			return -EFAULT;
		switch (value) {
		case WDIOS_ENABLECARD:
			bcm63xx_wdt_start();
			break;
		case WDIOS_DISABLECARD:
			bcm63xx_wdt_stop();
		default:
			return -EINVAL;
		}
		break;
	case WDIOC_SETTIMEOUT:
		if (copy_from_user(&new_timeout, argp, sizeof(int)))
			return -EFAULT;
		if (new_timeout < 5)
			return -EINVAL;
		if (new_timeout > 40)
			return -EINVAL;
		bcm63xx_wdt_set(new_timeout);
		bcm63xx_wdt_toggle();
	case WDIOC_GETTIMEOUT:
		return copy_to_user(argp, &timeout, sizeof(int));
	default:
		return -ENOTTY;
	}

	return 0;
}

static struct file_operations bcm63xx_wdt_fops = {
	.owner		= THIS_MODULE,
	.llseek		= no_llseek,
	.write		= bcm63xx_wdt_write,
	.unlocked_ioctl	= bcm63xx_wdt_ioctl,
	.open		= bcm63xx_wdt_open,
	.release	= bcm63xx_wdt_release,
};

static struct miscdevice bcm63xx_wdt_miscdev = {
	.minor	= WATCHDOG_MINOR,
	.name	= "watchdog",
	.fops	= &bcm63xx_wdt_fops,
};

static int bcm63xx_wdt_probe(struct platform_device *pdev)
{
	int ret;
	struct resource *r;

	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!r) {
		printk(KERN_ERR PFX 
			"failed to retrieve resources\n");
		return -ENODEV;
	}

	bcm63xx_wdt_device.regs = ioremap_nocache(r->start, r->end - r->start);
	if (!bcm63xx_wdt_device.regs) {
		printk(KERN_ERR PFX
			"failed to remap I/O resources\n");
		return -ENXIO;
	}

	ret = misc_register(&bcm63xx_wdt_miscdev);
	if (ret < 0) {
		printk(KERN_ERR PFX
			"failed to register watchdog device\n");
		goto unmap;
	}

	init_completion(&bcm63xx_wdt_device.stop);
	bcm63xx_wdt_device.queue = 0;

	clear_bit(0, &bcm63xx_wdt_device.inuse);

	setup_timer(&bcm63xx_wdt_device.timer, bcm63xx_wdt_update, 0L);

	bcm63xx_wdt_device.default_ticks = ticks;
	bcm63xx_wdt_set(ticks);
	bcm63xx_wdt_start();
	
	printk(KERN_INFO PFX " started, timer margin: %d sec\n", WDT_INTERVAL);

	return 0;

unmap:
	iounmap(bcm63xx_wdt_device.regs);
	return ret;
}

static int bcm63xx_wdt_remove(struct platform_device *pdev)
{
	if (bcm63xx_wdt_device.queue) {
		bcm63xx_wdt_device.queue = 0;
		wait_for_completion(&bcm63xx_wdt_device.stop);
	}

	misc_deregister(&bcm63xx_wdt_miscdev);

	iounmap(bcm63xx_wdt_device.regs);

	return 0;
}

static struct platform_driver bcm63xx_wdt = {
	.probe	= bcm63xx_wdt_probe,
	.remove = bcm63xx_wdt_remove,
	.driver = {
		.name = "bcm63xx-wdt",
	}
};

static int __init bcm63xx_wdt_init(void)
{
	return platform_driver_register(&bcm63xx_wdt);
}

static void __exit bcm63xx_wdt_exit(void)
{
	platform_driver_unregister(&bcm63xx_wdt);
}
コード例 #11
0
ファイル: bcm63xx-rng.c プロジェクト: Forzaferrarileo/linux
static int bcm63xx_rng_data_present(struct hwrng *rng, int wait)
{
	struct bcm63xx_rng_priv *priv = to_rng_priv(rng);

	return bcm_readl(priv->regs + RNG_STAT) & RNG_AVAIL_MASK;
}
コード例 #12
0
ファイル: prom.c プロジェクト: 168519/linux
void __init prom_init(void)
{
	u32 reg, mask;

	bcm63xx_cpu_init();

	/* stop any running watchdog */
	bcm_wdt_writel(WDT_STOP_1, WDT_CTL_REG);
	bcm_wdt_writel(WDT_STOP_2, WDT_CTL_REG);

	/* disable all hardware blocks clock for now */
	if (BCMCPU_IS_3368())
		mask = CKCTL_3368_ALL_SAFE_EN;
	else if (BCMCPU_IS_6328())
		mask = CKCTL_6328_ALL_SAFE_EN;
	else if (BCMCPU_IS_6338())
		mask = CKCTL_6338_ALL_SAFE_EN;
	else if (BCMCPU_IS_6345())
		mask = CKCTL_6345_ALL_SAFE_EN;
	else if (BCMCPU_IS_6348())
		mask = CKCTL_6348_ALL_SAFE_EN;
	else if (BCMCPU_IS_6358())
		mask = CKCTL_6358_ALL_SAFE_EN;
	else if (BCMCPU_IS_6362())
		mask = CKCTL_6362_ALL_SAFE_EN;
	else if (BCMCPU_IS_6368())
		mask = CKCTL_6368_ALL_SAFE_EN;
	else
		mask = 0;

	reg = bcm_perf_readl(PERF_CKCTL_REG);
	reg &= ~mask;
	bcm_perf_writel(reg, PERF_CKCTL_REG);

	/* register gpiochip */
	bcm63xx_gpio_init();

	/* do low level board init */
	board_prom_init();

	/* set up SMP */
	if (!register_bmips_smp_ops()) {
		/*
		 * BCM6328 might not have its second CPU enabled, while BCM3368
		 * and BCM6358 need special handling for their shared TLB, so
		 * disable SMP for now.
		 */
		if (BCMCPU_IS_6328()) {
			reg = bcm_readl(BCM_6328_OTP_BASE +
					OTP_USER_BITS_6328_REG(3));

			if (reg & OTP_6328_REG3_TP1_DISABLED)
				bmips_smp_enabled = 0;
		} else if (BCMCPU_IS_3368() || BCMCPU_IS_6358()) {
			bmips_smp_enabled = 0;
		}

		if (!bmips_smp_enabled)
			return;

		/*
		 * The bootloader has set up the CPU1 reset vector at
		 * 0xa000_0200.
		 * This conflicts with the special interrupt vector (IV).
		 * The bootloader has also set up CPU1 to respond to the wrong
		 * IPI interrupt.
		 * Here we will start up CPU1 in the background and ask it to
		 * reconfigure itself then go back to sleep.
		 */
		memcpy((void *)0xa0000200, &bmips_smp_movevec, 0x20);
		__sync();
		set_c0_cause(C_SW0);
		cpumask_set_cpu(1, &bmips_booted_mask);

		/*
		 * FIXME: we really should have some sort of hazard barrier here
		 */
	}
}