diff options
Diffstat (limited to 'lwis_dt.c')
-rw-r--r-- | lwis_dt.c | 132 |
1 files changed, 105 insertions, 27 deletions
@@ -25,6 +25,7 @@ #include "lwis_i2c.h" #include "lwis_ioreg.h" #include "lwis_regulator.h" +#include "lwis_i2c_bus_manager.h" #define SHARED_STRING "shared-" #define PULSE_STRING "pulse-" @@ -50,7 +51,7 @@ static int parse_gpios(struct lwis_device *lwis_dev, char *name, bool *is_presen } list = lwis_gpio_list_get(dev, name); - if (IS_ERR(list)) { + if (IS_ERR_OR_NULL(list)) { pr_err("Error parsing GPIO list %s (%ld)\n", name, PTR_ERR(list)); return PTR_ERR(list); } @@ -103,14 +104,14 @@ static int parse_irq_gpios(struct lwis_device *lwis_dev) } gpios = lwis_gpio_list_get(dev, "irq"); - if (IS_ERR(gpios)) { + if (IS_ERR_OR_NULL(gpios)) { pr_err("Error parsing irq GPIO list (%ld)\n", PTR_ERR(gpios)); return PTR_ERR(gpios); } lwis_dev->irq_gpios_info.gpios = gpios; lwis_dev->irq_gpios_info.irq_list = lwis_interrupt_list_alloc(lwis_dev, gpios->ndescs); - if (IS_ERR(lwis_dev->irq_gpios_info.irq_list)) { + if (IS_ERR_OR_NULL(lwis_dev->irq_gpios_info.irq_list)) { ret = -ENOMEM; lwis_dev->irq_gpios_info.irq_list = NULL; pr_err("Failed to allocate irq list\n"); @@ -141,8 +142,8 @@ static int parse_irq_gpios(struct lwis_device *lwis_dev) goto error_parse_irq_gpios; } - type_count = of_property_read_variable_u32_array( - dev_node, "irq-gpios-types", irq_gpios_types, type_count, type_count); + type_count = of_property_read_variable_u32_array(dev_node, "irq-gpios-types", + irq_gpios_types, type_count, type_count); if (type_count != count) { pr_err("Error getting irq-gpios-types: %d\n", type_count); @@ -252,9 +253,11 @@ static int parse_regulators(struct lwis_device *lwis_dev) of_property_count_elems_of_size(dev_node, "regulator-voltages", sizeof(u32)); lwis_dev->regulators = lwis_regulator_list_alloc(count); - if (IS_ERR(lwis_dev->regulators)) { + if (IS_ERR_OR_NULL(lwis_dev->regulators)) { pr_err("Cannot allocate regulator list\n"); - return PTR_ERR(lwis_dev->regulators); + ret = PTR_ERR(lwis_dev->regulators); + lwis_dev->regulators = NULL; + return ret; } /* Parse regulator list and acquire the regulator pointers */ @@ -310,9 +313,11 @@ static int parse_clocks(struct lwis_device *lwis_dev) } lwis_dev->clocks = lwis_clock_list_alloc(count); - if (IS_ERR(lwis_dev->clocks)) { + if (IS_ERR_OR_NULL(lwis_dev->clocks)) { pr_err("Cannot allocate clocks list\n"); - return PTR_ERR(lwis_dev->clocks); + ret = PTR_ERR(lwis_dev->clocks); + lwis_dev->clocks = NULL; + return ret; } /* Parse and acquire clock pointers and frequencies, if applicable */ @@ -333,7 +338,6 @@ static int parse_clocks(struct lwis_device *lwis_dev) ret = of_property_read_u32(dev_node, "clock-family", &clock_family); lwis_dev->clock_family = (ret == 0) ? clock_family : CLOCK_FAMILY_INVALID; -#ifdef LWIS_BTS_BLOCK_NAME_ENABLED /* Parse the BTS block names */ bts_count = of_property_count_strings(dev_node, "bts-block-names"); if (bts_count > 0) { @@ -351,7 +355,6 @@ static int parse_clocks(struct lwis_device *lwis_dev) for (i = 0; i < MAX_BTS_BLOCK_NUM; ++i) { lwis_dev->bts_indexes[i] = BTS_UNSUPPORTED; } -#endif #ifdef LWIS_DT_DEBUG pr_info("%s: clock family %d", lwis_dev->name, lwis_dev->clock_family); @@ -391,13 +394,13 @@ static int parse_pinctrls(struct lwis_device *lwis_dev, char *expected_state) /* Set up pinctrl */ pc = devm_pinctrl_get(dev); - if (IS_ERR(pc)) { + if (IS_ERR_OR_NULL(pc)) { pr_err("Cannot allocate pinctrl\n"); return PTR_ERR(pc); } pinctrl_state = pinctrl_lookup_state(pc, expected_state); - if (IS_ERR(pinctrl_state)) { + if (IS_ERR_OR_NULL(pinctrl_state)) { pr_err("Cannot find pinctrl state %s\n", expected_state); devm_pinctrl_put(pc); return PTR_ERR(pinctrl_state); @@ -637,7 +640,12 @@ static int parse_interrupts(struct lwis_device *lwis_dev) plat_dev = lwis_dev->plat_dev; dev_node = plat_dev->dev.of_node; - count = platform_irq_count(plat_dev); + /* Test device type DEVICE_TYPE_TEST used for test, platform independent. */ + if (lwis_dev->type == DEVICE_TYPE_TEST) { + count = TEST_DEVICE_IRQ_CNT; + } else { + count = platform_irq_count(plat_dev); + } /* No interrupts found, just return */ if (count <= 0) { @@ -646,9 +654,15 @@ static int parse_interrupts(struct lwis_device *lwis_dev) } lwis_dev->irqs = lwis_interrupt_list_alloc(lwis_dev, count); - if (IS_ERR(lwis_dev->irqs)) { - pr_err("Failed to allocate IRQ list\n"); - return PTR_ERR(lwis_dev->irqs); + if (IS_ERR_OR_NULL(lwis_dev->irqs)) { + if (lwis_dev->type == DEVICE_TYPE_TEST) { + pr_err("Failed to allocate injection\n"); + } else { + pr_err("Failed to allocate IRQ list\n"); + } + ret = PTR_ERR(lwis_dev->irqs); + lwis_dev->irqs = NULL; + return ret; } for (i = 0; i < count; ++i) { @@ -740,7 +754,7 @@ static int parse_interrupts(struct lwis_device *lwis_dev) ret = of_property_read_string(event_info, "irq-type", &irq_type_str); if (ret && ret != -EINVAL) { pr_err("Error getting irq-type from dt: %d\n", ret); - return ret; + goto error_event_infos; } else if (ret && ret == -EINVAL) { /* The property does not exist, which means regular*/ irq_type = REGULAR_INTERRUPT; @@ -751,9 +765,11 @@ static int parse_interrupts(struct lwis_device *lwis_dev) irq_type = AGGREGATE_INTERRUPT; } else if (strcmp(irq_type_str, "leaf") == 0) { irq_type = LEAF_INTERRUPT; + } else if (strcmp(irq_type_str, "injection") == 0) { + irq_type = FAKEEVENT_INTERRUPT; } else { pr_err("Invalid irq-type from dt: %s\n", irq_type_str); - return ret; + goto error_event_infos; } } @@ -769,6 +785,12 @@ static int parse_interrupts(struct lwis_device *lwis_dev) pr_err("Cannot set irq %s\n", name); goto error_event_infos; } + } else if (irq_type == FAKEEVENT_INTERRUPT) { + /* + * Hardcode the fake injection irq number to + * TEST_DEVICE_FAKE_INJECTION_IRQ + */ + lwis_dev->irqs->irq[i].irq = TEST_DEVICE_FAKE_INJECTION_IRQ; } /* Parse event info */ @@ -827,9 +849,11 @@ static int parse_phys(struct lwis_device *lwis_dev) } lwis_dev->phys = lwis_phy_list_alloc(count); - if (IS_ERR(lwis_dev->phys)) { + if (IS_ERR_OR_NULL(lwis_dev->phys)) { pr_err("Failed to allocate PHY list\n"); - return PTR_ERR(lwis_dev->phys); + ret = PTR_ERR(lwis_dev->phys); + lwis_dev->phys = NULL; + return ret; } for (i = 0; i < count; ++i) { @@ -858,7 +882,6 @@ error_parse_phy: static void parse_bitwidths(struct lwis_device *lwis_dev) { - int __maybe_unused ret; struct device *dev; struct device_node *dev_node; u32 addr_bitwidth = 32; @@ -927,9 +950,11 @@ static int parse_power_seqs(struct lwis_device *lwis_dev, const char *seq_name, } *list = lwis_dev_power_seq_list_alloc(power_seq_count); - if (IS_ERR(*list)) { + if (IS_ERR_OR_NULL(*list)) { pr_err("Failed to allocate power sequence list\n"); - return PTR_ERR(*list); + ret = PTR_ERR(*list); + *list = NULL; + return ret; } for (i = 0; i < power_seq_count; ++i) { @@ -966,7 +991,7 @@ static int parse_power_seqs(struct lwis_device *lwis_dev, const char *seq_name, if (type_gpio_count > 0 && lwis_dev->gpios_list == NULL) { lwis_dev->gpios_list = lwis_gpios_list_alloc(type_gpio_count); - if (IS_ERR(lwis_dev->gpios_list)) { + if (IS_ERR_OR_NULL(lwis_dev->gpios_list)) { pr_err("Failed to allocate gpios list\n"); ret = PTR_ERR(lwis_dev->gpios_list); goto error_parse_power_seqs; @@ -987,7 +1012,7 @@ static int parse_power_seqs(struct lwis_device *lwis_dev, const char *seq_name, seq_item_name = (*list)->seq_info[i].name; dev = &lwis_dev->plat_dev->dev; descs = lwis_gpio_list_get(dev, seq_item_name); - if (IS_ERR(descs)) { + if (IS_ERR_OR_NULL(descs)) { pr_err("Error parsing GPIO list %s (%ld)\n", seq_item_name, PTR_ERR(descs)); ret = PTR_ERR(descs); @@ -1021,7 +1046,7 @@ static int parse_power_seqs(struct lwis_device *lwis_dev, const char *seq_name, if (type_regulator_count > 0 && lwis_dev->regulators == NULL) { lwis_dev->regulators = lwis_regulator_list_alloc(type_regulator_count); - if (IS_ERR(lwis_dev->regulators)) { + if (IS_ERR_OR_NULL(lwis_dev->regulators)) { pr_err("Failed to allocate regulator list\n"); ret = PTR_ERR(lwis_dev->regulators); goto error_parse_power_seqs; @@ -1141,6 +1166,33 @@ static int parse_thread_priority(struct lwis_device *lwis_dev) return 0; } +static int parse_i2c_device_priority(struct lwis_i2c_device *i2c_dev) +{ + struct device_node *dev_node; + int ret = 0; + + dev_node = i2c_dev->base_dev.plat_dev->dev.of_node; + /* Set i2c device_priority value to default */ + i2c_dev->device_priority = I2C_DEVICE_HIGH_PRIORITY; + + ret = of_property_read_u32(dev_node, "i2c-device-priority", &i2c_dev->device_priority); + /* If no property in device tree, just return to use default */ + if (ret == -EINVAL) { + return 0; + } + if (ret) { + pr_err("invalid i2c-device-priority value\n"); + return ret; + } + if ((i2c_dev->device_priority < I2C_DEVICE_HIGH_PRIORITY) || + (i2c_dev->device_priority > I2C_DEVICE_LOW_PRIORITY)) { + pr_err("invalid i2c-device-priority value %d\n", i2c_dev->device_priority); + return -EINVAL; + } + + return 0; +} + static int parse_i2c_lock_group_id(struct lwis_i2c_device *i2c_dev) { struct device_node *dev_node; @@ -1167,6 +1219,19 @@ static int parse_i2c_lock_group_id(struct lwis_i2c_device *i2c_dev) return 0; } +static int parse_transaction_process_limit(struct lwis_device *lwis_dev) +{ + struct device_node *dev_node; + + lwis_dev->transaction_process_limit = 0; + dev_node = lwis_dev->plat_dev->dev.of_node; + + of_property_read_u32(dev_node, "transaction-process-limit", + &lwis_dev->transaction_process_limit); + + return 0; +} + int lwis_base_parse_dt(struct lwis_device *lwis_dev) { struct device *dev; @@ -1297,6 +1362,7 @@ int lwis_base_parse_dt(struct lwis_device *lwis_dev) parse_access_mode(lwis_dev); parse_thread_priority(lwis_dev); parse_bitwidths(lwis_dev); + parse_transaction_process_limit(lwis_dev); lwis_dev->bts_scenario_name = NULL; of_property_read_string(dev_node, "bts-scenario", &lwis_dev->bts_scenario_name); @@ -1340,6 +1406,12 @@ int lwis_i2c_device_parse_dt(struct lwis_i2c_device *i2c_dev) return ret; } + ret = parse_i2c_device_priority(i2c_dev); + if (ret) { + dev_err(i2c_dev->base_dev.dev, "Error parsing i2c device priority\n"); + return ret; + } + return 0; } @@ -1391,3 +1463,9 @@ int lwis_top_device_parse_dt(struct lwis_top_device *top_dev) /* To be implemented */ return 0; } + +int lwis_test_device_parse_dt(struct lwis_test_device *test_dev) +{ + /* To be implemented */ + return 0; +} |