ANDROID: serdev: restrict claim of platform devices
Make the fallback path for claiming platform devices trigger only if a new module parameter is specified: serdev_ttyport.pdev_tty_port=ttyS2 Bug: 146517987 Change-Id: Ibf331ad6e6d8712a405921530f217f7122428b13 Signed-off-by: Alistair Delva <adelva@google.com>
This commit is contained in:
@@ -623,16 +623,18 @@ static int platform_serdev_register_devices(struct serdev_controller *ctrl)
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* serdev_controller_add() - Add an serdev controller
|
* serdev_controller_add_platform() - Add an serdev controller
|
||||||
* @ctrl: controller to be registered.
|
* @ctrl: controller to be registered.
|
||||||
|
* @platform: whether to permit fallthrough to platform device probe
|
||||||
*
|
*
|
||||||
* Register a controller previously allocated via serdev_controller_alloc() with
|
* Register a controller previously allocated via serdev_controller_alloc() with
|
||||||
* the serdev core.
|
* the serdev core. Optionally permit probing via a platform device fallback.
|
||||||
*/
|
*/
|
||||||
int serdev_controller_add(struct serdev_controller *ctrl)
|
int serdev_controller_add_platform(struct serdev_controller *ctrl, bool platform)
|
||||||
{
|
{
|
||||||
int ret_of, ret_acpi, ret_platform, ret;
|
int ret, ret_of, ret_acpi, ret_platform = -ENODEV;
|
||||||
|
|
||||||
/* Can't register until after driver model init */
|
/* Can't register until after driver model init */
|
||||||
if (WARN_ON(!is_registered))
|
if (WARN_ON(!is_registered))
|
||||||
@@ -646,6 +648,7 @@ int serdev_controller_add(struct serdev_controller *ctrl)
|
|||||||
|
|
||||||
ret_of = of_serdev_register_devices(ctrl);
|
ret_of = of_serdev_register_devices(ctrl);
|
||||||
ret_acpi = acpi_serdev_register_devices(ctrl);
|
ret_acpi = acpi_serdev_register_devices(ctrl);
|
||||||
|
if (platform)
|
||||||
ret_platform = platform_serdev_register_devices(ctrl);
|
ret_platform = platform_serdev_register_devices(ctrl);
|
||||||
if (ret_of && ret_acpi && ret_platform) {
|
if (ret_of && ret_acpi && ret_platform) {
|
||||||
dev_dbg(&ctrl->dev, "no devices registered: of:%d acpi:%d "
|
dev_dbg(&ctrl->dev, "no devices registered: of:%d acpi:%d "
|
||||||
@@ -664,7 +667,7 @@ int serdev_controller_add(struct serdev_controller *ctrl)
|
|||||||
device_del(&ctrl->dev);
|
device_del(&ctrl->dev);
|
||||||
return ret;
|
return ret;
|
||||||
};
|
};
|
||||||
EXPORT_SYMBOL_GPL(serdev_controller_add);
|
EXPORT_SYMBOL_GPL(serdev_controller_add_platform);
|
||||||
|
|
||||||
/* Remove a device associated with a controller */
|
/* Remove a device associated with a controller */
|
||||||
static int serdev_remove_device(struct device *dev, void *data)
|
static int serdev_remove_device(struct device *dev, void *data)
|
||||||
|
|||||||
@@ -7,9 +7,15 @@
|
|||||||
#include <linux/tty.h>
|
#include <linux/tty.h>
|
||||||
#include <linux/tty_driver.h>
|
#include <linux/tty_driver.h>
|
||||||
#include <linux/poll.h>
|
#include <linux/poll.h>
|
||||||
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
|
||||||
#define SERPORT_ACTIVE 1
|
#define SERPORT_ACTIVE 1
|
||||||
|
|
||||||
|
static char *pdev_tty_port;
|
||||||
|
module_param(pdev_tty_port, charp, 0644);
|
||||||
|
MODULE_PARM_DESC(pdev_tty_port, "platform device tty port to claim");
|
||||||
|
|
||||||
struct serport {
|
struct serport {
|
||||||
struct tty_port *port;
|
struct tty_port *port;
|
||||||
struct tty_struct *tty;
|
struct tty_struct *tty;
|
||||||
@@ -267,6 +273,7 @@ struct device *serdev_tty_port_register(struct tty_port *port,
|
|||||||
{
|
{
|
||||||
struct serdev_controller *ctrl;
|
struct serdev_controller *ctrl;
|
||||||
struct serport *serport;
|
struct serport *serport;
|
||||||
|
bool platform = false;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!port || !drv || !parent)
|
if (!port || !drv || !parent)
|
||||||
@@ -291,7 +298,24 @@ struct device *serdev_tty_port_register(struct tty_port *port,
|
|||||||
port->client_ops = &client_ops;
|
port->client_ops = &client_ops;
|
||||||
port->client_data = ctrl;
|
port->client_data = ctrl;
|
||||||
|
|
||||||
ret = serdev_controller_add(ctrl);
|
/* There is not always a way to bind specific platform devices because
|
||||||
|
* they may be defined on platforms without DT or ACPI. When dealing
|
||||||
|
* with a platform devices, do not allow direct binding unless it is
|
||||||
|
* whitelisted by module parameter. If a platform device is otherwise
|
||||||
|
* described by DT or ACPI it will still be bound and this check will
|
||||||
|
* be ignored.
|
||||||
|
*/
|
||||||
|
if (parent->bus == &platform_bus_type) {
|
||||||
|
char tty_port_name[7];
|
||||||
|
|
||||||
|
sprintf(tty_port_name, "%s%d", drv->name, idx);
|
||||||
|
if (pdev_tty_port &&
|
||||||
|
!strcmp(pdev_tty_port, tty_port_name)) {
|
||||||
|
platform = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = serdev_controller_add_platform(ctrl, platform);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err_reset_data;
|
goto err_reset_data;
|
||||||
|
|
||||||
|
|||||||
@@ -173,9 +173,21 @@ int serdev_device_add(struct serdev_device *);
|
|||||||
void serdev_device_remove(struct serdev_device *);
|
void serdev_device_remove(struct serdev_device *);
|
||||||
|
|
||||||
struct serdev_controller *serdev_controller_alloc(struct device *, size_t);
|
struct serdev_controller *serdev_controller_alloc(struct device *, size_t);
|
||||||
int serdev_controller_add(struct serdev_controller *);
|
int serdev_controller_add_platform(struct serdev_controller *, bool);
|
||||||
void serdev_controller_remove(struct serdev_controller *);
|
void serdev_controller_remove(struct serdev_controller *);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* serdev_controller_add() - Add an serdev controller
|
||||||
|
* @ctrl: controller to be registered.
|
||||||
|
*
|
||||||
|
* Register a controller previously allocated via serdev_controller_alloc() with
|
||||||
|
* the serdev core.
|
||||||
|
*/
|
||||||
|
static inline int serdev_controller_add(struct serdev_controller *ctrl)
|
||||||
|
{
|
||||||
|
return serdev_controller_add_platform(ctrl, false);
|
||||||
|
}
|
||||||
|
|
||||||
static inline void serdev_controller_write_wakeup(struct serdev_controller *ctrl)
|
static inline void serdev_controller_write_wakeup(struct serdev_controller *ctrl)
|
||||||
{
|
{
|
||||||
struct serdev_device *serdev = ctrl->serdev;
|
struct serdev_device *serdev = ctrl->serdev;
|
||||||
|
|||||||
Reference in New Issue
Block a user