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); }
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; }
/* * 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 ; }
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(); }
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); }
/* * 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; }