summaryrefslogtreecommitdiff
path: root/lwis_dt.c
diff options
context:
space:
mode:
Diffstat (limited to 'lwis_dt.c')
-rw-r--r--lwis_dt.c132
1 files changed, 105 insertions, 27 deletions
diff --git a/lwis_dt.c b/lwis_dt.c
index d9f9e07..c844ce9 100644
--- a/lwis_dt.c
+++ b/lwis_dt.c
@@ -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;
+}