예제 #1
0
static void __init u8500_init_machine(void)
{
	int i;

	u8500_init_devices();

	nmk_config_pins(mop500_pins, ARRAY_SIZE(mop500_pins));

	u8500_i2c0_device.dev.platform_data = &u8500_i2c0_data;
	ux500_i2c1_device.dev.platform_data = &u8500_i2c1_data;
	ux500_i2c2_device.dev.platform_data = &u8500_i2c2_data;
	ux500_i2c3_device.dev.platform_data = &u8500_i2c3_data;

	u8500_ssp0_device.dev.platform_data = &ssp0_platform_data;

	/* Register the active AMBA devices on this board */
	for (i = 0; i < ARRAY_SIZE(amba_devs); i++)
		amba_device_register(amba_devs[i], &iomem_resource);

	platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs));

	mop500_sdi_init();

	/* If HW is early drop (ED) or V1.0 then use SPI to access AB8500 */
	if (cpu_is_u8500ed() || cpu_is_u8500v10())
		spi_register_board_info(ab8500_spi_devices,
			ARRAY_SIZE(ab8500_spi_devices));
	else /* If HW is v.1.1 or later use I2C to access AB8500 */
		platform_device_register(&ab8500_device);
}
예제 #2
0
int __init clk_init(void)
{
    if (cpu_is_u8500ed()) {
        clk_prcmu_ops.enable = clk_prcmu_ed_enable;
        clk_prcmu_ops.disable = clk_prcmu_ed_disable;
        clk_per6clk.rate = 100000000;
    } else if (cpu_is_u5500()) {
        /* Clock tree for U5500 not implemented yet */
        clk_prcc_ops.enable = clk_prcc_ops.disable = NULL;
        clk_prcmu_ops.enable = clk_prcmu_ops.disable = NULL;
        clk_per6clk.rate = 26000000;
    }

    clkdev_add_table(u8500_common_clks, ARRAY_SIZE(u8500_common_clks));
    if (cpu_is_u8500ed())
        clkdev_add_table(u8500_ed_clks, ARRAY_SIZE(u8500_ed_clks));
    else
        clkdev_add_table(u8500_v1_clks, ARRAY_SIZE(u8500_v1_clks));

    return 0;
}
예제 #3
0
/*
 * This function is called from the board init
 */
void __init u8500_init_devices(void)
{
	if (cpu_is_u8500ed())
		dma40_u8500ed_fixup();

	db8500_add_rtc();
	db8500_add_gpios();
	db8500_add_usb(usb_db8500_rx_dma_cfg, usb_db8500_tx_dma_cfg);

	platform_device_register_simple("cpufreq-u8500", -1, NULL, 0);
	platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs));

	return ;
}
예제 #4
0
static void __init ux500_timer_init(void)
{
#ifdef CONFIG_LOCAL_TIMERS
	/* Setup the local timer base */
	twd_base = __io_address(UX500_TWD_BASE);
#endif
	/* Setup the MTU base */
	if (cpu_is_u8500ed())
		mtu_base = __io_address(U8500_MTU0_BASE_ED);
	else
		mtu_base = __io_address(UX500_MTU0_BASE);

	nmdk_timer_init();
}
예제 #5
0
void __init u8500_map_io(void)
{
	/*
	 * Map the UARTs early so that the DEBUG_LL stuff continues to work.
	 */
	iotable_init(u8500_uart_io_desc, ARRAY_SIZE(u8500_uart_io_desc));

	ux500_map_io();

	iotable_init(u8500_io_desc, ARRAY_SIZE(u8500_io_desc));

	if (cpu_is_u8500ed())
		iotable_init(u8500_ed_io_desc, ARRAY_SIZE(u8500_ed_io_desc));
	else if (cpu_is_u8500v1())
		iotable_init(u8500_v1_io_desc, ARRAY_SIZE(u8500_v1_io_desc));
	else if (cpu_is_u8500v2())
		iotable_init(u8500_v2_io_desc, ARRAY_SIZE(u8500_v2_io_desc));

	_PRCMU_BASE = __io_address(U8500_PRCMU_BASE);
}
예제 #6
0
/*
 * The MTU has a separate, rather complex muxing setup
 * with alternative parents (peripheral cluster or
 * ULP or fixed 32768 Hz) depending on settings
 */
static unsigned long clk_mtu_get_rate(struct clk *clk)
{
    void __iomem *addr = __io_address(UX500_PRCMU_BASE)
                         + PRCM_TCR;
    u32 tcr = readl(addr);
    int mtu = (int) clk->data;
    /*
     * One of these is selected eventually
     * TODO: Replace the constant with a reference
     * to the ULP source once this is modeled.
     */
    unsigned long clk32k = 32768;
    unsigned long mturate;
    unsigned long retclk;

    /* Get the rate from the parent as a default */
    if (clk->parent_periph)
        mturate = clk_get_rate(clk->parent_periph);
    else if (clk->parent_cluster)
        mturate = clk_get_rate(clk->parent_cluster);
    else
        /* We need to be connected SOMEWHERE */
        BUG();

    /*
     * Are we in doze mode?
     * In this mode the parent peripheral or the fixed 32768 Hz
     * clock is fed into the block.
     */
    if (!(tcr & PRCM_TCR_DOZE_MODE)) {
        /*
         * Here we're using the clock input from the APE ULP
         * clock domain. But first: are the timers stopped?
         */
        if (tcr & PRCM_TCR_STOPPED) {
            clk32k = 0;
            mturate = 0;
        } else {
            /* Else default mode: 0 and 2.4 MHz */
            clk32k = 0;
            if (cpu_is_u5500())
                /* DB5500 divides by 8 */
                mturate /= 8;
            else if (cpu_is_u8500ed()) {
                /*
                 * This clocking setting must not be used
                 * in the ED chip, it is simply not
                 * connected anywhere!
                 */
                mturate = 0;
                BUG();
            } else
                /*
                 * In this mode the ulp38m4 clock is divided
                 * by a factor 16, on the DB8500 typically
                 * 38400000 / 16 ~ 2.4 MHz.
                 * TODO: Replace the constant with a reference
                 * to the ULP source once this is modeled.
                 */
                mturate = 38400000 / 16;
        }
    }

    /* Return the clock selected for this MTU */
    if (tcr & (1 << mtu))
        retclk = clk32k;
    else
        retclk = mturate;

    pr_info("MTU%d clock rate: %lu Hz\n", mtu, retclk);
    return retclk;
}
int shrm_protocol_init(struct shrm_dev *shrm,
			received_msg_handler common_rx_handler,
			received_msg_handler audio_rx_handler)
{
	int err;

	shm_dev = shrm;
	boot_state = BOOT_INIT;
	dev_info(shrm->dev, "IPC_ISA BOOT_INIT\n");
	rx_common_handler = common_rx_handler;
	rx_audio_handler = audio_rx_handler;
	atomic_set(&ac_sleep_disable_count, 0);

	is_earlydrop = cpu_is_u8500ed();
	if (is_earlydrop != 0x01) {
		hrtimer_init(&timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
		timer.function = callback;
	}

	hrtimer_init(&mod_stuck_timer_0, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	mod_stuck_timer_0.function = shm_mod_stuck_timeout;
	hrtimer_init(&mod_stuck_timer_1, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	mod_stuck_timer_1.function = shm_mod_stuck_timeout;
	hrtimer_init(&fifo_full_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	fifo_full_timer.function = shm_fifo_full_timeout;

	shrm->shm_common_ch_wr_wq = create_singlethread_workqueue
		("shm_common_channel_irq");
	if (!shrm->shm_common_ch_wr_wq) {
		dev_err(shrm->dev, "failed to create work queue\n");
		return -ENOMEM;
	}
	shrm->shm_audio_ch_wr_wq = create_rt_workqueue
	  ("shm_audio_channel_irq");
	if (!shrm->shm_audio_ch_wr_wq) {
		dev_err(shrm->dev, "failed to create work queue\n");
		err = -ENOMEM;
		goto free_wq1;
	}
	shrm->shm_ac_wake_wq = create_rt_workqueue("shm_ac_wake_req");
	if (!shrm->shm_ac_wake_wq) {
		dev_err(shrm->dev, "failed to create work queue\n");
		err = -ENOMEM;
		goto free_wq2;
	}
	shrm->shm_ca_wake_wq = create_rt_workqueue("shm_ca_wake_req");
	if (!shrm->shm_ca_wake_wq) {
		dev_err(shrm->dev, "failed to create work queue\n");
		err = -ENOMEM;
		goto free_wq3;
	}
	shrm->shm_ac_sleep_wq = create_singlethread_workqueue
						("shm_ac_sleep_req");
	if (!shrm->shm_ac_sleep_wq) {
		dev_err(shrm->dev, "failed to create work queue\n");
		err = -ENOMEM;
		goto free_wq4;
	}
	shrm->shm_mod_stuck_wq = create_rt_workqueue("shm_mod_reset_req");
	if (!shrm->shm_mod_stuck_wq) {
		dev_err(shrm->dev, "failed to create work queue\n");
		err = -ENOMEM;
		goto free_wq5;
	}
	INIT_WORK(&shrm->send_ac_msg_pend_notify_0,
			send_ac_msg_pend_notify_0_work);
	INIT_WORK(&shrm->send_ac_msg_pend_notify_1,
			send_ac_msg_pend_notify_1_work);
	INIT_WORK(&shrm->shm_ca_wake_req, shm_ca_wake_req_work);
	INIT_WORK(&shrm->shm_ca_sleep_req, shm_ca_sleep_req_work);
	INIT_WORK(&shrm->shm_ac_sleep_req, shm_ac_sleep_req_work);
	INIT_WORK(&shrm->shm_ac_wake_req, shm_ac_wake_req_work);
	INIT_WORK(&shrm->shm_mod_reset_req, shm_mod_reset_work);

	/* set tasklet data */
	shm_ca_0_tasklet.data = (unsigned long)shrm;
	shm_ca_1_tasklet.data = (unsigned long)shrm;

	err = request_irq(IRQ_PRCMU_CA_SLEEP, shrm_prcmu_irq_handler,
			IRQF_NO_SUSPEND, "ca-sleep", shrm);
	if (err < 0) {
		dev_err(shm_dev->dev, "Failed alloc IRQ_PRCMU_CA_SLEEP.\n");
		goto free_wq6;
	}

	err = request_irq(IRQ_PRCMU_CA_WAKE, shrm_prcmu_irq_handler,
		IRQF_NO_SUSPEND, "ca-wake", shrm);
	if (err < 0) {
		dev_err(shm_dev->dev, "Failed alloc IRQ_PRCMU_CA_WAKE.\n");
		goto drop2;
	}

	err = request_irq(IRQ_PRCMU_MODEM_SW_RESET_REQ, shrm_prcmu_irq_handler,
			IRQF_NO_SUSPEND, "modem-sw-reset-req", shrm);
	if (err < 0) {
		dev_err(shm_dev->dev,
				"Failed alloc IRQ_PRCMU_MODEM_SW_RESET_REQ.\n");
		goto drop1;
	}

#ifdef CONFIG_U8500_SHRM_MODEM_SILENT_RESET
	/* init netlink socket for user-space communication */
	shrm_nl_sk = netlink_kernel_create(NULL, NETLINK_SHRM, 1,
			shm_nl_receive, NULL, THIS_MODULE);

	if (!shrm_nl_sk) {
		dev_err(shm_dev->dev, "netlink socket creation failed\n");
		goto drop;
	}
#endif

	return 0;

#ifdef CONFIG_U8500_SHRM_MODEM_SILENT_RESET
drop:
	free_irq(IRQ_PRCMU_MODEM_SW_RESET_REQ, NULL);
#endif
drop1:
	free_irq(IRQ_PRCMU_CA_WAKE, NULL);
drop2:
	free_irq(IRQ_PRCMU_CA_SLEEP, NULL);
free_wq6:
	destroy_workqueue(shrm->shm_mod_stuck_wq);
free_wq5:
	destroy_workqueue(shrm->shm_ac_sleep_wq);
free_wq4:
	destroy_workqueue(shrm->shm_ca_wake_wq);
free_wq3:
	destroy_workqueue(shrm->shm_ac_wake_wq);
free_wq2:
	destroy_workqueue(shrm->shm_audio_ch_wr_wq);
free_wq1:
	destroy_workqueue(shrm->shm_common_ch_wr_wq);
	return err;
}