summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2020-03-18 08:48:17 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2020-03-18 08:48:17 +0100
commit8c02f14d1db16068a005b9674da42f14f344ab89 (patch)
treeb57b9d55789ab59e63436ff70f569db06c228f50 /drivers
parent52ef5245746cb13d1eaf9d520d9e7a36d2a70d4b (diff)
parent544bd2f460da25de41094aceadb799ca31474d97 (diff)
downloadbarebox-8c02f14d1db16068a005b9674da42f14f344ab89.tar.gz
Merge branch 'for-next/misc'
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/designware_eqos.c33
-rw-r--r--drivers/net/designware_eqos.h1
-rw-r--r--drivers/net/designware_stm32.c1
-rw-r--r--drivers/net/designware_tegra186.c1
-rw-r--r--drivers/of/overlay.c20
-rw-r--r--drivers/usb/gadget/Kconfig11
-rw-r--r--drivers/usb/gadget/f_fastboot.c4
-rw-r--r--drivers/usb/host/ehci-hcd.c101
-rw-r--r--drivers/video/ssd1307fb.c63
9 files changed, 131 insertions, 104 deletions
diff --git a/drivers/net/designware_eqos.c b/drivers/net/designware_eqos.c
index 4ae07fe..cb52f39 100644
--- a/drivers/net/designware_eqos.c
+++ b/drivers/net/designware_eqos.c
@@ -199,7 +199,7 @@ static int eqos_mdio_wait_idle(struct eqos *eqos)
static int eqos_mdio_read(struct mii_bus *bus, int addr, int reg)
{
struct eqos *eqos = bus->priv;
- u32 miiaddr;
+ u32 miiaddr = MII_BUSY;
int ret;
ret = eqos_mdio_wait_idle(eqos);
@@ -208,18 +208,13 @@ static int eqos_mdio_read(struct mii_bus *bus, int addr, int reg)
return ret;
}
- miiaddr = readl(&eqos->mac_regs->mdio_address);
- miiaddr &= EQOS_MDIO_ADDR_SKAP | EQOS_MDIO_ADDR_C45E;
- miiaddr |= EQOS_MDIO_ADDR_GOC_READ << EQOS_MDIO_ADDR_GOC_SHIFT;
-
- miiaddr |= EQOS_MDIO_CLK_CSR(eqos->ops->clk_csr);
miiaddr |= EQOS_MDIO_ADDR(addr) | EQOS_MDIO_REG(reg);
- miiaddr |= MII_BUSY;
+ miiaddr |= EQOS_MDIO_CLK_CSR(eqos->ops->clk_csr);
+ miiaddr |= EQOS_MDIO_ADDR_GOC_READ << EQOS_MDIO_ADDR_GOC_SHIFT;
+ writel(0, &eqos->mac_regs->mdio_data);
writel(miiaddr, &eqos->mac_regs->mdio_address);
- udelay(eqos->ops->mdio_wait_us);
-
ret = eqos_mdio_wait_idle(eqos);
if (ret) {
dev_err(&bus->dev, "MDIO read didn't complete\n");
@@ -232,7 +227,7 @@ static int eqos_mdio_read(struct mii_bus *bus, int addr, int reg)
static int eqos_mdio_write(struct mii_bus *bus, int addr, int reg, u16 data)
{
struct eqos *eqos = bus->priv;
- u32 miiaddr = 0;
+ u32 miiaddr = MII_BUSY;
int ret;
ret = eqos_mdio_wait_idle(eqos);
@@ -241,28 +236,18 @@ static int eqos_mdio_write(struct mii_bus *bus, int addr, int reg, u16 data)
return ret;
}
- miiaddr = readl(&eqos->mac_regs->mdio_address);
- miiaddr &= EQOS_MDIO_ADDR_SKAP | EQOS_MDIO_ADDR_C45E;
- miiaddr |= EQOS_MDIO_ADDR_GOC_WRITE << EQOS_MDIO_ADDR_GOC_SHIFT;
-
- miiaddr |= EQOS_MDIO_CLK_CSR(eqos->ops->clk_csr);
miiaddr |= EQOS_MDIO_ADDR(addr) | EQOS_MDIO_REG(reg);
- miiaddr |= MII_BUSY;
+ miiaddr |= EQOS_MDIO_CLK_CSR(eqos->ops->clk_csr);
+ miiaddr |= EQOS_MDIO_ADDR_GOC_WRITE << EQOS_MDIO_ADDR_GOC_SHIFT;
writel(data, &eqos->mac_regs->mdio_data);
writel(miiaddr, &eqos->mac_regs->mdio_address);
- udelay(eqos->ops->mdio_wait_us);
-
ret = eqos_mdio_wait_idle(eqos);
- if (ret) {
+ if (ret)
dev_err(&bus->dev, "MDIO read didn't complete\n");
- return ret;
- }
- /* Needed as a fix for ST-Phy */
- eqos_mdio_read(bus, addr, reg);
- return 0;
+ return ret;
}
diff --git a/drivers/net/designware_eqos.h b/drivers/net/designware_eqos.h
index f794195..30f4f02 100644
--- a/drivers/net/designware_eqos.h
+++ b/drivers/net/designware_eqos.h
@@ -17,7 +17,6 @@ struct eqos_ops {
unsigned long (*get_csr_clk_rate)(struct eqos *);
bool enh_desc;
- int mdio_wait_us;
#define EQOS_MAC_RXQ_CTRL0_RXQ0EN_SHIFT 0
#define EQOS_MAC_RXQ_CTRL0_RXQ0EN_MASK 3
diff --git a/drivers/net/designware_stm32.c b/drivers/net/designware_stm32.c
index 1e0cdfa..2e2af89 100644
--- a/drivers/net/designware_stm32.c
+++ b/drivers/net/designware_stm32.c
@@ -180,7 +180,6 @@ static struct eqos_ops stm32_ops = {
.adjust_link = eqos_adjust_link,
.get_csr_clk_rate = eqos_get_csr_clk_rate_stm32,
- .mdio_wait_us = 10 * USEC_PER_MSEC,
.clk_csr = EQOS_MDIO_ADDR_CR_250_300,
.config_mac = EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_AV,
};
diff --git a/drivers/net/designware_tegra186.c b/drivers/net/designware_tegra186.c
index 20521db..5348f65 100644
--- a/drivers/net/designware_tegra186.c
+++ b/drivers/net/designware_tegra186.c
@@ -280,7 +280,6 @@ static const struct eqos_ops tegra186_ops = {
.adjust_link = eqos_adjust_link_tegra186,
.get_csr_clk_rate = eqos_get_csr_clk_rate_tegra186,
- .mdio_wait_us = 10,
.clk_csr = EQOS_MDIO_ADDR_CR_20_35,
.config_mac = EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_DCB,
};
diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c
index de79e05..a35eddf 100644
--- a/drivers/of/overlay.c
+++ b/drivers/of/overlay.c
@@ -105,7 +105,7 @@ static char *of_overlay_fix_path(struct device_node *root,
return basprintf("%s%s", target->full_name, path_tail);
}
-static int of_overlay_apply_symbols(struct device_node *root,
+static void of_overlay_apply_symbols(struct device_node *root,
struct device_node *overlay)
{
const char *old_path;
@@ -115,12 +115,12 @@ static int of_overlay_apply_symbols(struct device_node *root,
struct device_node *overlay_symbols;
root_symbols = of_get_child_by_name(root, "__symbols__");
- if (!root_symbols)
- return -EINVAL;
-
overlay_symbols = of_get_child_by_name(overlay, "__symbols__");
- if (!overlay_symbols)
- return -EINVAL;
+
+ if (!overlay_symbols || !root_symbols) {
+ pr_info("overlay/root doesn't have a __symbols__ node\n");
+ return;
+ }
list_for_each_entry(prop, &overlay_symbols->properties, list) {
if (of_prop_cmp(prop->name, "name") == 0)
@@ -133,8 +133,6 @@ static int of_overlay_apply_symbols(struct device_node *root,
prop->name, new_path);
of_property_write_string(root_symbols, prop->name, new_path);
}
-
- return 0;
}
static int of_overlay_apply_fragment(struct device_node *root,
@@ -171,15 +169,13 @@ int of_overlay_apply_tree(struct device_node *root,
return -EINVAL;
/* Copy symbols from resolved overlay to base device tree */
- err = of_overlay_apply_symbols(root, resolved);
- if (err)
- pr_warn("failed to copy symbols from overlay");
+ of_overlay_apply_symbols(root, resolved);
/* Copy nodes and properties from resolved overlay to root */
for_each_child_of_node(resolved, fragment) {
err = of_overlay_apply_fragment(root, fragment);
if (err)
- pr_warn("failed to apply %s", fragment->name);
+ pr_warn("failed to apply %s\n", fragment->name);
}
of_delete_node(resolved);
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index 3c1d7e6..6e60c7a 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -61,6 +61,7 @@ config USB_GADGET_FASTBOOT
config USB_GADGET_FASTBOOT_SPARSE
bool
+ depends on USB_GADGET_FASTBOOT
select IMAGE_SPARSE
prompt "Enable Fastboot sparse image support"
help
@@ -80,4 +81,14 @@ config USB_GADGET_FASTBOOT_BUF
a buffer, then using a buffer might be better.
Say no here unless you know what you are doing.
+
+config USB_GADGET_FASTBOOT_CMD_OEM
+ bool
+ depends on USB_GADGET_FASTBOOT
+ prompt "Enable OEM commands"
+ help
+ This option enables the fastboot "oem" group of commands. They allow to
+ executing arbitrary barebox commands and may be disabled in secure
+ environments.
+
endif
diff --git a/drivers/usb/gadget/f_fastboot.c b/drivers/usb/gadget/f_fastboot.c
index 426ee9d..cf3cc6d 100644
--- a/drivers/usb/gadget/f_fastboot.c
+++ b/drivers/usb/gadget/f_fastboot.c
@@ -1253,7 +1253,7 @@ static const struct cmd_dispatch_info cmd_oem_dispatch_info[] = {
},
};
-static void cb_oem(struct f_fastboot *f_fb, const char *cmd)
+static void __maybe_unused cb_oem(struct f_fastboot *f_fb, const char *cmd)
{
pr_debug("%s: \"%s\"\n", __func__, cmd);
@@ -1281,9 +1281,11 @@ static const struct cmd_dispatch_info cmd_dispatch_info[] = {
}, {
.cmd = "erase:",
.cb = cb_erase,
+#if defined(CONFIG_USB_GADGET_FASTBOOT_CMD_OEM)
}, {
.cmd = "oem ",
.cb = cb_oem,
+#endif
},
};
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 417ae5d..ead63b2 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -42,7 +42,9 @@ struct ehci_host {
struct ehci_hcor *hcor;
struct usb_host host;
struct QH *qh_list;
+ dma_addr_t qh_list_dma;
struct qTD *td;
+ dma_addr_t td_dma;
int portreset;
unsigned long flags;
@@ -51,7 +53,9 @@ struct ehci_host {
void *drvdata;
int periodic_schedules;
struct QH *periodic_queue;
+ dma_addr_t periodic_queue_dma;
uint32_t *periodic_list;
+ dma_addr_t periodic_list_dma;
};
struct int_queue {
@@ -59,9 +63,11 @@ struct int_queue {
int queuesize;
unsigned long pipe;
struct QH *first;
+ dma_addr_t first_dma;
struct QH *current;
struct QH *last;
struct qTD *tds;
+ dma_addr_t tds_dma;
};
#define to_ehci(ptr) container_of(ptr, struct ehci_host, host)
@@ -137,6 +143,29 @@ static struct descriptor {
#define ehci_is_TDI() (ehci->flags & EHCI_HAS_TT)
+#define EHCI_DMA(dma0, ptr0, ptr) \
+ ((dma0) + ((ptr) - (ptr0)) * sizeof(*(ptr)))
+
+static inline uint32_t ehci_qh_dma(struct ehci_host *ehci, struct QH *qh)
+{
+ return EHCI_DMA(ehci->qh_list_dma, ehci->qh_list, qh);
+}
+
+static inline uint32_t ehci_td_dma(struct ehci_host *ehci, struct qTD *td)
+{
+ return EHCI_DMA(ehci->td_dma, ehci->td, td);
+}
+
+static inline uint32_t ehci_int_qh_dma(struct int_queue *intq, struct QH *qh)
+{
+ return EHCI_DMA(intq->first_dma, intq->first, qh);
+}
+
+static inline uint32_t ehci_int_td_dma(struct int_queue *intq, struct qTD *td)
+{
+ return EHCI_DMA(intq->tds_dma, intq->tds, td);
+}
+
static void memzero32(void *ptr, size_t size)
{
uint32_t *ptr32 = ptr;
@@ -346,7 +375,7 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
dev_dbg(ehci->dev, "unable construct SETUP td\n");
return ret;
}
- *tdp = cpu_to_hc32((uint32_t) td);
+ *tdp = cpu_to_hc32(ehci_td_dma(ehci, td));
tdp = &td->qt_next;
toggle = 1;
@@ -385,7 +414,7 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
dev_err(ehci->dev, "unable construct DATA td\n");
return ret;
}
- *tdp = cpu_to_hc32((uint32_t) td);
+ *tdp = cpu_to_hc32(ehci_td_dma(ehci, td));
tdp = &td->qt_next;
}
@@ -399,7 +428,7 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
QT_TOKEN_PID_IN),
NULL, 0,
NULL, DMA_NONE);
- *tdp = cpu_to_hc32((uint32_t)td);
+ *tdp = cpu_to_hc32(ehci_td_dma(ehci, td));
tdp = &td->qt_next;
}
@@ -841,7 +870,7 @@ static int ehci_init(struct usb_host *host)
return ret;
}
- ehci->qh_list[0].qh_link = cpu_to_hc32((uint32_t)&ehci->qh_list[1] |
+ ehci->qh_list[0].qh_link = cpu_to_hc32(ehci_qh_dma(ehci, &ehci->qh_list[1]) |
QH_LINK_TYPE_QH);
ehci->qh_list[0].qh_endpt1 = cpu_to_hc32(QH_ENDPT1_H(1) |
QH_ENDPT1_EPS(USB_SPEED_HIGH));
@@ -850,12 +879,13 @@ static int ehci_init(struct usb_host *host)
ehci->qh_list[0].qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE);
ehci->qh_list[0].qt_token = cpu_to_hc32(QT_TOKEN_STATUS_HALTED);
- ehci->qh_list[1].qh_link = cpu_to_hc32((uint32_t)&ehci->qh_list[0] |
+ ehci->qh_list[1].qh_link = cpu_to_hc32(ehci_qh_dma(ehci,
+ &ehci->qh_list[0]) |
QH_LINK_TYPE_QH);
ehci->qh_list[1].qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE);
/* Set async. queue head pointer. */
- ehci_writel(&ehci->hcor->or_asynclistaddr, (uint32_t)ehci->qh_list);
+ ehci_writel(&ehci->hcor->or_asynclistaddr, (uint32_t)ehci->qh_list_dma);
/*
* Set up periodic list
@@ -885,15 +915,15 @@ static int ehci_init(struct usb_host *host)
* PAGE_SIZE less then 4k will break this code.
*/
ehci->periodic_list = dma_alloc_coherent(1024 * 4,
- DMA_ADDRESS_BROKEN);
+ &ehci->periodic_list_dma);
for (i = 0; i < 1024; i++) {
- ehci->periodic_list[i] = cpu_to_hc32((unsigned long)periodic
+ ehci->periodic_list[i] = cpu_to_hc32((unsigned long)ehci->periodic_queue_dma
| QH_LINK_TYPE_QH);
}
/* Set periodic list base address */
ehci_writel(&ehci->hcor->or_periodiclistbase,
- (unsigned long)ehci->periodic_list);
+ (uint32_t)ehci->periodic_list_dma);
reg = ehci_readl(&ehci->hccr->cr_hcsparams);
descriptor.hub.bNbrPorts = HCS_N_PORTS(reg);
@@ -986,7 +1016,10 @@ disable_periodic(struct ehci_host *ehci)
return 0;
}
-#define NEXT_QH(qh) (struct QH *)((unsigned long)hc32_to_cpu((qh)->qh_link) & ~0x1f)
+#define NEXT_QH(queue, qh) (struct QH *)( \
+ ((unsigned long)hc32_to_cpu((qh)->qh_link) & ~0x1f) - \
+ (queue)->first_dma + \
+ (unsigned long)(queue)->first)
static int
enable_periodic(struct ehci_host *ehci)
@@ -1051,7 +1084,7 @@ static void ehci_update_endpt2_dev_n_port(struct usb_device *udev,
static struct int_queue *ehci_create_int_queue(struct usb_device *dev,
unsigned long pipe, int queuesize, int elementsize,
- void *buffer, int interval)
+ void *buffer, dma_addr_t buffer_dma, int interval)
{
struct usb_host *host = dev->host;
struct ehci_host *ehci = to_ehci(host);
@@ -1100,22 +1133,23 @@ static struct int_queue *ehci_create_int_queue(struct usb_device *dev,
result->queuesize = queuesize;
result->pipe = pipe;
result->first = dma_alloc_coherent(sizeof(struct QH) * queuesize,
- DMA_ADDRESS_BROKEN);
+ &result->first_dma);
result->current = result->first;
result->last = result->first + queuesize - 1;
result->tds = dma_alloc_coherent(sizeof(struct qTD) * queuesize,
- DMA_ADDRESS_BROKEN);
+ &result->tds_dma);
for (i = 0; i < queuesize; i++) {
struct QH *qh = result->first + i;
struct qTD *td = result->tds + i;
void **buf = &qh->buffer;
- qh->qh_link = cpu_to_hc32((unsigned long)(qh+1) | QH_LINK_TYPE_QH);
+ qh->qh_link = cpu_to_hc32(ehci_int_qh_dma(result, qh + 1) |
+ QH_LINK_TYPE_QH);
if (i == queuesize - 1)
qh->qh_link = cpu_to_hc32(QH_LINK_TERMINATE);
- qh->qt_next = cpu_to_hc32((unsigned long)td);
+ qh->qt_next = cpu_to_hc32(ehci_int_td_dma(result, td));
qh->qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE);
qh->qh_endpt1 =
cpu_to_hc32((0 << 28) | /* No NAK reload (ehci 4.9) */
@@ -1142,15 +1176,15 @@ static struct int_queue *ehci_create_int_queue(struct usb_device *dev,
((usb_pipein(pipe) ? 1 : 0) << 8) | /* IN/OUT token */
0x80); /* active */
td->qt_buffer[0] =
- cpu_to_hc32((unsigned long)buffer + i * elementsize);
+ cpu_to_hc32(buffer_dma + i * elementsize);
td->qt_buffer[1] =
- cpu_to_hc32((td->qt_buffer[0] + 0x1000) & ~0xfff);
+ cpu_to_hc32((buffer_dma + i * elementsize + 0x1000) & ~0xfff);
td->qt_buffer[2] =
- cpu_to_hc32((td->qt_buffer[0] + 0x2000) & ~0xfff);
+ cpu_to_hc32((buffer_dma + i * elementsize + 0x2000) & ~0xfff);
td->qt_buffer[3] =
- cpu_to_hc32((td->qt_buffer[0] + 0x3000) & ~0xfff);
+ cpu_to_hc32((buffer_dma + i * elementsize + 0x3000) & ~0xfff);
td->qt_buffer[4] =
- cpu_to_hc32((td->qt_buffer[0] + 0x4000) & ~0xfff);
+ cpu_to_hc32((buffer_dma + i * elementsize + 0x4000) & ~0xfff);
*buf = buffer + i * elementsize;
}
@@ -1165,7 +1199,7 @@ static struct int_queue *ehci_create_int_queue(struct usb_device *dev,
/* hook up to periodic list */
result->last->qh_link = list->qh_link;
- list->qh_link = cpu_to_hc32((unsigned long)result->first | QH_LINK_TYPE_QH);
+ list->qh_link = cpu_to_hc32(result->first_dma | QH_LINK_TYPE_QH);
if (enable_periodic(ehci) < 0) {
dev_err(&dev->dev,
@@ -1177,8 +1211,10 @@ static struct int_queue *ehci_create_int_queue(struct usb_device *dev,
dev_dbg(&dev->dev, "Exit create_int_queue\n");
return result;
fail3:
- dma_free_coherent(result->tds, 0, sizeof(struct qTD) * queuesize);
- dma_free_coherent(result->first, 0, sizeof(struct QH) * queuesize);
+ dma_free_coherent(result->tds, result->tds_dma,
+ sizeof(struct qTD) * queuesize);
+ dma_free_coherent(result->first, result->first_dma,
+ sizeof(struct QH) * queuesize);
free(result);
return NULL;
}
@@ -1235,14 +1271,14 @@ static int ehci_destroy_int_queue(struct usb_device *dev,
dev_dbg(&dev->dev,
"considering %p, with qh_link %x\n",
cur, cur->qh_link);
- if (NEXT_QH(cur) == queue->first) {
+ if (NEXT_QH(queue, cur) == queue->first) {
dev_dbg(&dev->dev,
"found candidate. removing from chain\n");
cur->qh_link = queue->last->qh_link;
result = 0;
break;
}
- cur = NEXT_QH(cur);
+ cur = NEXT_QH(queue, cur);
}
if (ehci->periodic_schedules > 0) {
@@ -1269,14 +1305,14 @@ submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
uint64_t start;
void *backbuffer;
int result = 0, ret;
+ dma_addr_t buffer_dma;
dev_dbg(ehci->dev, "dev=%p, pipe=%lu, buffer=%p, length=%d, interval=%d",
dev, pipe, buffer, length, interval);
- dma_sync_single_for_device((unsigned long)buffer, length,
- DMA_BIDIRECTIONAL);
+ buffer_dma = dma_map_single(ehci->dev, buffer, length, DMA_BIDIRECTIONAL);
- queue = ehci_create_int_queue(dev, pipe, 1, length, buffer, interval);
+ queue = ehci_create_int_queue(dev, pipe, 1, length, buffer, buffer_dma, interval);
if (!queue)
return -EINVAL;
@@ -1298,8 +1334,7 @@ submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
result = -EINVAL;
}
- dma_sync_single_for_cpu((unsigned long)buffer, length,
- DMA_BIDIRECTIONAL);
+ dma_unmap_single(ehci->dev, buffer_dma, length, DMA_BIDIRECTIONAL);
ret = ehci_destroy_int_queue(dev, queue);
if (!result)
@@ -1335,11 +1370,11 @@ struct ehci_host *ehci_register(struct device_d *dev, struct ehci_data *data)
ehci->post_init = data->post_init;
ehci->qh_list = dma_alloc_coherent(sizeof(struct QH) * NUM_QH,
- DMA_ADDRESS_BROKEN);
+ &ehci->qh_list_dma);
ehci->periodic_queue = dma_alloc_coherent(sizeof(struct QH),
- DMA_ADDRESS_BROKEN);
+ &ehci->periodic_queue_dma);
ehci->td = dma_alloc_coherent(sizeof(struct qTD) * NUM_TD,
- DMA_ADDRESS_BROKEN);
+ &ehci->td_dma);
host->hw_dev = dev;
host->init = ehci_init;
diff --git a/drivers/video/ssd1307fb.c b/drivers/video/ssd1307fb.c
index 70077e4..835814b 100644
--- a/drivers/video/ssd1307fb.c
+++ b/drivers/video/ssd1307fb.c
@@ -405,8 +405,9 @@ static int ssd1307fb_probe(struct device_d *dev)
}
info = xzalloc(sizeof(struct fb_info));
+ par = xzalloc(sizeof(*par));
- par = info->priv;
+ info->priv = par;
par->info = info;
par->client = client;
@@ -414,12 +415,8 @@ static int ssd1307fb_probe(struct device_d *dev)
par->reset = of_get_named_gpio(node,
"reset-gpios", 0);
- if (!gpio_is_valid(par->reset)) {
- ret = par->reset;
- if (ret != -EPROBE_DEFER)
- dev_err(&client->dev,
- "Couldn't get named gpio 'reset-gpios': %s.\n",
- strerror(-ret));
+ if (!gpio_is_valid(par->reset) && par->reset == -EPROBE_DEFER) {
+ ret = -EPROBE_DEFER;
goto fb_alloc_error;
}
@@ -502,38 +499,41 @@ static int ssd1307fb_probe(struct device_d *dev)
info->screen_base = (u8 __force __iomem *)vmem;
- ret = gpio_request_one(par->reset,
- GPIOF_OUT_INIT_HIGH,
- "oled-reset");
- if (ret) {
- dev_err(&client->dev,
- "failed to request gpio %d: %d\n",
- par->reset, ret);
- goto reset_oled_error;
- }
-
- if (par->vbat) {
- ret = regulator_disable(par->vbat);
- if (ret < 0)
+ if (par->reset >= 0) {
+ ret = gpio_request_one(par->reset,
+ GPIOF_OUT_INIT_HIGH,
+ "oled-reset");
+ if (ret) {
+ dev_err(&client->dev,
+ "failed to request gpio %d: %d\n",
+ par->reset, ret);
goto reset_oled_error;
+ }
}
- i2c_set_clientdata(client, info);
+ ret = regulator_disable(par->vbat);
+ if (ret < 0)
+ goto reset_oled_error;
- /* Reset the screen */
- gpio_set_value(par->reset, 0);
- udelay(4);
+ i2c_set_clientdata(client, info);
- if (par->vbat) {
- ret = regulator_enable(par->vbat);
- if (ret < 0)
- goto reset_oled_error;
+ if (par->reset > 0) {
+ /* Reset the screen */
+ gpio_set_value(par->reset, 0);
+ udelay(4);
}
- mdelay(100);
+ ret = regulator_enable(par->vbat);
+ if (ret < 0)
+ goto reset_oled_error;
- gpio_set_value(par->reset, 1);
- udelay(4);
+ if (par->vbat)
+ mdelay(100);
+
+ if (par->reset > 0) {
+ gpio_set_value(par->reset, 1);
+ udelay(4);
+ }
ret = ssd1307fb_init(par);
if (ret)
@@ -574,6 +574,7 @@ reset_oled_error:
free(vmem);
fb_alloc_error:
regulator_disable(par->vbat);
+ free(par);
free(info);
return ret;
}