* Janusz Krzysztofik <jkrzyszt@xxxxxxxxxxxx> [111212 14:36]: > (adding Greg Kroah-Hartman and linux-serial@xxxxxxxxxxxxxxx to Cc:) > > On Monday 12 of December 2011 at 19:04:56, Tony Lindgren wrote: > > * Janusz Krzysztofik <jkrzyszt@xxxxxxxxxxxx> [111211 11:41]: > > > This will allow boards with custom memory mapped GPIO ports to set up > > > and use those port pins while initializing devices from arch init. > > > > Care to explain a bit more why you need to initialize those devices > > early on? > > Let me try. > > From patch 2/10 "ARM: OMAP1: ams-delta: Convert latches to > basic_mmio_gpio": > > > @@ -307,8 +487,8 @@ static void __init ams_delta_init(void) > > omap_serial_init(); > > omap_register_i2c_bus(1, 100, NULL, 0); > > > > - /* Clear latch2 (NAND, LCD, modem enable) */ > > - ams_delta_latch2_write(~0, 0); > > + platform_add_devices(_latch_devices, ARRAY_SIZE(_latch_devices)); > > + BUG_ON(gpio_request_array(_latch_gpios, ARRAY_SIZE(_latch_gpios))); > > > > omap1_usb_init(&ams_delta_usb_config); > > omap1_set_camera_info(&ams_delta_camera_platform_data); > > Here I'm accessing the latches from ams_delta_init() (.init_machine > hook) with gpio_request_array() in order to: > a) clear their contents, > b) avoid accessing them, from ams_delta_latch_write(), never requested. > > I could imagine clearing their contents with something like > > *(volatile __u8 *) AMS_DELTA_LATCH2_VIRT = 0; > *(volatile __u16 *) AMS_DELTA_LATCH2_VIRT = 0; > > instead, i.e., the way the old code used to, than accessing those GPIO > pins not requested, until they are finally requested by drivers updated > to use gpiolib with successive patche. Would this be acceptable? Thanks for explaining, it's best to use gpio calls instead :) How about just add some __initcall into your board-*.c file to do the required setups a bit later? Just make sure you exit early if (!machine_is...) fails. > However, > From patch 6/10 "ARM: OMAP1: ams-delta: Use GPIO API in modem setup": > > > @@ -482,6 +472,12 @@ static void __init ams_delta_init(void) > > omap_writew(omap_readw(ARM_RSTCT1) | 0x0004, ARM_RSTCT1); > > } > > > > +static void _modem_pm(struct uart_port *port, unsigned int state, unsigned old) > > +{ > > + if (state != old) > > + gpio_set_value(AMS_DELTA_GPIO_PIN_MODEM_NRESET, state == 0); > > +} > > + > > static struct plat_serial8250_port ams_delta_modem_ports[] = { > > { > > .membase = IOMEM(_MODEM_VIRT), > > @@ -492,6 +488,7 @@ static struct plat_serial8250_port ams_delta_modem_ports[] = { > > .iotype = UPIO_MEM, > > .regshift = 1, > > .uartclk = BASE_BAUD * 16, > > + .pm = _modem_pm, > > }, > > { }, > > }; > > @@ -504,6 +501,24 @@ static struct platform_device ams_delta_modem_device = { > > }, > > }; > > > > +static struct gpio _modem_gpios[] __initconst = { > > + { > > + .gpio = AMS_DELTA_GPIO_PIN_MODEM_IRQ, > > + .flags = GPIOF_DIR_IN, > > + .label = "modem_irq", > > + }, > > + { > > + .gpio = AMS_DELTA_GPIO_PIN_MODEM_NRESET, > > + .flags = GPIOF_OUT_INIT_HIGH, > > + .label = "modem_nreset", > > + }, > > + { > > + .gpio = AMS_DELTA_GPIO_PIN_MODEM_CODEC, > > + .flags = GPIOF_OUT_INIT_HIGH, > > + .label = "modem_codec", > > + }, > > +}; > > + > > static int __init ams_delta_modem_init(void) > > { > > int err; > > @@ -515,16 +530,11 @@ static int __init ams_delta_modem_init(void) > > ams_delta_modem_ports[0].irq = > > gpio_to_irq(AMS_DELTA_GPIO_PIN_MODEM_IRQ); > > > > - err = gpio_request(AMS_DELTA_GPIO_PIN_MODEM_IRQ, "modem"); > > + err = gpio_request_array(_modem_gpios, ARRAY_SIZE(_modem_gpios)); > > if (err) { > > - pr_err("Couldn't request gpio pin for modem\n"); > > + pr_err("Couldn't request gpio pins for modem\n"); > > return err; > > } > > - gpio_direction_input(AMS_DELTA_GPIO_PIN_MODEM_IRQ); > > - > > - ams_delta_latch2_write( > > - AMS_DELTA_LATCH2_MODEM_NRESET | AMS_DELTA_LATCH2_MODEM_CODEC, > > - AMS_DELTA_LATCH2_MODEM_NRESET | AMS_DELTA_LATCH2_MODEM_CODEC); > > > > return platform_device_register(&ams_delta_modem_device); > > } > > Before the change, only one GPIO pin, that IRQ, driven with omap_gpio > driver which is registered from postcore, was gpio_request()ed. Now, two > more, gpio-generic driven pins, are also requested _and_ initialized in > order to make the modem accessible. The ams_delta_modem_init() is > installed with arch_initcall(). > > I could imagine initializing those modem pins the old way I've suggested > above, but I can see no good solution to delegate calling of that > gpio_request*() to the 8250 driver. For me, the only hook passed to the > driver with platform_data that can be suitable is the .pm hook. However, > when I tried to remove powering up the modem (rising up > AMS_DELTA_GPIO_PIN_MODEM_NRESET) from the arch init and do this only > from that .pm hook, the device was not detected, so I wonder if and when > that hook is called, and if it is before probe, then perhaps powering > up the modem chip from there is too late for the device to get up before > being examined. But then, maybe if we initialize the pin the old way > from arch init, it would be enough for the device to be detected, while > consecutive open() response times may not be so critical. Perhaps Greg > or another serial guru can shed some more light on this. > > But this way or another, we are talking about dirty hacks here IMHO. Might be worth checking if some board specific __initcall helps here too? Regards, Tony -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html