#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
+#include <linux/property.h>
#include <linux/gpio/machine.h>
#include <linux/gpio/property.h>
#include <linux/input.h>
/******************************************************************************/
-static const struct software_node mtx1_gpiochip_node = {
- .name = "alchemy-gpio2",
-};
-
static const struct software_node mtx1_gpio_keys_node = {
.name = "mtx1-gpio-keys",
};
static const struct property_entry mtx1_button_props[] = {
PROPERTY_ENTRY_U32("linux,code", BTN_0),
- PROPERTY_ENTRY_GPIO("gpios", &mtx1_gpiochip_node, 7, GPIO_ACTIVE_HIGH),
+ PROPERTY_ENTRY_GPIO("gpios", &alchemy_gpio2_node, 7, GPIO_ACTIVE_HIGH),
PROPERTY_ENTRY_STRING("label", "System button"),
{ }
};
.properties = mtx1_button_props,
};
-static const struct software_node *mtx1_gpio_keys_swnodes[] __initconst = {
+static const struct software_node * const mtx1_gpio_keys_swnodes[] __initconst = {
&mtx1_gpio_keys_node,
&mtx1_button_node,
NULL
pr_err("failed to create gpio-keys device: %d\n", err);
}
-/* Global number 215 is offset 15 on Alchemy GPIO 2 */
static const struct property_entry mtx1_wdt_props[] = {
- PROPERTY_ENTRY_GPIO("gpios", &mtx1_gpiochip_node, 15, GPIO_ACTIVE_HIGH),
+ /* Global number 215 is offset 15 on Alchemy GPIO 2 */
+ PROPERTY_ENTRY_GPIO("gpios", &alchemy_gpio2_node, 15, GPIO_ACTIVE_HIGH),
{ }
};
-static struct platform_device_info mtx1_wdt_info __initconst = {
+static const struct platform_device_info mtx1_wdt_info __initconst = {
.name = "mtx1-wdt",
.id = 0,
.properties = mtx1_wdt_props,
pd = platform_device_register_full(&mtx1_wdt_info);
err = PTR_ERR_OR_ZERO(pd);
if (err)
- pr_err("failed to create gpio-keys device: %d\n", err);
+ pr_err("failed to create watchdog device: %d\n", err);
}
static const struct software_node mtx1_gpio_leds_node = {
};
static const struct property_entry mtx1_green_led_props[] = {
- PROPERTY_ENTRY_GPIO("gpios", &mtx1_gpiochip_node, 11, GPIO_ACTIVE_HIGH),
+ PROPERTY_ENTRY_GPIO("gpios", &alchemy_gpio2_node, 11, GPIO_ACTIVE_HIGH),
{ }
};
};
static const struct property_entry mtx1_red_led_props[] = {
- PROPERTY_ENTRY_GPIO("gpios", &mtx1_gpiochip_node, 12, GPIO_ACTIVE_HIGH),
+ PROPERTY_ENTRY_GPIO("gpios", &alchemy_gpio2_node, 12, GPIO_ACTIVE_HIGH),
{ }
};
.properties = mtx1_red_led_props,
};
-static const struct software_node *mtx1_gpio_leds_swnodes[] = {
+static const struct software_node * const mtx1_gpio_leds_swnodes[] __initconst = {
&mtx1_gpio_leds_node,
&mtx1_green_led_node,
&mtx1_red_led_node,
static void __init mtx1_leds_init(void)
{
- struct platform_device_info led_info = {
+ const struct platform_device_info pdevinfo = {
.name = "leds-gpio",
.id = PLATFORM_DEVID_NONE,
+ .swnode = &mtx1_gpio_leds_node,
};
struct platform_device *led_dev;
int err;
return;
}
- led_info.fwnode = software_node_fwnode(&mtx1_gpio_leds_node);
-
- led_dev = platform_device_register_full(&led_info);
+ led_dev = platform_device_register_full(&pdevinfo);
err = PTR_ERR_OR_ZERO(led_dev);
if (err)
pr_err("failed to create LED device: %d\n", err);
au1xxx_override_eth_cfg(0, &mtx1_au1000_eth0_pdata);
- rc = software_node_register(&mtx1_gpiochip_node);
- if (rc)
- return rc;
-
rc = platform_add_devices(mtx1_devs, ARRAY_SIZE(mtx1_devs));
if (rc)
return rc;
#include <linux/init.h>
#include <linux/kernel.h>
+#include <linux/property.h>
#include <linux/types.h>
#include <linux/gpio/driver.h>
#include <asm/mach-au1x00/gpio-au1000.h>
return alchemy_gpio1_to_irq(offset + ALCHEMY_GPIO1_BASE);
}
-struct gpio_chip alchemy_gpio_chip[] = {
+const struct software_node alchemy_gpio1_node = {
+ .name = "alchemy-gpio1",
+};
+
+const struct software_node alchemy_gpio2_node = {
+ .name = "alchemy-gpio2",
+};
+
+static const struct software_node *alchemy_gpio_node_group[] = {
+ &alchemy_gpio1_node,
+ &alchemy_gpio2_node,
+ NULL
+};
+
+static struct gpio_chip alchemy_gpio_chip[] = {
[0] = {
.label = "alchemy-gpio1",
.direction_input = gpio1_direction_input,
.ngpio = AU1300_GPIO_NUM,
};
+/*
+ * Software nodes must be registered before board-specific code (that runs
+ * at arch_initcall level) attempts to use them as GPIO targets or as fwnodes
+ * for registered devices. We can not do registration in alchemy_gpiochip_init
+ * because it also runs as arch_initcall and runs after board-specific code
+ * because of the link order, and so we do it at postcore_initcall level.
+ */
+static int __init alchemy_gpio_nodes_init(void)
+{
+ int ret;
+
+ ret = software_node_register_node_group(alchemy_gpio_node_group);
+ if (ret)
+ return ret;
+
+ alchemy_gpio_chip[0].fwnode = software_node_fwnode(&alchemy_gpio1_node);
+ alchemy_gpio_chip[1].fwnode = software_node_fwnode(&alchemy_gpio2_node);
+
+ return 0;
+}
+postcore_initcall(alchemy_gpio_nodes_init);
+
static int __init alchemy_gpiochip_init(void)
{
int ret = 0;